UNPKG

ccxt

Version:

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

983 lines (980 loc) • 52.6 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 asterRest from '../aster.js'; import { ArgumentsRequired } from '../base/errors.js'; import { ArrayCache, ArrayCacheByTimestamp } from '../base/ws/Cache.js'; // --------------------------------------------------------------------------- export default class aster extends asterRest { describe() { return this.deepExtend(super.describe(), { 'has': { 'ws': true, 'watchBalance': false, 'watchBidsAsks': true, 'watchTicker': true, 'watchTickers': true, 'watchMarkPrice': true, 'watchMarkPrices': true, 'watchTrades': true, 'watchTradesForSymbols': true, 'watchOrderBook': true, 'watchOrderBookForSymbols': true, 'watchOHLCV': true, 'watchOHLCVForSymbols': true, 'unWatchTicker': true, 'unWatchTickers': true, 'unWatchMarkPrice': true, 'unWatchMarkPrices': true, 'unWatchBidsAsks': true, 'unWatchTrades': true, 'unWatchTradesForSymbols': true, 'unWatchOrderBook': true, 'unWatchOrderBookForSymbols': true, 'unWatchOHLCV': true, 'unWatchOHLCVForSymbols': true, }, 'urls': { 'api': { 'ws': { 'spot': 'wss://sstream.asterdex.com/stream', 'swap': 'wss://fstream.asterdex.com/stream', }, }, }, 'options': {}, 'streaming': {}, 'exceptions': {}, }); } getAccountTypeFromSubscriptions(subscriptions) { let accountType = ''; for (let i = 0; i < subscriptions.length; i++) { const subscription = subscriptions[i]; if ((subscription === 'spot') || (subscription === 'swap')) { accountType = subscription; break; } } return accountType; } /** * @method * @name aster#watchTicker * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#full-ticker-per-symbol * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#individual-symbol-ticker-streams * @param {string} symbol unified symbol of the market to fetch the ticker for * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ async watchTicker(symbol, params = {}) { params['callerMethodName'] = 'watchTicker'; await this.loadMarkets(); symbol = this.safeSymbol(symbol); const tickers = await this.watchTickers([symbol], params); return tickers[symbol]; } /** * @method * @name aster#unWatchTicker * @description unWatches a price ticker * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#full-ticker-per-symbol * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#individual-symbol-ticker-streams * @param {string} symbol unified symbol of the market to fetch the ticker for * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ async unWatchTicker(symbol, params = {}) { params['callerMethodName'] = 'unWatchTicker'; return await this.unWatchTickers([symbol], params); } /** * @method * @name aster#watchTickers * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#full-ticker-per-symbol * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#individual-symbol-ticker-streams * @param {string[]} symbols unified symbol of the market to fetch the ticker for * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ async watchTickers(symbols = undefined, params = {}) { await this.loadMarkets(); symbols = this.marketSymbols(symbols, undefined, true, true, true); const firstMarket = this.getMarketFromSymbols(symbols); const type = this.safeString(firstMarket, 'type', 'swap'); const symbolsLength = symbols.length; let methodName = undefined; [methodName, params] = this.handleParamString(params, 'callerMethodName', 'watchTickers'); params = this.omit(params, 'callerMethodName'); if (symbolsLength === 0) { throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols'); } const url = this.urls['api']['ws'][type]; const subscriptionArgs = []; const messageHashes = []; const request = { 'method': 'SUBSCRIBE', 'params': subscriptionArgs, }; for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; const market = this.market(symbol); subscriptionArgs.push(this.safeStringLower(market, 'id') + '@ticker'); messageHashes.push('ticker:' + market['symbol']); } const newTicker = await this.watchMultiple(url, messageHashes, this.extend(request, params), [type]); if (this.newUpdates) { const result = {}; result[newTicker['symbol']] = newTicker; return result; } return this.filterByArray(this.tickers, 'symbol', symbols); } /** * @method * @name aster#unWatchTickers * @description unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#full-ticker-per-symbol * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#individual-symbol-ticker-streams * @param {string[]} symbols unified symbol of the market to fetch the ticker for * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ async unWatchTickers(symbols = undefined, params = {}) { await this.loadMarkets(); symbols = this.marketSymbols(symbols, undefined, true, true, true); const firstMarket = this.getMarketFromSymbols(symbols); const type = this.safeString(firstMarket, 'type', 'swap'); const symbolsLength = symbols.length; let methodName = undefined; [methodName, params] = this.handleParamString(params, 'callerMethodName', 'unWatchTickers'); params = this.omit(params, 'callerMethodName'); if (symbolsLength === 0) { throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols'); } const url = this.urls['api']['ws'][type]; const subscriptionArgs = []; const messageHashes = []; const request = { 'method': 'UNSUBSCRIBE', 'params': subscriptionArgs, }; for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; const market = this.market(symbol); subscriptionArgs.push(this.safeStringLower(market, 'id') + '@ticker'); messageHashes.push('unsubscribe:ticker:' + market['symbol']); } return await this.watchMultiple(url, messageHashes, this.extend(request, params), [type]); } /** * @method * @name aster#watchMarkPrice * @description watches a mark price for a specific market * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#mark-price-stream * @param {string} symbol unified symbol of the market to fetch the ticker for * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.use1sFreq] *default is true* if set to true, the mark price will be updated every second, otherwise every 3 seconds * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ async watchMarkPrice(symbol, params = {}) { params['callerMethodName'] = 'watchMarkPrice'; await this.loadMarkets(); symbol = this.safeSymbol(symbol); const tickers = await this.watchMarkPrices([symbol], params); return tickers[symbol]; } /** * @method * @name aster#unWatchMarkPrice * @description unWatches a mark price for a specific market * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#mark-price-stream * @param {string} symbol unified symbol of the market to fetch the ticker for * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.use1sFreq] *default is true* if set to true, the mark price will be updated every second, otherwise every 3 seconds * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ async unWatchMarkPrice(symbol, params = {}) { params['callerMethodName'] = 'unWatchMarkPrice'; return await this.unWatchMarkPrices([symbol], params); } /** * @method * @name aster#watchMarkPrices * @description watches the mark price for all markets * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#mark-price-stream * @param {string[]} symbols unified symbol of the market to fetch the ticker for * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.use1sFreq] *default is true* if set to true, the mark price will be updated every second, otherwise every 3 seconds * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ async watchMarkPrices(symbols = undefined, params = {}) { await this.loadMarkets(); symbols = this.marketSymbols(symbols, undefined, true, true, true); const firstMarket = this.getMarketFromSymbols(symbols); const type = this.safeString(firstMarket, 'type', 'swap'); const symbolsLength = symbols.length; let methodName = undefined; [methodName, params] = this.handleParamString(params, 'callerMethodName', 'watchMarkPrices'); params = this.omit(params, 'callerMethodName'); if (symbolsLength === 0) { throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols'); } const url = this.urls['api']['ws'][type]; const subscriptionArgs = []; const messageHashes = []; const request = { 'method': 'SUBSCRIBE', 'params': subscriptionArgs, }; const use1sFreq = this.safeBool(params, 'use1sFreq', true); for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; const market = this.market(symbol); const suffix = (use1sFreq) ? '@1s' : ''; subscriptionArgs.push(this.safeStringLower(market, 'id') + '@markPrice' + suffix); messageHashes.push('ticker:' + market['symbol']); } const newTicker = await this.watchMultiple(url, messageHashes, this.extend(request, params), [type]); if (this.newUpdates) { const result = {}; result[newTicker['symbol']] = newTicker; return result; } return this.filterByArray(this.tickers, 'symbol', symbols); } /** * @method * @name aster#unWatchMarkPrices * @description watches the mark price for all markets * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#mark-price-stream * @param {string[]} symbols unified symbol of the market to fetch the ticker for * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.use1sFreq] *default is true* if set to true, the mark price will be updated every second, otherwise every 3 seconds * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ async unWatchMarkPrices(symbols = undefined, params = {}) { await this.loadMarkets(); symbols = this.marketSymbols(symbols, undefined, true, true, true); const firstMarket = this.getMarketFromSymbols(symbols); const type = this.safeString(firstMarket, 'type', 'swap'); const symbolsLength = symbols.length; let methodName = undefined; [methodName, params] = this.handleParamString(params, 'callerMethodName', 'unWatchMarkPrices'); params = this.omit(params, 'callerMethodName'); if (symbolsLength === 0) { throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols'); } const url = this.urls['api']['ws'][type]; const subscriptionArgs = []; const messageHashes = []; const request = { 'method': 'UNSUBSCRIBE', 'params': subscriptionArgs, }; const use1sFreq = this.safeBool(params, 'use1sFreq', true); for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; const market = this.market(symbol); const suffix = (use1sFreq) ? '@1s' : ''; subscriptionArgs.push(this.safeStringLower(market, 'id') + '@markPrice' + suffix); messageHashes.push('unsubscribe:ticker:' + market['symbol']); } return await this.watchMultiple(url, messageHashes, this.extend(request, params), [type]); } handleTicker(client, message) { // // { // "stream": "trumpusdt@ticker", // "data": { // "e": "24hrTicker", // "E": 1754451187277, // "s": "CAKEUSDT", // "p": "-0.08800", // "P": "-3.361", // "w": "2.58095", // "c": "2.53000", // "Q": "5", // "o": "2.61800", // "h": "2.64700", // "l": "2.52400", // "v": "15775", // "q": "40714.46000", // "O": 1754364780000, // "C": 1754451187274, // "F": 6571389, // "L": 6574507, // "n": 3119 // } // } // { // "stream": "btcusdt@markPrice", // "data": { // "e": "markPriceUpdate", // "E": 1754660466000, // "s": "BTCUSDT", // "p": "116809.60000000", // "P": "116595.54012838", // "i": "116836.93534884", // "r": "0.00010000", // "T": 1754668800000 // } // } // const subscriptions = client.subscriptions; const subscriptionsKeys = Object.keys(subscriptions); const marketType = this.getAccountTypeFromSubscriptions(subscriptionsKeys); const ticker = this.safeDict(message, 'data'); const parsed = this.parseWsTicker(ticker, marketType); const symbol = parsed['symbol']; const messageHash = 'ticker:' + symbol; this.tickers[symbol] = parsed; client.resolve(this.tickers[symbol], messageHash); } parseWsTicker(message, marketType) { const event = this.safeString(message, 'e'); const part = event.split('@'); const channel = this.safeString(part, 1); const marketId = this.safeString(message, 's'); const timestamp = this.safeInteger(message, 'E'); const market = this.safeMarket(marketId, undefined, undefined, marketType); const last = this.safeString(message, 'c'); if (channel === 'markPriceUpdate') { return this.safeTicker({ 'symbol': market['symbol'], 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'info': message, 'markPrice': this.safeString(message, 'p'), 'indexPrice': this.safeString(message, 'i'), }); } return this.safeTicker({ 'symbol': market['symbol'], 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'high': this.safeString(message, 'h'), 'low': this.safeString(message, 'l'), 'bid': undefined, 'bidVolume': undefined, 'ask': undefined, 'askVolume': undefined, 'vwap': this.safeString(message, 'w'), 'open': this.safeString(message, 'o'), 'close': last, 'last': last, 'previousClose': undefined, 'change': this.safeString(message, 'p'), 'percentage': this.safeString(message, 'P'), 'average': undefined, 'baseVolume': this.safeString(message, 'v'), 'quoteVolume': this.safeString(message, 'q'), 'info': message, }, market); } /** * @method * @name aster#watchBidsAsks * @description watches best bid & ask for symbols * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#best-order-book-information-by-symbol * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#individual-symbol-book-ticker-streams * @param {string[]} symbols unified symbol of the market to fetch the ticker for * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ async watchBidsAsks(symbols = undefined, params = {}) { await this.loadMarkets(); symbols = this.marketSymbols(symbols, undefined, true, true, true); const firstMarket = this.getMarketFromSymbols(symbols); const type = this.safeString(firstMarket, 'type', 'swap'); const symbolsLength = symbols.length; if (symbolsLength === 0) { throw new ArgumentsRequired(this.id + ' watchBidsAsks() requires a non-empty array of symbols'); } const url = this.urls['api']['ws'][type]; const subscriptionArgs = []; const messageHashes = []; const request = { 'method': 'SUBSCRIBE', 'params': subscriptionArgs, }; for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; const market = this.market(symbol); subscriptionArgs.push(this.safeStringLower(market, 'id') + '@bookTicker'); messageHashes.push('bidask:' + market['symbol']); } const newTicker = await this.watchMultiple(url, messageHashes, this.extend(request, params), [type]); if (this.newUpdates) { const result = {}; result[newTicker['symbol']] = newTicker; return result; } return this.filterByArray(this.bidsasks, 'symbol', symbols); } /** * @method * @name aster#unWatchBidsAsks * @description unWatches best bid & ask for symbols * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#best-order-book-information-by-symbol * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#individual-symbol-book-ticker-streams * @param {string[]} symbols unified symbol of the market to fetch the ticker for * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ async unWatchBidsAsks(symbols = undefined, params = {}) { await this.loadMarkets(); symbols = this.marketSymbols(symbols, undefined, true, true, true); const firstMarket = this.getMarketFromSymbols(symbols); const type = this.safeString(firstMarket, 'type', 'swap'); const symbolsLength = symbols.length; if (symbolsLength === 0) { throw new ArgumentsRequired(this.id + ' unWatchBidsAsks() requires a non-empty array of symbols'); } const url = this.urls['api']['ws'][type]; const subscriptionArgs = []; const messageHashes = []; const request = { 'method': 'UNSUBSCRIBE', 'params': subscriptionArgs, }; for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; const market = this.market(symbol); subscriptionArgs.push(this.safeStringLower(market, 'id') + '@bookTicker'); messageHashes.push('unsubscribe:bidask:' + market['symbol']); } return await this.watchMultiple(url, messageHashes, this.extend(request, params), [type]); } handleBidAsk(client, message) { // // { // "stream": "btcusdt@bookTicker", // "data": { // "e": "bookTicker", // "u": 157240846459, // "s": "BTCUSDT", // "b": "122046.7", // "B": "1.084", // "a": "122046.8", // "A": "0.001", // "T": 1754896692922, // "E": 1754896692926 // } // } // const subscriptions = client.subscriptions; const subscriptionsKeys = Object.keys(subscriptions); const marketType = this.getAccountTypeFromSubscriptions(subscriptionsKeys); const data = this.safeDict(message, 'data', {}); const marketId = this.safeString(data, 's'); const market = this.safeMarket(marketId, undefined, undefined, marketType); const ticker = this.parseWsBidAsk(data, market); const symbol = ticker['symbol']; this.bidsasks[symbol] = ticker; const messageHash = 'bidask:' + symbol; client.resolve(ticker, messageHash); } parseWsBidAsk(message, market = undefined) { const timestamp = this.safeInteger(message, 'T'); return this.safeTicker({ 'symbol': market['symbol'], 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'ask': this.safeString(message, 'a'), 'askVolume': this.safeString(message, 'A'), 'bid': this.safeString(message, 'b'), 'bidVolume': this.safeString(message, 'B'), 'info': message, }, market); } /** * @method * @name aster#watchTrades * @description watches information on multiple trades made in a market * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#collection-transaction-flow * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#aggregate-trade-streams * @param {string} symbol unified market symbol of the market trades were made in * @param {int} [since] the earliest time in ms to fetch trades for * @param {int} [limit] the maximum number of trade structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ async watchTrades(symbol, since = undefined, limit = undefined, params = {}) { params['callerMethodName'] = 'watchTrades'; return await this.watchTradesForSymbols([symbol], since, limit, params); } /** * @method * @name aster#unWatchTrades * @description unsubscribe from the trades channel * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#collection-transaction-flow * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#aggregate-trade-streams * @param {string} symbol unified market symbol of the market trades were made in * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ async unWatchTrades(symbol, params = {}) { params['callerMethodName'] = 'unWatchTrades'; return await this.unWatchTradesForSymbols([symbol], params); } /** * @method * @name aster#watchTradesForSymbols * @description get the list of most recent trades for a list of symbols * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#collection-transaction-flow * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#aggregate-trade-streams * @param {string[]} symbols 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 {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades} */ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) { await this.loadMarkets(); symbols = this.marketSymbols(symbols, undefined, true, true, true); const firstMarket = this.getMarketFromSymbols(symbols); const type = this.safeString(firstMarket, 'type', 'swap'); const symbolsLength = symbols.length; let methodName = undefined; [methodName, params] = this.handleParamString(params, 'callerMethodName', 'watchTradesForSymbols'); params = this.omit(params, 'callerMethodName'); if (symbolsLength === 0) { throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols'); } const url = this.urls['api']['ws'][type]; const subscriptionArgs = []; const messageHashes = []; const request = { 'method': 'SUBSCRIBE', 'params': subscriptionArgs, }; for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; const market = this.market(symbol); subscriptionArgs.push(this.safeStringLower(market, 'id') + '@aggTrade'); messageHashes.push('trade:' + market['symbol']); } const trades = await this.watchMultiple(url, messageHashes, this.extend(request, params), [type]); if (this.newUpdates) { const first = this.safeValue(trades, 0); const tradeSymbol = this.safeString(first, 'symbol'); limit = trades.getLimit(tradeSymbol, limit); } return this.filterBySinceLimit(trades, since, limit, 'timestamp', true); } /** * @method * @name aster#unWatchTradesForSymbols * @description unsubscribe from the trades channel * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#collection-transaction-flow * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#aggregate-trade-streams * @param {string[]} symbols unified symbol of the market to fetch trades for * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades} */ async unWatchTradesForSymbols(symbols, params = {}) { await this.loadMarkets(); symbols = this.marketSymbols(symbols, undefined, true, true, true); const firstMarket = this.getMarketFromSymbols(symbols); const type = this.safeString(firstMarket, 'type', 'swap'); const symbolsLength = symbols.length; let methodName = undefined; [methodName, params] = this.handleParamString(params, 'callerMethodName', 'unWatchTradesForSymbols'); params = this.omit(params, 'callerMethodName'); if (symbolsLength === 0) { throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols'); } const url = this.urls['api']['ws'][type]; const subscriptionArgs = []; const messageHashes = []; const request = { 'method': 'UNSUBSCRIBE', 'params': subscriptionArgs, }; for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; const market = this.market(symbol); subscriptionArgs.push(this.safeStringLower(market, 'id') + '@aggTrade'); messageHashes.push('unsubscribe:trade:' + market['symbol']); } return await this.watchMultiple(url, messageHashes, this.extend(request, params), [type]); } handleTrade(client, message) { // // { // "stream": "btcusdt@aggTrade", // "data": { // "e": "aggTrade", // "E": 1754551358681, // "a": 20505890, // "s": "BTCUSDT", // "p": "114783.7", // "q": "0.020", // "f": 26024678, // "l": 26024682, // "T": 1754551358528, // "m": false // } // } // const subscriptions = client.subscriptions; const subscriptionsKeys = Object.keys(subscriptions); const marketType = this.getAccountTypeFromSubscriptions(subscriptionsKeys); const trade = this.safeDict(message, 'data'); const marketId = this.safeString(trade, 's'); const market = this.safeMarket(marketId, undefined, undefined, marketType); const parsed = this.parseWsTrade(trade, market); const symbol = parsed['symbol']; let stored = this.safeValue(this.trades, symbol); if (stored === undefined) { const limit = this.safeInteger(this.options, 'tradesLimit', 1000); stored = new ArrayCache(limit); this.trades[symbol] = stored; } stored.append(parsed); const messageHash = 'trade' + ':' + symbol; client.resolve(stored, messageHash); } parseWsTrade(trade, market = undefined) { const timestamp = this.safeInteger(trade, 'T'); const symbol = market['symbol']; const amountString = this.safeString(trade, 'q'); const priceString = this.safeString(trade, 'p'); const isMaker = this.safeBool(trade, 'm'); let takerOrMaker = undefined; if (isMaker !== undefined) { takerOrMaker = isMaker ? 'maker' : 'taker'; } return this.safeTrade({ 'id': this.safeString(trade, 'a'), 'info': trade, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'symbol': symbol, 'order': undefined, 'type': undefined, 'side': undefined, 'takerOrMaker': takerOrMaker, 'price': priceString, 'amount': amountString, 'cost': undefined, 'fee': undefined, }, market); } /** * @method * @name aster#watchOrderBook * @description watches 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#limited-depth-information * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#partial-book-depth-streams * @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 watchOrderBook(symbol, limit = undefined, params = {}) { params['callerMethodName'] = 'watchOrderBook'; return await this.watchOrderBookForSymbols([symbol], limit, params); } /** * @method * @name aster#unWatchOrderBook * @description unsubscribe from the orderbook channel * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#limited-depth-information * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#partial-book-depth-streams * @param {string} symbol symbol of the market to unwatch the trades for * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.limit] orderbook limit, default is undefined * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols */ async unWatchOrderBook(symbol, params = {}) { params['callerMethodName'] = 'unWatchOrderBook'; return await this.unWatchOrderBookForSymbols([symbol], params); } /** * @method * @name aster#watchOrderBookForSymbols * @description watches 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#limited-depth-information * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#partial-book-depth-streams * @param {string[]} symbols unified array of symbols * @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 watchOrderBookForSymbols(symbols, limit = undefined, params = {}) { await this.loadMarkets(); symbols = this.marketSymbols(symbols, undefined, true, true, true); const firstMarket = this.getMarketFromSymbols(symbols); const type = this.safeString(firstMarket, 'type', 'swap'); const symbolsLength = symbols.length; let methodName = undefined; [methodName, params] = this.handleParamString(params, 'callerMethodName', 'watchOrderBookForSymbols'); params = this.omit(params, 'callerMethodName'); if (symbolsLength === 0) { throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols'); } const url = this.urls['api']['ws'][type]; const subscriptionArgs = []; const messageHashes = []; const request = { 'method': 'SUBSCRIBE', 'params': subscriptionArgs, }; if (limit === undefined || (limit !== 5 && limit !== 10 && limit !== 20)) { limit = 20; } for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; const market = this.market(symbol); subscriptionArgs.push(this.safeStringLower(market, 'id') + '@depth' + limit); messageHashes.push('orderbook:' + market['symbol']); } const orderbook = await this.watchMultiple(url, messageHashes, this.extend(request, params), [type]); return orderbook.limit(); } /** * @method * @name aster#unWatchOrderBookForSymbols * @description unsubscribe from the orderbook channel * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api.md#limited-depth-information * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#partial-book-depth-streams * @param {string[]} symbols unified symbol of the market to unwatch the trades for * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.limit] orderbook limit, default is undefined * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols */ async unWatchOrderBookForSymbols(symbols, params = {}) { await this.loadMarkets(); symbols = this.marketSymbols(symbols, undefined, true, true, true); const firstMarket = this.getMarketFromSymbols(symbols); const type = this.safeString(firstMarket, 'type', 'swap'); const symbolsLength = symbols.length; let methodName = undefined; [methodName, params] = this.handleParamString(params, 'callerMethodName', 'unWatchOrderBookForSymbols'); params = this.omit(params, 'callerMethodName'); if (symbolsLength === 0) { throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols'); } const url = this.urls['api']['ws'][type]; const subscriptionArgs = []; const messageHashes = []; const request = { 'method': 'UNSUBSCRIBE', 'params': subscriptionArgs, }; let limit = this.safeNumber(params, 'limit'); params = this.omit(params, 'limit'); if (limit === undefined || (limit !== 5 && limit !== 10 && limit !== 20)) { limit = 20; } for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; const market = this.market(symbol); subscriptionArgs.push(this.safeStringLower(market, 'id') + '@depth' + limit); messageHashes.push('unsubscribe:orderbook:' + market['symbol']); } return await this.watchMultiple(url, messageHashes, this.extend(request, params), [type]); } handleOrderBook(client, message) { // // { // "stream": "btcusdt@depth20", // "data": { // "e": "depthUpdate", // "E": 1754556878284, // "T": 1754556878031, // "s": "BTCUSDT", // "U": 156391349814, // "u": 156391349814, // "pu": 156391348236, // "b": [ // [ // "114988.3", // "0.147" // ] // ], // "a": [ // [ // "114988.4", // "1.060" // ] // ] // } // } // const subscriptions = client.subscriptions; const subscriptionsKeys = Object.keys(subscriptions); const marketType = this.getAccountTypeFromSubscriptions(subscriptionsKeys); const data = this.safeDict(message, 'data'); const marketId = this.safeString(data, 's'); const timestamp = this.safeInteger(data, 'T'); const market = this.safeMarket(marketId, undefined, undefined, marketType); const symbol = market['symbol']; if (!(symbol in this.orderbooks)) { this.orderbooks[symbol] = this.orderBook(); } const orderbook = this.orderbooks[symbol]; const snapshot = this.parseOrderBook(data, symbol, timestamp, 'b', 'a'); orderbook.reset(snapshot); const messageHash = 'orderbook' + ':' + symbol; this.orderbooks[symbol] = orderbook; client.resolve(orderbook, messageHash); } /** * @method * @name aster#watchOHLCV * @description watches 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-streams * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#klinecandlestick-streams * @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 * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) { params['callerMethodName'] = 'watchOHLCV'; await this.loadMarkets(); symbol = this.safeSymbol(symbol); const result = await this.watchOHLCVForSymbols([[symbol, timeframe]], since, limit, params); return result[symbol][timeframe]; } /** * @method * @name aster#unWatchOHLCV * @description unWatches 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-streams * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#klinecandlestick-streams * @param {string} symbol unified symbol of the market to fetch OHLCV data for * @param {string} timeframe the length of time each candle represents * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ async unWatchOHLCV(symbol, timeframe = '1m', params = {}) { params['callerMethodName'] = 'unWatchOHLCV'; return await this.unWatchOHLCVForSymbols([[symbol, timeframe]], params); } /** * @method * @name aster#watchOHLCVForSymbols * @description watches 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-streams * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#klinecandlestick-streams * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']] * @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 * @returns {object} A list of candles ordered as timestamp, open, high, low, close, volume */ async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) { await this.loadMarkets(); const symbolsLength = symbolsAndTimeframes.length; let methodName = undefined; [methodName, params] = this.handleParamString(params, 'callerMethodName', 'watchOHLCVForSymbols'); params = this.omit(params, 'callerMethodName'); if (symbolsLength === 0) { throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols'); } const symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0); const marketSymbols = this.marketSymbols(symbols, undefined, false, true, true); const firstMarket = this.market(marketSymbols[0]); const type = this.safeString(firstMarket, 'type', 'swap'); const url = this.urls['api']['ws'][type]; const subscriptionArgs = []; const messageHashes = []; const request = { 'method': 'SUBSCRIBE', 'params': subscriptionArgs, }; for (let i = 0; i < symbolsAndTimeframes.length; i++) { const data = symbolsAndTimeframes[i]; let symbolString = this.safeString(data, 0); const market = this.market(symbolString); symbolString = market['symbol']; const unfiedTimeframe = this.safeString(data, 1); const timeframeId = this.safeString(this.timeframes, unfiedTimeframe, unfiedTimeframe); subscriptionArgs.push(this.safeStringLower(market, 'id') + '@kline_' + timeframeId); messageHashes.push('ohlcv:' + market['symbol'] + ':' + unfiedTimeframe); } const [symbol, timeframe, stored] = await this.watchMultiple(url, messageHashes, this.extend(request, params), [type]); if (this.newUpdates) { limit = stored.getLimit(symbol, limit); } const filtered = this.filterBySinceLimit(stored, since, limit, 0, true); return this.createOHLCVObject(symbol, timeframe, filtered); } /** * @method * @name aster#unWatchOHLCVForSymbols * @description unWatches 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-streams * @see https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api.md#klinecandlestick-streams * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']] * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ async unWatchOHLCVForSymbols(symbolsAndTimeframes, params = {}) { await this.loadMarkets(); const symbolsLength = symbolsAndTimeframes.length; let methodName = undefined; [methodName, params] = this.handleParamString(params, 'callerMethodName', 'unWatchOHLCVForSymbols'); params = this.omit(params, 'callerMethodName'); if (symbolsLength === 0) { throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols'); } const symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0); const marketSymbols = this.marketSymbols(symbols, undefined, false, true, true); const firstMarket = this.market(marketSymbols[0]); const type = this.safeString(firstMarket, 'type', 'swap'); const url = this.urls['api']['ws'][type]; const subscriptionArgs = []; const messageHashes = []; const request = { 'method': 'UNSUBSCRIBE', 'params': subscriptionArgs, }; for (let i = 0; i < symbolsAndTimeframes.length; i++) { const data = symbolsAndTimeframes[i]; let symbolString = this.safeString(data, 0); const market = this.market(symbolString); symbolString = market['symbol']; const unfiedTimeframe = this.safeString(data, 1); const timeframeId = this.safeString(this.timeframes, unfiedTimeframe, unfiedTimeframe); subscriptionArgs.push(this.safeStringLower(market, 'id') + '@kline_' + timeframeId); messageHashes.push('unsubscribe:ohlcv:' + market['symbol'] + ':' + unfiedTimeframe); } return await this.watchMultiple(url, messageHashes, this.extend(request, params), [type]); } handleOHLCV(client, message) { // // { // "stream": "btcusdt@kline_1m", // "data": { // "e": "kline", // "E": 1754655777119, // "s": "BTCUSDT", // "k": { // "t": 1754655720000, // "T": 1754655779999, // "s": "BTCUSDT", // "i": "1m", // "f": 26032629, // "L": 26032629, // "o": "116546.9", // "c": "116546.9", // "h": "116546.9", // "l": "116546.9", // "v": "0.011", // "n": 1, // "x": false, // "q": "1282.0159", // "V": "0.000", // "Q": "0.0000", // "B": "0"