ccxt
Version:
1,054 lines (1,051 loc) • 210 kB
JavaScript
// ----------------------------------------------------------------------------
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
// EDIT THE CORRESPONDENT .ts FILE INSTEAD
// ---------------------------------------------------------------------------
import { keccak_256 as keccak } from '@noble/hashes/sha3.js';
import { secp256k1 } from '@noble/curves/secp256k1.js';
import Exchange from './abstract/aster.js';
import { AccountNotEnabled, AccountSuspended, ArgumentsRequired, AuthenticationError, BadRequest, BadResponse, BadSymbol, DuplicateOrderId, ExchangeClosedByUser, ExchangeError, InsufficientFunds, InvalidNonce, InvalidOrder, MarketClosed, NetworkError, NoChange, NotSupported, OperationFailed, OperationRejected, OrderImmediatelyFillable, OrderNotFillable, OrderNotFound, PermissionDenied, RateLimitExceeded, RequestTimeout, NullResponse } from './base/errors.js';
import { TRUNCATE, TICK_SIZE } from './base/functions/number.js';
import Precise from './base/Precise.js';
import { ecdsa } from './base/functions/crypto.js';
// ---------------------------------------------------------------------------xs
/**
* @class aster
* @augments Exchange
*/
export default class aster extends Exchange {
describe() {
return this.deepExtend(super.describe(), {
'id': 'aster',
'name': 'Aster',
'countries': ['US'],
// 3 req/s for free
// 150 req/s for subscribers: https://aster.markets/data
// for brokers: https://aster.markets/docs/api-references/broker-api/#authentication-and-rate-limit
'rateLimit': 333,
'certified': false,
'pro': true,
'dex': true,
'urls': {
'logo': 'https://github.com/user-attachments/assets/5e5909d6-c4de-4435-992f-4339c80edbd7',
'www': 'https://www.asterdex.com/en',
'api': {
'fapiPublic': 'https://fapi.asterdex.com/fapi',
'fapiPrivate': 'https://fapi.asterdex.com/fapi',
'sapiPublic': 'https://sapi.asterdex.com/api',
'sapiPrivate': 'https://sapi.asterdex.com/api',
},
'doc': 'https://github.com/asterdex/api-docs',
'fees': 'https://docs.asterdex.com/product/asterex-simple/fees-and-slippage',
'referral': {
'url': 'https://www.asterdex.com/en/referral/aA1c2B',
'discount': 0.1,
},
},
'has': {
'CORS': undefined,
'spot': true,
'margin': false,
'swap': true,
'future': false,
'option': false,
'addMargin': true,
'borrowCrossMargin': false,
'borrowIsolatedMargin': false,
'cancelAllOrders': true,
'cancelOrder': true,
'cancelOrders': true,
'closeAllPositions': false,
'closePosition': false,
'createConvertTrade': false,
'createDepositAddress': false,
'createLimitBuyOrder': false,
'createLimitSellOrder': false,
'createMarketBuyOrder': false,
'createMarketBuyOrderWithCost': false,
'createMarketOrderWithCost': false,
'createMarketSellOrder': false,
'createMarketSellOrderWithCost': false,
'createOrder': true,
'createOrders': false,
'createOrderWithTakeProfitAndStopLoss': false,
'createPostOnlyOrder': false,
'createReduceOnlyOrder': false,
'createStopLimitOrder': false,
'createStopLossOrder': false,
'createStopMarketOrder': false,
'createStopOrder': false,
'createTakeProfitOrder': false,
'createTrailingPercentOrder': false,
'createTriggerOrder': false,
'editOrder': false,
'editOrders': false,
'fetchAccounts': undefined,
'fetchBalance': true,
'fetchBidsAsks': false,
'fetchBorrowInterest': false,
'fetchBorrowRateHistories': false,
'fetchBorrowRateHistory': false,
'fetchCanceledAndClosedOrders': 'emulated',
'fetchCanceledOrders': 'emulated',
'fetchClosedOrder': false,
'fetchClosedOrders': 'emulated',
'fetchConvertCurrencies': false,
'fetchConvertQuote': false,
'fetchConvertTrade': false,
'fetchConvertTradeHistory': false,
'fetchCrossBorrowRate': false,
'fetchCrossBorrowRates': false,
'fetchCurrencies': true,
'fetchDeposit': false,
'fetchDepositAddress': false,
'fetchDepositAddresses': false,
'fetchDepositAddressesByNetwork': false,
'fetchDeposits': false,
'fetchDepositsWithdrawals': false,
'fetchDepositWithdrawFee': 'emulated',
'fetchDepositWithdrawFees': false,
'fetchFundingHistory': true,
'fetchFundingInterval': 'emulated',
'fetchFundingIntervals': true,
'fetchFundingRate': true,
'fetchFundingRateHistory': true,
'fetchFundingRates': true,
'fetchGreeks': false,
'fetchIndexOHLCV': false,
'fetchIsolatedBorrowRate': 'emulated',
'fetchIsolatedBorrowRates': false,
'fetchL3OrderBook': false,
'fetchLastPrices': false,
'fetchLedger': true,
'fetchLedgerEntry': false,
'fetchLeverage': 'emulated',
'fetchLeverages': true,
'fetchLeverageTiers': false,
'fetchLiquidations': false,
'fetchLongShortRatio': false,
'fetchLongShortRatioHistory': false,
'fetchMarginAdjustmentHistory': true,
'fetchMarginMode': 'emulated',
'fetchMarginModes': true,
'fetchMarketLeverageTiers': 'emulated',
'fetchMarkets': true,
'fetchMarkOHLCV': false,
'fetchMarkPrice': false,
'fetchMarkPrices': false,
'fetchMyLiquidations': false,
'fetchMySettlementHistory': false,
'fetchMyTrades': true,
'fetchOHLCV': true,
'fetchOpenInterest': false,
'fetchOpenInterestHistory': false,
'fetchOpenOrder': true,
'fetchOpenOrders': true,
'fetchOption': false,
'fetchOptionChain': false,
'fetchOrder': true,
'fetchOrderBook': true,
'fetchOrderBooks': false,
'fetchOrders': true,
'fetchOrderTrades': false,
'fetchPosition': false,
'fetchPositionHistory': false,
'fetchPositionMode': true,
'fetchPositions': true,
'fetchPositionsHistory': false,
'fetchPositionsRisk': true,
'fetchPremiumIndexOHLCV': false,
'fetchSettlementHistory': false,
'fetchStatus': false,
'fetchTicker': true,
'fetchTickers': true,
'fetchTime': true,
'fetchTrades': true,
'fetchTradingFee': true,
'fetchTradingFees': false,
'fetchTradingLimits': 'emulated',
'fetchTransactionFee': 'emulated',
'fetchTransactionFees': false,
'fetchTransactions': false,
'fetchTransfer': false,
'fetchTransfers': false,
'fetchUnderlyingAssets': false,
'fetchVolatilityHistory': false,
'fetchWithdrawAddresses': false,
'fetchWithdrawal': false,
'fetchWithdrawals': false,
'fetchWithdrawalWhitelist': false,
'reduceMargin': true,
'repayCrossMargin': false,
'repayIsolatedMargin': false,
'sandbox': false,
'setLeverage': true,
'setMargin': false,
'setMarginMode': true,
'setPositionMode': true,
'signIn': true,
'transfer': true,
'withdraw': true,
},
'api': {
'fapiPublic': {
'get': {
'v1/ping': 1,
'v3/ping': 1,
'v1/time': 1,
'v3/time': 1,
'v1/exchangeInfo': 1,
'v3/exchangeInfo': 1,
'v1/depth': 1,
'v3/depth': 2, // dynamic: 5, 10, 20, 50->2, 100->5, 500->10, 1000->20
'v1/trades': 1,
'v3/trades': 1,
'v1/historicalTrades': 1,
'v3/historicalTrades': 20,
'v1/aggTrades': 1,
'v3/aggTrades': 20,
'v1/klines': 1,
'v3/klines': 1, // dynamic [1,100) ->1, [100, 500)->2, [500, 1000]->5, [1000 -> 10
'v1/indexPriceKlines': 1,
'v3/indexPriceKlines': 1, // same as klines
'v1/markPriceKlines': 1,
'v3/markPriceKlines': 1, // same as klines
'v1/premiumIndex': 1,
'v3/premiumIndex': 1,
'v1/fundingRate': 1,
'v3/fundingRate': 1,
'v1/fundingInfo': 1,
'v3/fundingInfo': 1,
'v1/ticker/24hr': 1,
'v3/ticker/24hr': 1, // 1 single-symbol, otherwise 40
'v1/ticker/price': 1,
'v3/ticker/price': 1, // 1 single-symbol, otherwise 2
'v1/ticker/bookTicker': 1,
'v3/ticker/bookTicker': 1, // 1 single-symbol, otherwise 2
// different endpoints
'v1/adlQuantile': 1,
'v1/forceOrders': 1,
'v3/indexreferences': 1,
},
},
'fapiPrivate': {
'get': {
'v1/positionSide/dual': 1,
'v3/positionSide/dual': 30,
'v1/multiAssetsMargin': 1,
'v3/multiAssetsMargin': 1,
'v1/order': 1,
'v3/order': 1,
'v1/openOrder': 1,
'v3/openOrder': 1,
'v1/openOrders': 1,
'v3/openOrders': 1,
'v1/allOrders': 1,
'v3/allOrders': 1,
'v2/balance': 1,
'v3/balance': 1,
'v3/account': 1,
'v1/positionMargin/history': 1,
'v3/positionMargin/history': 1,
'v2/positionRisk': 1,
'v3/positionRisk': 1,
'v1/userTrades': 1,
'v3/userTrades': 5,
'v1/income': 1,
'v3/income': 1,
'v1/leverageBracket': 1,
'v3/leverageBracket': 1,
'v1/commissionRate': 1,
'v3/commissionRate': 1,
// others
'v3/adlQuantile': 1,
'v3/forceOrders': 1,
'v3/mmp': 1,
'v3/accountWithJoinMargin': 1,
'v4/account': 1,
// builder
'v3/agent': 1,
'v3/builder': 1,
},
'post': {
'v1/positionSide/dual': 1,
'v3/positionSide/dual': 1,
'v1/multiAssetsMargin': 1,
'v3/multiAssetsMargin': 1,
'v1/order': 1,
'v3/order': 1,
'v1/order/test': 1,
'v3/order/test': 1,
'v1/batchOrders': 1,
'v3/batchOrders': 1,
'v1/asset/wallet/transfer': 1,
'v3/asset/wallet/transfer': 1,
'v1/countdownCancelAll': 1,
'v3/countdownCancelAll': 1,
'v1/leverage': 1,
'v3/leverage': 1,
'v1/marginType': 1,
'v3/marginType': 1,
'v1/positionMargin': 1,
'v3/positionMargin': 1,
'v1/listenKey': 1,
'v3/listenKey': 1,
// others
'v3/mmp': 1,
'v3/mmpReset': 1,
'v3/noop': 1,
// builder
'v3/approveAgent': 1,
'v3/updateAgent': 1,
'v3/approveBuilder': 1,
'v3/updateBuilder': 1,
},
'put': {
'v1/listenKey': 1,
'v3/listenKey': 1,
},
'delete': {
'v1/order': 1,
'v3/order': 1,
'v1/allOpenOrders': 1,
'v3/allOpenOrders': 1,
'v1/batchOrders': 1,
'v3/batchOrders': 1,
'v3/mmp': 1,
'v1/listenKey': 1,
'v3/listenKey': 1,
// builder
'v3/agent': 1,
'v3/builder': 1,
},
},
'sapiPublic': {
'get': {
// v1
'v1/ping': 1,
'v1/time': 1,
'v1/exchangeInfo': 1,
'v1/depth': 1,
'v1/trades': 1,
'v1/historicalTrades': 1,
'v1/aggTrades': 1,
'v1/klines': 1,
'v1/ticker/24hr': 1,
'v1/ticker/price': 1,
'v1/ticker/bookTicker': 1,
'v1/aster/withdraw/estimateFee': 1,
// v3
'v3/ping': 1,
'v3/time': 1,
'v3/exchangeInfo': 1,
'v3/depth': { 'cost': 2, 'byLimit': [[50, 2], [100, 5], [500, 10], [1000, 20]] },
'v3/trades': 1,
'v3/historicalTrades': 20,
'v3/aggTrades': 20,
'v3/klines': { 'cost': 1, 'byLimit': [[99, 1], [499, 2], [1000, 5], [10000, 10]] }, // todo: not specified in docs
'v3/ticker/24hr': { 'cost': 1, 'noSymbol': 40 },
'v3/ticker/price': { 'cost': 1, 'noSymbol': 2 },
'v3/ticker/bookTicker': { 'cost': 1, 'noSymbol': 2 },
'v3/aster/withdraw/estimateFee': 1,
},
},
'sapiPrivate': {
'get': {
// v1
'v1/commissionRate': 1,
'v1/order': 1,
'v1/openOrders': 1,
'v1/allOrders': 1,
'v1/transactionHistory': 1,
'v1/account': 1,
'v1/userTrades': 1,
// v3
'v3/commissionRate': { 'cost': 1, 'noSymbol': 2 },
'v3/order': 1,
'v3/openOrders': 1, // with symbol 1, otherwise 40
'v3/allOrders': 5,
'v3/account': 5,
'v3/userTrades': 5,
'v3/openOrder': 1,
},
'post': {
// v1
'v1/order': 1,
'v1/asset/wallet/transfer': 5,
'v1/asset/sendToAddress': 1, // inexistent in v3
'v1/listenKey': 1,
// v3
'v3/order': 1,
'v3/asset/wallet/transfer': 5,
'v3/aster/user-withdraw': 1,
'v3/listenKey': 1,
},
'put': [
'v1/listenKey',
'v3/listenKey',
],
'delete': {
// v1
'v1/order': 1,
'v1/allOpenOrders': 1,
'v1/listenKey': 1,
// v3
'v3/allOpenOrders': 1,
'v3/order': 1,
'v3/listenKey': 1,
},
},
},
'timeframes': {
'1m': '1m',
'3m': '3m',
'5m': '5m',
'15m': '15m',
'30m': '30m',
'1h': '1h',
'2h': '2h',
'4h': '4h',
'6h': '6h',
'8h': '8h',
'12h': '12h',
'1d': '1d',
'3d': '3d',
'1w': '1w',
'1M': '1M',
},
'precisionMode': TICK_SIZE,
'requiredCredentials': {
'apiKey': false,
'secret': false,
'privateKey': true,
},
'fees': {
'trading': {
'tierBased': true,
'percentage': true,
'maker': this.parseNumber('0.0001'),
'taker': this.parseNumber('0.00035'),
},
},
'features': {
'spot': {
'sandbox': false,
'createOrder': {
'marginMode': false,
'triggerPrice': true,
'triggerPriceType': undefined,
'triggerDirection': undefined,
'stopLossPrice': true,
'takeProfitPrice': true,
'attachedStopLossTakeProfit': undefined,
'timeInForce': {
'IOC': true,
'FOK': true,
'PO': true,
'GTD': false,
},
'hedged': false,
'trailing': false,
'leverage': false,
'marketBuyByCost': true,
'marketBuyRequiresPrice': false,
'selfTradePrevention': false,
'iceberg': false,
},
'createOrders': undefined,
'fetchMyTrades': {
'marginMode': false,
'limit': 1000,
'daysBack': undefined,
'untilDays': undefined,
'symbolRequired': true,
},
'fetchOrder': {
'marginMode': false,
'trigger': false,
'trailing': false,
'symbolRequired': true,
},
'fetchOpenOrders': {
'marginMode': false,
'limit': undefined,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOrders': {
'marginMode': false,
'limit': 1000,
'daysBack': undefined,
'untilDays': undefined,
'trigger': false,
'trailing': false,
'symbolRequired': true,
},
'fetchClosedOrders': undefined,
'fetchOHLCV': {
'limit': 1500,
},
},
'forDerivs': {
'sandbox': false,
'createOrder': {
'marginMode': false,
'triggerPrice': true,
'triggerPriceType': {
'last': true,
'mark': true,
'index': false,
},
'triggerDirection': false,
'stopLossPrice': true,
'takeProfitPrice': true,
'attachedStopLossTakeProfit': undefined,
'timeInForce': {
'IOC': true,
'FOK': true,
'PO': true,
'GTD': false,
},
'hedged': true,
'trailing': true,
'leverage': false,
'marketBuyByCost': false,
'marketBuyRequiresPrice': false,
'selfTradePrevention': false,
'iceberg': false,
},
'createOrders': undefined,
'fetchMyTrades': {
'marginMode': false,
'limit': 1000,
'daysBack': undefined,
'untilDays': undefined,
'symbolRequired': true,
},
'fetchOrder': {
'marginMode': false,
'trigger': false,
'trailing': false,
'symbolRequired': true,
},
'fetchOpenOrders': {
'marginMode': false,
'limit': undefined,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOrders': {
'marginMode': false,
'limit': 1000,
'daysBack': undefined,
'untilDays': undefined,
'trigger': false,
'trailing': false,
'symbolRequired': true,
},
'fetchClosedOrders': undefined,
'fetchOHLCV': {
'limit': 1500,
},
},
'swap': {
'linear': {
'extends': 'forDerivs',
},
'inverse': undefined,
},
},
'options': {
'defaultType': 'spot',
'recvWindow': 10 * 1000, // 10 sec
'zeroAddress': '0x0000000000000000000000000000000000000000',
'v3ChainId': 1666, // Aster chain ID used for EIP-712 v3 signing
'createOrder': {
'timeInForce': 'GTC', // 'GTC' = Good To Cancel (default), 'IOC' = Immediate Or Cancel
'quoteOrderQty': true, // whether market orders support amounts in quote currency
},
'accountsByType': {
'spot': 'SPOT',
'swap': 'FUTURE',
'future': 'FUTURE',
'linear': 'FUTURE',
},
'networks': {
'ERC20': 'ETH',
'BEP20': 'BSC',
'ARBONE': 'Arbitrum',
},
'networksToChainId': {
'ETH': 1,
'BSC': 56,
'Arbitrum': 42161,
},
'fetchOpenOrders': {
'warnIfNoSymbol': true, // set to false to suppress warning when calling fetchOpenOrders without symbol
},
'builderFee': true,
'builder': '0x1F5877C19e3777Cfd15F9d57253eA4aA5254Ec39',
'builderRate': '0.001',
},
'exceptions': {
'exact': {
// 10xx - General Server or Network issues
'-1000': OperationRejected, // UNKNOWN
'-1001': NetworkError, // DISCONNECTED
'-1002': AuthenticationError, // UNAUTHORIZED
'-1003': RateLimitExceeded, // TOO_MANY_REQUESTS
'-1004': DuplicateOrderId, // DUPLICATE_IP
'-1005': BadRequest, // NO_SUCH_IP
'-1006': BadResponse, // UNEXPECTED_RESP
'-1007': RequestTimeout, // TIMEOUT
'-1010': OperationRejected, // ERROR_MSG_RECEIVED
'-1011': PermissionDenied, // NON_WHITE_LIST
'-1013': BadRequest, // INVALID_MESSAGE
'-1014': OrderNotFillable, // UNKNOWN_ORDER_COMPOSITION
'-1015': RateLimitExceeded, // TOO_MANY_ORDERS
'-1016': ExchangeClosedByUser, // SERVICE_SHUTTING_DOWN
'-1020': NotSupported, // UNSUPPORTED_OPERATION
'-1021': InvalidNonce, // INVALID_TIMESTAMP
'-1022': AuthenticationError, // INVALID_SIGNATURE
'-1023': BadRequest, // START_TIME_GREATER_THAN_END_TIME
// 11xx - Request issues
'-1100': BadRequest, // ILLEGAL_CHARS
'-1101': BadRequest, // TOO_MANY_PARAMETERS
'-1102': ArgumentsRequired, // MANDATORY_PARAM_EMPTY_OR_MALFORMED
'-1103': BadRequest, // UNKNOWN_PARAM
'-1104': BadRequest, // UNREAD_PARAMETERS
'-1105': ArgumentsRequired, // PARAM_EMPTY
'-1106': BadRequest, // PARAM_NOT_REQUIRED
'-1108': BadRequest, // BAD_ASSET
'-1109': BadRequest, // BAD_ACCOUNT
'-1110': BadSymbol, // BAD_INSTRUMENT_TYPE
'-1111': BadRequest, // BAD_PRECISION
'-1112': BadRequest, // NO_DEPTH
'-1113': BadRequest, // WITHDRAW_NOT_NEGATIVE
'-1114': BadRequest, // TIF_NOT_REQUIRED
'-1115': InvalidOrder, // INVALID_TIF
'-1116': InvalidOrder, // INVALID_ORDER_TYPE
'-1117': InvalidOrder, // INVALID_SIDE
'-1118': InvalidOrder, // EMPTY_NEW_CL_ORD_ID
'-1119': InvalidOrder, // EMPTY_ORG_CL_ORD_ID
'-1120': BadRequest, // BAD_INTERVAL
'-1121': BadSymbol, // BAD_SYMBOL
'-1125': AuthenticationError, // INVALID_LISTEN_KEY
'-1127': BadRequest, // MORE_THAN_XX_HOURS
'-1128': BadRequest, // OPTIONAL_PARAMS_BAD_COMBO
'-1130': BadRequest, // INVALID_PARAMETER
'-1136': InvalidOrder, // INVALID_NEW_ORDER_RESP_TYPE
// 20xx - Processing Issues
'-2010': InvalidOrder, // NEW_ORDER_REJECTED
'-2011': OrderNotFound, // CANCEL_REJECTED
'-2013': OrderNotFound, // NO_SUCH_ORDER
'-2014': AuthenticationError, // BAD_API_KEY_FMT
'-2015': AuthenticationError, // REJECTED_MBX_KEY
'-2016': MarketClosed, // NO_TRADING_WINDOW
'-2018': InsufficientFunds, // BALANCE_NOT_SUFFICIENT
'-2019': InsufficientFunds, // MARGIN_NOT_SUFFICIEN
'-2020': OrderNotFillable, // UNABLE_TO_FILL
'-2021': OrderImmediatelyFillable, // ORDER_WOULD_IMMEDIATELY_TRIGGER
'-2022': OperationRejected, // REDUCE_ONLY_REJECT
'-2023': AccountSuspended, // USER_IN_LIQUIDATION
'-2024': InsufficientFunds, // POSITION_NOT_SUFFICIENT
'-2025': RateLimitExceeded, // MAX_OPEN_ORDER_EXCEEDED
'-2026': NotSupported, // REDUCE_ONLY_ORDER_TYPE_NOT_SUPPORTED
'-2027': BadRequest, // MAX_LEVERAGE_RATIO
'-2028': BadRequest, // MIN_LEVERAGE_RATIO
// 40xx - Filters and other Issues
'-4000': InvalidOrder, // INVALID_ORDER_STATUS
'-4001': InvalidOrder, // PRICE_LESS_THAN_ZERO
'-4002': InvalidOrder, // PRICE_GREATER_THAN_MAX_PRICE
'-4003': InvalidOrder, // QTY_LESS_THAN_ZERO
'-4004': InvalidOrder, // QTY_LESS_THAN_MIN_QTY
'-4005': InvalidOrder, // QTY_GREATER_THAN_MAX_QTY
'-4006': InvalidOrder, // STOP_PRICE_LESS_THAN_ZERO
'-4007': InvalidOrder, // STOP_PRICE_GREATER_THAN_MAX_PRICE
'-4008': InvalidOrder, // TICK_SIZE_LESS_THAN_ZERO
'-4009': InvalidOrder, // MAX_PRICE_LESS_THAN_MIN_PRICE
'-4010': InvalidOrder, // MAX_QTY_LESS_THAN_MIN_QTY
'-4011': InvalidOrder, // STEP_SIZE_LESS_THAN_ZERO
'-4012': RateLimitExceeded, // MAX_NUM_ORDERS_LESS_THAN_ZERO
'-4013': InvalidOrder, // PRICE_LESS_THAN_MIN_PRICE
'-4014': InvalidOrder, // PRICE_NOT_INCREASED_BY_TICK_SIZE
'-4015': InvalidOrder, // INVALID_CL_ORD_ID_LEN
'-4016': InvalidOrder, // PRICE_HIGHTER_THAN_MULTIPLIER_UP
'-4017': InvalidOrder, // MULTIPLIER_UP_LESS_THAN_ZERO
'-4018': InvalidOrder, // MULTIPLIER_DOWN_LESS_THAN_ZERO
'-4019': BadRequest, // COMPOSITE_SCALE_OVERFLOW
'-4020': BadRequest, // TARGET_STRATEGY_INVALID
'-4021': BadRequest, // INVALID_DEPTH_LIMIT
'-4022': MarketClosed, // WRONG_MARKET_STATUS
'-4023': InvalidOrder, // QTY_NOT_INCREASED_BY_STEP_SIZE
'-4024': InvalidOrder, // PRICE_LOWER_THAN_MULTIPLIER_DOWN
'-4025': BadRequest, // MULTIPLIER_DECIMAL_LESS_THAN_ZERO
'-4026': BadRequest, // COMMISSION_INVALID
'-4027': BadRequest, // INVALID_ACCOUNT_TYPE
'-4028': BadRequest, // INVALID_LEVERAGE
'-4029': BadRequest, // INVALID_TICK_SIZE_PRECISION
'-4030': BadRequest, // INVALID_STEP_SIZE_PRECISION
'-4031': BadRequest, // INVALID_WORKING_TYPE
'-4032': RateLimitExceeded, // EXCEED_MAX_CANCEL_ORDER_SIZE
'-4033': AccountNotEnabled, // INSURANCE_ACCOUNT_NOT_FOUND
'-4044': BadRequest, // INVALID_BALANCE_TYPE
'-4045': RateLimitExceeded, // MAX_STOP_ORDER_EXCEEDED
'-4046': NoChange, // NO_NEED_TO_CHANGE_MARGIN_TYPE
'-4047': OperationRejected, // THERE_EXISTS_OPEN_ORDERS
'-4048': OperationRejected, // THERE_EXISTS_QUANTITY
'-4049': OperationRejected, // ADD_ISOLATED_MARGIN_REJECT
'-4050': InsufficientFunds, // CROSS_BALANCE_INSUFFICIENT
'-4051': InsufficientFunds, // ISOLATED_BALANCE_INSUFFICIENT
'-4052': NoChange, // NO_NEED_TO_CHANGE_AUTO_ADD_MARGIN
'-4053': OperationRejected, // AUTO_ADD_CROSSED_MARGIN_REJECT
'-4054': OperationRejected, // ADD_ISOLATED_MARGIN_NO_POSITION_REJECT
'-4055': ArgumentsRequired, // AMOUNT_MUST_BE_POSITIVE
'-4056': AuthenticationError, // INVALID_API_KEY_TYPE
'-4057': AuthenticationError, // INVALID_RSA_PUBLIC_KEY
'-4058': InvalidOrder, // MAX_PRICE_TOO_LARGE
'-4059': NoChange, // NO_NEED_TO_CHANGE_POSITION_SIDE
'-4060': InvalidOrder, // INVALID_POSITION_SIDE
'-4061': InvalidOrder, // POSITION_SIDE_NOT_MATCH
'-4062': OperationRejected, // REDUCE_ONLY_CONFLICT
'-4063': BadRequest, // INVALID_OPTIONS_REQUEST_TYPE
'-4064': BadRequest, // INVALID_OPTIONS_TIME_FRAME
'-4065': BadRequest, // INVALID_OPTIONS_AMOUNT
'-4066': BadRequest, // INVALID_OPTIONS_EVENT_TYPE
'-4067': OperationRejected, // POSITION_SIDE_CHANGE_EXISTS_OPEN_ORDERS
'-4068': OperationRejected, // POSITION_SIDE_CHANGE_EXISTS_QUANTITY
'-4069': BadRequest, // INVALID_OPTIONS_PREMIUM_FEE
'-4070': InvalidOrder, // INVALID_CL_OPTIONS_ID_LEN
'-4071': InvalidOrder, // INVALID_OPTIONS_DIRECTION
'-4072': NoChange, // OPTIONS_PREMIUM_NOT_UPDATE
'-4073': BadRequest, // OPTIONS_PREMIUM_INPUT_LESS_THAN_ZERO
'-4074': InvalidOrder, // OPTIONS_AMOUNT_BIGGER_THAN_UPPER
'-4075': OperationRejected, // OPTIONS_PREMIUM_OUTPUT_ZERO
'-4076': OperationRejected, // OPTIONS_PREMIUM_TOO_DIFF
'-4077': RateLimitExceeded, // OPTIONS_PREMIUM_REACH_LIMIT
'-4078': BadRequest, // OPTIONS_COMMON_ERROR
'-4079': BadRequest, // INVALID_OPTIONS_ID
'-4080': BadRequest, // OPTIONS_USER_NOT_FOUND
'-4081': BadRequest, // OPTIONS_NOT_FOUND
'-4082': RateLimitExceeded, // INVALID_BATCH_PLACE_ORDER_SIZE
'-4083': OperationFailed, // PLACE_BATCH_ORDERS_FAIL
'-4084': NotSupported, // UPCOMING_METHOD
'-4085': BadRequest, // INVALID_NOTIONAL_LIMIT_COEF
'-4086': BadRequest, // INVALID_PRICE_SPREAD_THRESHOLD
'-4087': PermissionDenied, // REDUCE_ONLY_ORDER_PERMISSION
'-4088': PermissionDenied, // NO_PLACE_ORDER_PERMISSION
'-4104': BadSymbol, // INVALID_CONTRACT_TYPE
'-4114': InvalidOrder, // INVALID_CLIENT_TRAN_ID_LEN
'-4115': DuplicateOrderId, // DUPLICATED_CLIENT_TRAN_ID
'-4118': InsufficientFunds, // REDUCE_ONLY_MARGIN_CHECK_FAILED
'-4131': InvalidOrder, // MARKET_ORDER_REJECT
'-4135': InvalidOrder, // INVALID_ACTIVATION_PRICE
'-4137': InvalidOrder, // QUANTITY_EXISTS_WITH_CLOSE_POSITION
'-4138': OperationRejected, // REDUCE_ONLY_MUST_BE_TRUE
'-4139': InvalidOrder, // ORDER_TYPE_CANNOT_BE_MKT
'-4140': OperationRejected, // INVALID_OPENING_POSITION_STATUS
'-4141': MarketClosed, // SYMBOL_ALREADY_CLOSED
'-4142': InvalidOrder, // STRATEGY_INVALID_TRIGGER_PRICE
'-4144': BadSymbol, // INVALID_PAIR
'-4161': OperationRejected, // ISOLATED_LEVERAGE_REJECT_WITH_POSITION
'-4164': InvalidOrder, // MIN_NOTIONAL
'-4165': BadRequest, // INVALID_TIME_INTERVAL
'-4183': InvalidOrder, // PRICE_HIGHTER_THAN_STOP_MULTIPLIER_UP
'-4184': InvalidOrder, // PRICE_LOWER_THAN_STOP_MULTIPLIER_DOWN
'-5060': OperationRejected, // {"code":-5060,"msg":"The limit order price does not meet the PERCENT_PRICE filter limit."}
'-5076': OperationRejected, // {"code":-5076,"msg":"Total order value should be more than 5 USDT"}
// occured errors:
'-4168': OperationRejected, // Unable to adjust to isolated-margin mode under the Multi-Assets mode.
},
'broad': {},
},
});
}
isInverse(type, subType = undefined) {
if (subType === undefined) {
return (type === 'delivery');
}
else {
return subType === 'inverse';
}
}
isLinear(type, subType = undefined) {
if (subType === undefined) {
return (type === 'future') || (type === 'swap');
}
else {
return subType === 'linear';
}
}
/**
* @method
* @name aster#fetchCurrencies
* @description fetches all available currencies on an exchange
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#trading-specification-information
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#exchange-information
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} an associative dictionary of currencies
*/
async fetchCurrencies(params = {}) {
const sapiResult = await this.sapiPublicGetV3ExchangeInfo(params);
const sapiRows = this.safeList(sapiResult, 'assets', []);
//
// [
// {
// "asset": "USDT",
// "marginAvailable": true, // only in PERP
// "autoAssetExchange": "-10000" // only in PERP
// }
// ]
//
return this.parseCurrencies(sapiRows);
}
parseCurrency(rawCurrency) {
const currencyId = this.safeString(rawCurrency, 'asset');
const code = this.safeCurrencyCode(currencyId);
return this.safeCurrencyStructure({
'info': rawCurrency,
'code': code,
'id': currencyId,
'name': code,
'active': undefined,
'deposit': undefined,
'withdraw': undefined,
'fee': undefined,
'precision': undefined,
'margin': this.safeBool(rawCurrency, 'marginAvailable'),
'limits': {
'amount': {
'min': undefined,
'max': undefined,
},
'withdraw': {
'min': undefined,
'max': undefined,
},
'deposit': {
'min': undefined,
'max': undefined,
},
},
'networks': undefined,
'type': 'crypto', // atm exchange api provides only cryptos
});
}
/**
* @method
* @name aster#fetchMarkets
* @description retrieves data on all markets for bigone
* @see https://asterdex.github.io/aster-api-website/spot-v3/market-data/#trading-specification-information
* @see https://asterdex.github.io/aster-api-website/futures-v3/market-data/#exchange-information
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object[]} an array of objects representing market data
*/
async fetchMarkets(params = {}) {
const promises = [
this.sapiPublicGetV3ExchangeInfo(params),
this.fapiPublicGetV3ExchangeInfo(params),
];
promises.push(this.signIn());
const results = await Promise.all(promises);
const sapiResult = this.safeDict(results, 0, {});
const sapiRows = this.safeList(sapiResult, 'symbols', []);
const fapiResult = this.safeDict(results, 1, {});
const fapiRows = this.safeList(fapiResult, 'symbols', []);
//
// example:
//
// [
// {
// symbol: "TESTUSDT",
// status: "TRADING",
// baseAsset: "TEST",
// quoteAsset: "USDT",
// pricePrecision: "2",
// quantityPrecision: "5",
// baseAssetPrecision: "8",
// quotePrecision: "8",
// listingTime: "1756289680210", // only in SPOT
// baseAssetAddress: null, // only in SPOT
// ocoAllowed: false, // only in SPOT
// pair: "ASTERUSDT", // only in PERP
// contractType: "PERPETUAL", // only in PERP
// deliveryDate: "4133404800000", // only in PERP
// onboardDate: "1758178800000", // only in PERP
// maintMarginPercent: "12.5000", // only in PERP
// requiredMarginPercent: "25.0000", // only in PERP
// marginAsset: "USDT", // only in PERP
// underlyingType: "COIN", // only in PERP
// underlyingSubType: [ "Top", ], // only in PERP
// symbolType: "0", // only in PERP
// tradingMode: "0", // only in PERP
// name: "", // only in PERP
// channel: "{}", // only in PERP
// sequenceNo: "100", // only in PERP
// twapMinNotional: "1000", // only in PERP
// imn: "4000.00", // only in PERP
// tags: [], // only in PERP
// settlePlan: "0", // only in PERP
// triggerProtect: "0.1500", // only in PERP
// liquidationFee: "0.025000", // only in PERP
// marketTakeBound: "0.05", // only in PERP
// createTime: "1758215451058", // only in PERP
// filters: [
// {
// minPrice: "0.01",
// maxPrice: "1000000",
// filterType: "PRICE_FILTER",
// tickSize: "0.01",
// },
// {
// stepSize: "0.00001",
// filterType: "LOT_SIZE",
// maxQty: "9000",
// minQty: "0.00001",
// },
// {
// stepSize: "0.00001",
// filterType: "MARKET_LOT_SIZE",
// maxQty: "9000",
// minQty: "0.00001",
// },
// {
// limit: "200",
// filterType: "MAX_NUM_ORDERS",
// },
// {
// minNotional: "5",
// filterType: "MIN_NOTIONAL",
// },
// {
// minNotional: "5",
// avgPriceMins: "5",
// applyMinToMarket: true,
// filterType: "NOTIONAL", // only in SPOT
// applyMaxToMarket: true,
// },
// {
// multiplierDown: "0.2",
// multiplierUp: "5",
// multiplierDecimal: "1",
// filterType: "PERCENT_PRICE",
// },
// {
// bidMultiplierUp: "5",
// askMultiplierUp: "5",
// bidMultiplierDown: "0.2",
// avgPriceMins: "5",
// multiplierDecimal: "1",
// filterType: "PERCENT_PRICE_BY_SIDE", // only in SPOT
// askMultiplierDown: "0.2",
// },
// ],
// orderTypes: [ "LIMIT", "MARKET", "STOP", "STOP_MARKET", "TAKE_PROFIT", "TAKE_PROFIT_MARKET", "TRAILING_STOP_MARKET", ],
// timeInForce: [ "GTC", "IOC", "FOK", "GTX", "HIDDEN", ],
// }
// ]
//
//
const fapiRowsFiltered = [];
for (let i = 0; i < fapiRows.length; i++) {
const market = fapiRows[i];
// tmp skip some markets with base = undefined
if (this.safeString(market, 'baseAsset')) {
fapiRowsFiltered.push(market);
}
}
const rows = this.arrayConcat(sapiRows, fapiRowsFiltered);
return this.parseMarkets(rows);
}
parseMarket(market) {
const id = this.safeString(market, 'symbol');
const baseId = this.safeString(market, 'baseAsset');
const quoteId = this.safeString(market, 'quoteAsset');
const base = this.safeCurrencyCode(baseId);
const quote = this.safeCurrencyCode(quoteId);
const active = this.safeString(market, 'status') === 'TRADING';
let spot = undefined;
let symbol = undefined;
let settle = undefined;
let settleId = undefined;
let swap = undefined;
let linear = undefined;
let inverse = undefined;
let contractSize = undefined;
const contractType = this.safeString(market, 'contractType');
const isContract = contractType !== undefined;
if (isContract) {
// currently, there is only perpetuals, not futures
spot = false;
swap = true;
settleId = this.safeString(market, 'marginAsset');
settle = this.safeCurrencyCode(settleId);
symbol = base + '/' + quote + ':' + settle;
linear = settle === quote;
inverse = settle === base;
contractSize = this.safeNumber2(market, 'contractSize', 'unit', this.parseNumber('1'));
}
else {
spot = true;
swap = false;
symbol = base + '/' + quote;
}
// filters
const filters = this.safeList(market, 'filters', []);
const filtersByType = this.indexBy(filters, 'filterType');
const filterNotional = this.safeDict2(filtersByType, 'MIN_NOTIONAL', 'NOTIONAL');
const filterPrice = this.safeDict(filtersByType, 'PRICE_FILTER');
const filterLotSize = this.safeDict(filtersByType, 'LOT_SIZE');
const filterMarketLotSize = this.safeDict(filtersByType, 'MARKET_LOT_SIZE', {});
let pricePrecision = this.safeNumber(filterPrice, 'tickSize');
if (pricePrecision === undefined) {
pricePrecision = this.parseNumber(this.parsePrecision(this.safeString(market, 'pricePrecision')));
}
const amountPrecision = (filterLotSize !== undefined) ? this.safeNumber(filterLotSize, 'stepSize') : this.parseNumber(this.parsePrecision(this.safeString(market, 'quantityPrecision')));
return this.safeMarketStructure({
'id': id,
'symbol': symbol,
'base': base,
'quote': quote,
'settle': settle,
'baseId': baseId,
'quoteId': quoteId,
'settleId': settleId,
'type': isContract ? 'swap' : 'spot',
'spot': spot,
'margin': false,
'swap': swap,
'future': false,
'option': false,
'active': active,
'contract': isContract,
'linear': linear,
'inverse': inverse,
'taker': this.fees['trading']['taker'],
'maker': this.fees['trading']['maker'],
'contractSize': contractSize,
'expiry': undefined,
'expiryDatetime': undefined,
'strike': undefined,
'optionType': undefined,
'precision': {
'amount': amountPrecision,
'price': pricePrecision,
'base': this.parseNumber(this.parsePrecision(this.safeString(market, 'baseAssetPrecision'))),
'quote': this.parseNumber(this.parsePrecision(this.safeString(market, 'quotePrecision'))),
},
'limits': {
'leverage': {
'min': undefined,
'max': undefined,
},
'amount': {
'min': this.safeNumber(filterLotSize, 'minQty'),
'max': this.safeNumber(filterLotSize, 'maxQty'),
},
'price': {
'min': this.safeNumber(filterPrice, 'minPrice'),
'max': this.safeNumber(filterPrice, 'maxPrice'),