UNPKG

ccxt

Version:

A cryptocurrency trading API with more than 100 exchanges in JavaScript / TypeScript / Python / C# / PHP / Go

1,193 lines (1,191 loc) • 173 kB
// ---------------------------------------------------------------------------- // 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 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 } from './base/errors.js'; import { TRUNCATE, TICK_SIZE } from './base/functions/number.js'; import Precise from './base/Precise.js'; import { sha256 } from './static_dependencies/noble-hashes/sha256.js'; import { ecdsa } from './base/functions/crypto.js'; import { keccak_256 as keccak } from './static_dependencies/noble-hashes/sha3.js'; import { secp256k1 } from './static_dependencies/noble-curves/secp256k1.js'; // ---------------------------------------------------------------------------xs /** * @class aster * @augments Exchange */ export default class aster extends Exchange { describe() { return this.deepExtend(super.describe(), { 'id': 'aster', 'name': 'Aster', 'dex': true, '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, 'hostname': 'aster.markets', 'pro': true, 'urls': { 'logo': 'https://github.com/user-attachments/assets/4982201b-73cd-4d7a-8907-e69e239e9609', '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': false, 'margin': false, 'swap': false, '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': false, 'transfer': true, 'withdraw': true, }, 'api': { 'fapiPublic': { 'get': [ 'v1/ping', 'v1/time', 'v1/exchangeInfo', 'v1/depth', 'v1/trades', 'v1/historicalTrades', 'v1/aggTrades', 'v1/klines', 'v1/indexPriceKlines', 'v1/markPriceKlines', 'v1/premiumIndex', 'v1/fundingRate', 'v1/fundingInfo', 'v1/ticker/24hr', 'v1/ticker/price', 'v1/ticker/bookTicker', 'v1/adlQuantile', 'v1/forceOrders', ], 'post': [ 'v1/listenKey', ], 'put': [ 'v1/listenKey', ], 'delete': [ 'v1/listenKey', ], }, 'fapiPrivate': { 'get': [ 'v1/positionSide/dual', 'v1/multiAssetsMargin', 'v1/order', 'v1/openOrder', 'v1/openOrders', 'v1/allOrders', 'v2/balance', 'v3/balance', 'v3/account', 'v4/account', 'v1/positionMargin/history', 'v2/positionRisk', 'v3/positionRisk', 'v1/userTrades', 'v1/income', 'v1/leverageBracket', 'v1/commissionRate', ], 'post': [ 'v1/positionSide/dual', 'v1/multiAssetsMargin', 'v1/order', 'v1/order/test', 'v1/batchOrders', 'v1/asset/wallet/transfer', 'v1/countdownCancelAll', 'v1/leverage', 'v1/marginType', 'v1/positionMargin', ], 'delete': [ 'v1/order', 'v1/allOpenOrders', 'v1/batchOrders', ], }, 'sapiPublic': { 'get': [ 'v1/ping', 'v1/time', 'v1/exchangeInfo', 'v1/depth', 'v1/trades', 'v1/historicalTrades', 'v1/aggTrades', 'v1/klines', 'v1/ticker/24hr', 'v1/ticker/price', 'v1/ticker/bookTicker', 'v1/aster/withdraw/estimateFee', ], 'post': [ 'v1/getNonce', 'v1/createApiKey', 'v1/listenKey', ], 'put': [ 'v1/listenKey', ], 'delete': [ 'v1/listenKey', ], }, 'sapiPrivate': { 'get': [ 'v1/commissionRate', 'v1/order', 'v1/openOrders', 'v1/allOrders', 'v1/transactionHistory', 'v1/account', 'v1/userTrades', ], 'post': [ 'v1/order', 'v1/asset/wallet/transfer', 'v1/asset/sendToAddress', 'v1/aster/user-withdraw', ], 'delete': [ 'v1/order', 'v1/allOpenOrders', ], }, }, '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': true, 'secret': true, }, 'fees': { 'trading': { 'tierBased': true, 'percentage': true, 'maker': this.parseNumber('0.0001'), 'taker': this.parseNumber('0.00035'), }, }, 'options': { 'recvWindow': 10 * 1000, 'defaultTimeInForce': 'GTC', 'zeroAddress': '0x0000000000000000000000000000000000000000', 'quoteOrderQty': true, 'accountsByType': { 'spot': 'SPOT', 'future': 'FUTURE', 'linear': 'FUTURE', 'swap': 'FUTURE', }, 'networks': { 'ERC20': 'ETH', 'BEP20': 'BSC', 'ARB': 'Arbitrum', }, 'networksToChainId': { 'ETH': 1, 'BSC': 56, 'Arbitrum': 42161, }, }, 'exceptions': { 'exact': { // 10xx - General Server or Network issues '-1000': OperationFailed, '-1001': NetworkError, '-1002': AuthenticationError, '-1003': RateLimitExceeded, '-1004': DuplicateOrderId, '-1005': BadRequest, '-1006': BadResponse, '-1007': RequestTimeout, '-1010': OperationFailed, '-1011': PermissionDenied, '-1013': BadRequest, '-1014': OrderNotFillable, '-1015': RateLimitExceeded, '-1016': ExchangeClosedByUser, '-1020': NotSupported, '-1021': InvalidNonce, '-1022': AuthenticationError, '-1023': BadRequest, // 11xx - Request issues '-1100': BadRequest, '-1101': BadRequest, '-1102': ArgumentsRequired, '-1103': BadRequest, '-1104': BadRequest, '-1105': ArgumentsRequired, '-1106': BadRequest, '-1108': BadRequest, '-1109': BadRequest, '-1110': BadSymbol, '-1111': BadRequest, '-1112': BadRequest, '-1113': BadRequest, '-1114': BadRequest, '-1115': InvalidOrder, '-1116': InvalidOrder, '-1117': InvalidOrder, '-1118': InvalidOrder, '-1119': InvalidOrder, '-1120': BadRequest, '-1121': BadSymbol, '-1125': AuthenticationError, '-1127': BadRequest, '-1128': BadRequest, '-1130': BadRequest, '-1136': InvalidOrder, // 20xx - Processing Issues '-2010': InvalidOrder, '-2011': OrderNotFound, '-2013': OrderNotFound, '-2014': AuthenticationError, '-2015': AuthenticationError, '-2016': MarketClosed, '-2018': InsufficientFunds, '-2019': InsufficientFunds, '-2020': OrderNotFillable, '-2021': OrderImmediatelyFillable, '-2022': OperationRejected, '-2023': AccountSuspended, '-2024': InsufficientFunds, '-2025': RateLimitExceeded, '-2026': NotSupported, '-2027': BadRequest, '-2028': BadRequest, // 40xx - Filters and other Issues '-4000': InvalidOrder, '-4001': InvalidOrder, '-4002': InvalidOrder, '-4003': InvalidOrder, '-4004': InvalidOrder, '-4005': InvalidOrder, '-4006': InvalidOrder, '-4007': InvalidOrder, '-4008': InvalidOrder, '-4009': InvalidOrder, '-4010': InvalidOrder, '-4011': InvalidOrder, '-4012': RateLimitExceeded, '-4013': InvalidOrder, '-4014': InvalidOrder, '-4015': InvalidOrder, '-4016': InvalidOrder, '-4017': InvalidOrder, '-4018': InvalidOrder, '-4019': BadRequest, '-4020': BadRequest, '-4021': BadRequest, '-4022': MarketClosed, '-4023': InvalidOrder, '-4024': InvalidOrder, '-4025': BadRequest, '-4026': BadRequest, '-4027': BadRequest, '-4028': BadRequest, '-4029': BadRequest, '-4030': BadRequest, '-4031': BadRequest, '-4032': RateLimitExceeded, '-4033': AccountNotEnabled, '-4044': BadRequest, '-4045': RateLimitExceeded, '-4046': NoChange, '-4047': OperationRejected, '-4048': OperationRejected, '-4049': OperationRejected, '-4050': InsufficientFunds, '-4051': InsufficientFunds, '-4052': NoChange, '-4053': OperationRejected, '-4054': OperationRejected, '-4055': ArgumentsRequired, '-4056': AuthenticationError, '-4057': AuthenticationError, '-4058': InvalidOrder, '-4059': NoChange, '-4060': InvalidOrder, '-4061': InvalidOrder, '-4062': OperationRejected, '-4063': BadRequest, '-4064': BadRequest, '-4065': BadRequest, '-4066': BadRequest, '-4067': OperationRejected, '-4068': OperationRejected, '-4069': BadRequest, '-4070': InvalidOrder, '-4071': InvalidOrder, '-4072': NoChange, '-4073': BadRequest, '-4074': InvalidOrder, '-4075': OperationRejected, '-4076': OperationRejected, '-4077': RateLimitExceeded, '-4078': BadRequest, '-4079': BadRequest, '-4080': BadRequest, '-4081': BadRequest, '-4082': RateLimitExceeded, '-4083': OperationFailed, '-4084': NotSupported, '-4085': BadRequest, '-4086': BadRequest, '-4087': PermissionDenied, '-4088': PermissionDenied, '-4104': BadSymbol, '-4114': InvalidOrder, '-4115': DuplicateOrderId, '-4118': InsufficientFunds, '-4131': InvalidOrder, '-4135': InvalidOrder, '-4137': InvalidOrder, '-4138': OperationRejected, '-4139': InvalidOrder, '-4140': OperationRejected, '-4141': MarketClosed, '-4142': InvalidOrder, '-4144': BadSymbol, '-4161': OperationRejected, '-4164': InvalidOrder, '-4165': BadRequest, '-4183': InvalidOrder, '-4184': InvalidOrder, '-5060': OperationRejected, '-5076': OperationRejected, // {"code":-5076,"msg":"Total order value should be more than 5 USDT"} }, '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://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#trading-specification-information * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#exchange-information * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ async fetchCurrencies(params = {}) { const promises = [ this.sapiPublicGetV1ExchangeInfo(params), this.fapiPublicGetV1ExchangeInfo(params), ]; const results = await Promise.all(promises); const sapiResult = this.safeDict(results, 0, {}); const sapiRows = this.safeList(sapiResult, 'assets', []); const fapiResult = this.safeDict(results, 1, {}); const fapiRows = this.safeList(fapiResult, 'assets', []); const rows = this.arrayConcat(sapiRows, fapiRows); // // [ // { // "asset": "USDT", // "marginAvailable": true, // "autoAssetExchange": "-10000" // } // ] // const result = {}; for (let i = 0; i < rows.length; i++) { const currency = rows[i]; const currencyId = this.safeString(currency, 'asset'); const code = this.safeCurrencyCode(currencyId); result[code] = this.safeCurrencyStructure({ 'info': currency, 'code': code, 'id': currencyId, 'name': code, 'active': undefined, 'deposit': undefined, 'withdraw': undefined, 'fee': undefined, 'precision': undefined, '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 }); } return result; } /** * @method * @name aster#fetchMarkets * @description retrieves data on all markets for bigone * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#trading-specification-information * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#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.sapiPublicGetV1ExchangeInfo(params), this.fapiPublicGetV1ExchangeInfo(params), ]; 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', []); const rows = this.arrayConcat(sapiRows, fapiRows); // // [ // { // "symbol": "BTCUSDT", // "pair": "BTCUSDT", // "contractType": "PERPETUAL", // "deliveryDate": 4133404800000, // "onboardDate": 1627628400000, // "status": "TRADING", // "maintMarginPercent": "2.5000", // "requiredMarginPercent": "5.0000", // "baseAsset": "BTC", // "quoteAsset": "USDT", // "marginAsset": "USDT", // "pricePrecision": 1, // "quantityPrecision": 3, // "baseAssetPrecision": 8, // "quotePrecision": 8, // "underlyingType": "COIN", // "underlyingSubType": [], // "settlePlan": 0, // "triggerProtect": "0.0200", // "liquidationFee": "0.025000", // "marketTakeBound": "0.02", // "filters": [ // { // "minPrice": "1", // "maxPrice": "1000000", // "filterType": "PRICE_FILTER", // "tickSize": "0.1" // }, // { // "stepSize": "0.001", // "filterType": "LOT_SIZE", // "maxQty": "100", // "minQty": "0.001" // }, // { // "stepSize": "0.001", // "filterType": "MARKET_LOT_SIZE", // "maxQty": "10", // "minQty": "0.001" // }, // { // "limit": 200, // "filterType": "MAX_NUM_ORDERS" // }, // { // "limit": 10, // "filterType": "MAX_NUM_ALGO_ORDERS" // }, // { // "notional": "5", // "filterType": "MIN_NOTIONAL" // }, // { // "multiplierDown": "0.9800", // "multiplierUp": "1.0200", // "multiplierDecimal": "4", // "filterType": "PERCENT_PRICE" // } // ], // "orderTypes": [ // "LIMIT", // "MARKET", // "STOP", // "STOP_MARKET", // "TAKE_PROFIT", // "TAKE_PROFIT_MARKET", // "TRAILING_STOP_MARKET" // ], // "timeInForce": [ // "GTC", // "IOC", // "FOK", // "GTX", // "RPI" // ] // } // ] // const fees = this.fees; const result = []; for (let i = 0; i < rows.length; i++) { let swap = false; const market = rows[i]; 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 contractType = this.safeString(market, 'contractType'); const contract = contractType !== undefined; let spot = true; if (contractType === 'PERPETUAL') { swap = true; spot = false; } let contractSize = undefined; let linear = undefined; let inverse = undefined; let symbol = base + '/' + quote; let settle = undefined; let settleId = undefined; if (contract) { settleId = this.safeString(market, 'marginAsset'); settle = this.safeCurrencyCode(settleId); if (swap) { symbol = symbol + ':' + settle; } linear = settle === quote; inverse = settle === base; contractSize = this.safeNumber2(market, 'contractSize', 'unit', this.parseNumber('1')); } let unifiedType = undefined; if (spot) { unifiedType = 'spot'; } else if (swap) { unifiedType = 'swap'; } const status = this.safeString(market, 'status'); const active = status === 'TRADING'; const filters = this.safeList(market, 'filters', []); const filtersByType = this.indexBy(filters, 'filterType'); const entry = this.safeMarketStructure({ 'id': id, 'symbol': symbol, 'base': base, 'quote': quote, 'settle': settle, 'baseId': baseId, 'quoteId': quoteId, 'settleId': settleId, 'type': unifiedType, 'spot': spot, 'margin': false, 'swap': swap, 'future': false, 'option': false, 'active': active, 'contract': contract, 'linear': linear, 'inverse': inverse, 'taker': fees['trading']['taker'], 'maker': fees['trading']['maker'], 'contractSize': contractSize, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': this.parseNumber(this.parsePrecision(this.safeString(market, 'quantityPrecision'))), 'price': this.parseNumber(this.parsePrecision(this.safeString(market, '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': undefined, 'max': undefined, }, 'price': { 'min': undefined, 'max': undefined, }, 'cost': { 'min': undefined, 'max': undefined, }, }, 'created': this.safeInteger(market, 'onboardDate'), 'info': market, }); if ('PRICE_FILTER' in filtersByType) { const filter = this.safeDict(filtersByType, 'PRICE_FILTER', {}); entry['limits']['price'] = { 'min': this.safeNumber(filter, 'minPrice'), 'max': this.safeNumber(filter, 'maxPrice'), }; entry['precision']['price'] = this.safeNumber(filter, 'tickSize'); } if ('LOT_SIZE' in filtersByType) { const filter = this.safeDict(filtersByType, 'LOT_SIZE', {}); entry['precision']['amount'] = this.safeNumber(filter, 'stepSize'); entry['limits']['amount'] = { 'min': this.safeNumber(filter, 'minQty'), 'max': this.safeNumber(filter, 'maxQty'), }; } if ('MARKET_LOT_SIZE' in filtersByType) { const filter = this.safeDict(filtersByType, 'MARKET_LOT_SIZE', {}); entry['limits']['market'] = { 'min': this.safeNumber(filter, 'minQty'), 'max': this.safeNumber(filter, 'maxQty'), }; } if (('MIN_NOTIONAL' in filtersByType) || ('NOTIONAL' in filtersByType)) { const filter = this.safeDict2(filtersByType, 'MIN_NOTIONAL', 'NOTIONAL', {}); entry['limits']['cost']['min'] = this.safeNumber(filter, 'notional'); } result.push(entry); } return result; } /** * @method * @name aster#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#check-server-time * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ async fetchTime(params = {}) { const response = await this.fapiPublicGetV1Time(params); // // { // "serverTime": 1499827319559 // } // return this.safeInteger(response, 'serverTime'); } parseOHLCV(ohlcv, market = undefined) { // // [ // 1631158560000, // "208.1850", // "208.1850", // "208.1850", // "208.1850", // "11.84", // 1631158619999, // "2464.910400", // 1, // "11.84", // "2464.910400", // "0" // ] // return [ this.safeInteger(ohlcv, 0), this.safeNumber(ohlcv, 1), this.safeNumber(ohlcv, 2), this.safeNumber(ohlcv, 3), this.safeNumber(ohlcv, 4), this.safeNumber(ohlcv, 5), ]; } /** * @method * @name aster#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#k-line-data * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#klinecandlestick-data * @param {string} symbol unified symbol of the market to fetch OHLCV data for * @param {string} timeframe the length of time each candle represents * @param {int} [since] timestamp in ms of the earliest candle to fetch * @param {int} [limit] the maximum amount of candles to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.price] "mark" or "index" for mark price and index price candles * @param {int} [params.until] the latest time in ms to fetch orders for * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) { if (symbol === undefined) { throw new ArgumentsRequired(this.id + ' fetchOHLCV() requires a symbol argument'); } await this.loadMarkets(); const market = this.market(symbol); let request = {}; if (since !== undefined) { request['startTime'] = since; } if (limit !== undefined) { if (limit > 1500) { limit = 1500; // Default 500; max 1500. } request['limit'] = limit; } [request, params] = this.handleUntilOption('endTime', request, params); request['interval'] = this.safeString(this.timeframes, timeframe, timeframe); const price = this.safeString(params, 'price'); const isMark = (price === 'mark'); const isIndex = (price === 'index'); params = this.omit(params, 'price'); let response = undefined; if (isMark) { request['symbol'] = market['id']; response = await this.fapiPublicGetV1MarkPriceKlines(this.extend(request, params)); } else if (isIndex) { request['pair'] = market['id']; response = await this.fapiPublicGetV1IndexPriceKlines(this.extend(request, params)); } else { request['symbol'] = market['id']; if (market['linear']) { response = await this.fapiPublicGetV1Klines(this.extend(request, params)); } else { response = await this.sapiPublicGetV1Klines(this.extend(request, params)); } } // // [ // [ // 1631158560000, // "208.1850", // "208.1850", // "208.1850", // "208.1850", // "11.84", // 1631158619999, // "2464.910400", // 1, // "11.84", // "2464.910400", // "0" // ] // ] // return this.parseOHLCVs(response, market, timeframe, since, limit); } parseTrade(trade, market = undefined) { // // fetchTrades // // { // "id": 3913206, // "price": "644.100", // "qty": "0.08", // "quoteQty": "51.528", // "time": 1749784506633, // "isBuyerMaker": true // } // // { // "id": 657, // "price": "1.01000000", // "qty": "5.00000000", // "baseQty": "4.95049505", // "time": 1755156533943, // "isBuyerMaker": false // } // // fetchMyTrades // // { // "buyer": false, // "commission": "-0.07819010", // "commissionAsset": "USDT", // "id": 698759, // "maker": false, // "orderId": 25851813, // "price": "7819.01", // "qty": "0.002", // "quoteQty": "15.63802", // "realizedPnl": "-0.91539999", // "side": "SELL", // "positionSide": "SHORT", // "symbol": "BTCUSDT", // "time": 1569514978020 // } // const id = this.safeString(trade, 'id'); const symbol = market['symbol']; const currencyId = this.safeString(trade, 'commissionAsset'); const currencyCode = this.safeCurrencyCode(currencyId); const amountString = this.safeString(trade, 'qty'); const priceString = this.safeString(trade, 'price'); const costString = this.safeString2(trade, 'quoteQty', 'baseQty'); const timestamp = this.safeInteger(trade, 'time'); let side = this.safeStringLower(trade, 'side'); const isMaker = this.safeBool(trade, 'maker'); let takerOrMaker = undefined; if (isMaker !== undefined) { takerOrMaker = isMaker ? 'maker' : 'taker'; } const isBuyerMaker = this.safeBool(trade, 'isBuyerMaker'); if (isBuyerMaker !== undefined) { side = isBuyerMaker ? 'sell' : 'buy'; } return this.safeTrade({ 'id': id, 'info': trade, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'symbol': symbol, 'order': this.safeString(trade, 'orderId'), 'type': undefined, 'side': side, 'takerOrMaker': takerOrMaker, 'price': priceString, 'amount': amountString, 'cost': costString, 'fee': { 'cost': this.parseNumber(Precise.stringAbs(this.safeString(trade, 'commission'))), 'currency': currencyCode, }, }, market); } /** * @method * @name aster#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#recent-trades-list * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#recent-trades-list * @param {string} symbol unified symbol of the market to fetch trades for * @param {int} [since] timestamp in ms of the earliest trade to fetch * @param {int} [limit] the maximum amount of trades to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades} */ async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) { if (symbol === undefined) { throw new ArgumentsRequired(this.id + ' fetchTrades() requires a symbol argument'); } await this.loadMarkets(); const market = this.market(symbol); const request = { 'symbol': market['id'], }; if (limit !== undefined) { if (limit > 1000) { limit = 1000; // Default 500; max 1000. } request['limit'] = limit; } let response = undefined; if (market['swap']) { response = await this.fapiPublicGetV1Trades(this.extend(request, params)); // // [ // { // "id": 3913206, // "price": "644.100", // "qty": "0.08", // "quoteQty": "51.528", // "time": 1749784506633, // "isBuyerMaker": true // } // ] // } else { response = await this.sapiPublicGetV1Trades(this.extend(request, params)); // [ // { // "id": 657, // "price": "1.01000000", // "qty": "5.00000000", // "baseQty": "4.95049505", // "time": 1755156533943, // "isBuyerMaker": false // } // ] } return this.parseTrades(response, market, since, limit); } /** * @method * @name aster#fetchMyTrades * @description fetch all trades made by the user * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#account-trade-history-user_data * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#account-trade-list-user_data * @param {string} [symbol] unified market symbol * @param {int} [since] the earliest time in ms to fetch trades for * @param {int} [limit] the maximum number of trades structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms for the ending date filter, default is undefined * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) { if (symbol === undefined) { throw new ArgumentsRequired(this.id + ' fetchMyTrades() requires a symbol argument'); } await this.loadMarkets(); const market = this.market(symbol); let request = { 'symbol': market['id'], }; if (since !== undefined) { request['startTime'] = since; } if (limit !== undefined) { if (limit > 1000) { limit = 1000; // Default 500; max 1000. } request['limit'] = limit; } [request, params] = this.handleUntilOption('endTime', request, params); let response = undefined; if (market['swap']) { response = await this.fapiPrivateGetV1UserTrades(this.extend(request, params)); } else { response = await this.sapiPrivateGetV1UserTrades(this.extend(request, params)); } // // [ // { // "buyer": false, // "commission": "-0.07819010", // "commissionAsset": "USDT", // "id": 698759, // "maker": false, // "orderId": 25851813, // "price": "7819.01", // "qty": "0.002", // "quoteQty": "15.63802", // "realizedPnl": "-0.91539999", // "side": "SELL", // "positionSide": "SHORT", // "symbol": "BTCUSDT", // "time": 1569514978020 // } // ] // return this.parseTrades(response, market, since, limit, params); } /** * @method * @name aster#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#depth-information * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#order-book * @param {string} symbol unified symbol of the market to fetch the order book for * @param {int} [limit] the maximum amount of order book entries to return * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols */ async fetchOrderBook(symbol, limit = undefined, params = {}) { if (symbol === undefined) { throw new ArgumentsRequired(this.id + ' fetchOrderBook() requires a symbol argument'); } await this.loadMarkets(); const market = this.market(symbol); const request = { 'symbol': market['id'], }; if (limit !== undefined) { // limit: [5, 10, 20, 50, 100, 500, 1000]. Default: 500 if (limit > 1000) { limit = 1000; // Default 500; max 1000. } request['limit'] = limit; } let response = undefined; if (market['swap']) { response = await this.fapiPublicGetV1Depth(this.extend(request, params)); } else { response = await this.sapiPublicGetV1Depth(this.extend(request, para