ccxt
Version:
1,031 lines (1,028 loc) • 93.5 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var aster$1 = require('../aster.js');
var Precise = require('../base/Precise.js');
var errors = require('../base/errors.js');
var Cache = require('../base/ws/Cache.js');
// ----------------------------------------------------------------------------
// ---------------------------------------------------------------------------
class aster extends aster$1["default"] {
describe() {
return this.deepExtend(super.describe(), {
'has': {
'ws': true,
'watchBalance': true,
'watchBidsAsks': true,
'watchMarkPrice': true,
'watchMarkPrices': true,
'watchTrades': true,
'watchTradesForSymbols': true,
'watchOrders': true,
'watchOrderBook': true,
'watchOrderBookForSymbols': true,
'watchOHLCV': true,
'watchOHLCVForSymbols': true,
'watchPositions': true,
'watchTicker': true,
'watchTickers': true,
'watchMyTrades': 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': {
'public': {
'spot': 'wss://sstream.asterdex.com/stream',
'swap': 'wss://fstream.asterdex.com/stream',
},
'private': {
'spot': 'wss://sstream.asterdex.com/ws',
'swap': 'wss://fstream.asterdex.com/ws',
},
},
},
},
'options': {
'listenKey': {
'spot': undefined,
'swap': undefined,
},
'lastAuthenticatedTime': {
'spot': 0,
'swap': 0,
},
'listenKeyRefreshRate': {
'spot': 3600000,
'swap': 3600000,
},
'watchBalance': {
'fetchBalanceSnapshot': false,
'awaitBalanceSnapshot': true, // whether to wait for the balance snapshot before providing updates
},
'wallet': 'wb',
'watchPositions': {
'fetchPositionsSnapshot': true,
'awaitPositionsSnapshot': true, // whether to wait for the positions snapshot before providing updates
},
},
'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 errors.ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols');
}
const url = this.urls['api']['ws']['public'][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 errors.ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols');
}
const url = this.urls['api']['ws']['public'][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 errors.ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols');
}
const url = this.urls['api']['ws']['public'][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 errors.ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols');
}
const url = this.urls['api']['ws']['public'][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 errors.ArgumentsRequired(this.id + ' watchBidsAsks() requires a non-empty array of symbols');
}
const url = this.urls['api']['ws']['public'][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 errors.ArgumentsRequired(this.id + ' unWatchBidsAsks() requires a non-empty array of symbols');
}
const url = this.urls['api']['ws']['public'][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 errors.ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols');
}
const url = this.urls['api']['ws']['public'][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 errors.ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols');
}
const url = this.urls['api']['ws']['public'][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 Cache.ArrayCache(limit);
this.trades[symbol] = stored;
}
stored.append(parsed);
const messageHash = 'trade' + ':' + symbol;
client.resolve(stored, messageHash);
}
parseWsTrade(trade, market = undefined) {
//
// public watchTrades
//
// {
// "e": "trade", // event type
// "E": 1579481530911, // event time
// "s": "ETHBTC", // symbol
// "t": 158410082, // trade id
// "p": "0.01914100", // price
// "q": "0.00700000", // quantity
// "b": 586187049, // buyer order id
// "a": 586186710, // seller order id
// "T": 1579481530910, // trade time
// "m": false, // is the buyer the market maker
// "M": true // binance docs say it should be ignored
// }
//
// {
// "e": "aggTrade", // Event type
// "E": 123456789, // Event time
// "s": "BNBBTC", // Symbol
// "a": 12345, // Aggregate trade ID
// "p": "0.001", // Price
// "q": "100", // Quantity
// "f": 100, // First trade ID
// "l": 105, // Last trade ID
// "T": 123456785, // Trade time
// "m": true, // Is the buyer the market maker?
// "M": true // Ignore
// }
//
// private watchMyTrades spot
//
// {
// "e": "executionReport",
// "E": 1611063861489,
// "s": "BNBUSDT",
// "c": "m4M6AD5MF3b1ERe65l4SPq",
// "S": "BUY",
// "o": "MARKET",
// "f": "GTC",
// "q": "2.00000000",
// "p": "0.00000000",
// "P": "0.00000000",
// "F": "0.00000000",
// "g": -1,
// "C": '',
// "x": "TRADE",
// "X": "PARTIALLY_FILLED",
// "r": "NONE",
// "i": 1296882607,
// "l": "0.33200000",
// "z": "0.33200000",
// "L": "46.86600000",
// "n": "0.00033200",
// "N": "BNB",
// "T": 1611063861488,
// "t": 109747654,
// "I": 2696953381,
// "w": false,
// "m": false,
// "M": true,
// "O": 1611063861488,
// "Z": "15.55951200",
// "Y": "15.55951200",
// "Q": "0.00000000"
// }
//
// private watchMyTrades future/delivery
//
// {
// "s": "BTCUSDT",
// "c": "pb2jD6ZQHpfzSdUac8VqMK",
// "S": "SELL",
// "o": "MARKET",
// "f": "GTC",
// "q": "0.001",
// "p": "0",
// "ap": "33468.46000",
// "sp": "0",
// "x": "TRADE",
// "X": "FILLED",
// "i": 13351197194,
// "l": "0.001",
// "z": "0.001",
// "L": "33468.46",
// "n": "0.00027086",
// "N": "BNB",
// "T": 1612095165362,
// "t": 458032604,
// "b": "0",
// "a": "0",
// "m": false,
// "R": false,
// "wt": "CONTRACT_PRICE",
// "ot": "MARKET",
// "ps": "BOTH",
// "cp": false,
// "rp": "0.00335000",
// "pP": false,
// "si": 0,
// "ss": 0
// }
//
const id = this.safeString2(trade, 't', 'a');
const timestamp = this.safeInteger(trade, 'T');
const price = this.safeString2(trade, 'L', 'p');
const amount = this.safeString2(trade, 'q', 'l');
let cost = this.safeString(trade, 'Y');
if (cost === undefined) {
if ((price !== undefined) && (amount !== undefined)) {
cost = Precise["default"].stringMul(price, amount);
}
}
const marketId = this.safeString(trade, 's');
const defaultType = (market === undefined) ? this.safeString(this.options, 'defaultType', 'spot') : market['type'];
const symbol = this.safeSymbol(marketId, market, undefined, defaultType);
let side = this.safeStringLower(trade, 'S');
let takerOrMaker = undefined;
const orderId = this.safeString(trade, 'i');
if ('m' in trade) {
if (side === undefined) {
side = trade['m'] ? 'sell' : 'buy'; // this is reversed intentionally
}
takerOrMaker = trade['m'] ? 'maker' : 'taker';
}
let fee = undefined;
const feeCost = this.safeString(trade, 'n');
if (feeCost !== undefined) {
const feeCurrencyId = this.safeString(trade, 'N');
const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
fee = {
'cost': feeCost,
'currency': feeCurrencyCode,
};
}
const type = this.safeStringLower(trade, 'o');
return this.safeTrade({
'info': trade,
'timestamp': timestamp,
'datetime': this.iso8601(timestamp),
'symbol': symbol,
'id': id,
'order': orderId,
'type': type,
'takerOrMaker': takerOrMaker,
'side': side,
'price': price,
'amount': amount,
'cost': cost,
'fee': fee,
});
}
/**
* @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 errors.ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols');
}
const url = this.urls['api']['ws']['public'][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.toString());
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 errors.ArgumentsRequired(this.id + ' ' + methodName + '() requires a non-empty array of symbols');
}
const url = this.urls['api']['ws']['public'][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 OHL