ccxt 4.5.63 → 4.5.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +6 -8
  2. package/dist/ccxt.browser.min.js +4 -4
  3. package/dist/cjs/ccxt.js +6 -12
  4. package/dist/cjs/src/aster.js +2 -2
  5. package/dist/cjs/src/base/Exchange.js +34 -3
  6. package/dist/cjs/src/bitget.js +5 -3
  7. package/dist/cjs/src/bitmex.js +1 -1
  8. package/dist/cjs/src/bitstamp.js +2 -1
  9. package/dist/cjs/src/bitvavo.js +1 -0
  10. package/dist/cjs/src/btcbox.js +1 -1
  11. package/dist/cjs/src/bullish.js +1 -1
  12. package/dist/cjs/src/bybiteu.js +3 -0
  13. package/dist/cjs/src/coinbase.js +3 -2
  14. package/dist/cjs/src/coinbaseinternational.js +1 -1
  15. package/dist/cjs/src/delta.js +23 -1
  16. package/dist/cjs/src/derive.js +1 -1
  17. package/dist/cjs/src/digifinex.js +12 -0
  18. package/dist/cjs/src/dydx.js +2 -2
  19. package/dist/cjs/src/extended.js +1 -1
  20. package/dist/cjs/src/gateeu.js +1 -0
  21. package/dist/cjs/src/grvt.js +1 -1
  22. package/dist/cjs/src/hashkey.js +127 -6
  23. package/dist/cjs/src/hibachi.js +20 -10
  24. package/dist/cjs/src/hyperliquid.js +1 -1
  25. package/dist/cjs/src/kraken.js +2 -0
  26. package/dist/cjs/src/kucoin.js +1 -1
  27. package/dist/cjs/src/kucoineu.js +3 -0
  28. package/dist/cjs/src/lighter.js +6 -4
  29. package/dist/cjs/src/mudrex.js +1328 -0
  30. package/dist/cjs/src/myokx.js +3 -0
  31. package/dist/cjs/src/okxus.js +1 -5
  32. package/dist/cjs/src/onetrading.js +1 -0
  33. package/dist/cjs/src/pacifica.js +1 -1
  34. package/dist/cjs/src/poloniex.js +1 -1
  35. package/dist/cjs/src/pro/bingx.js +4 -2
  36. package/dist/cjs/src/pro/bitget.js +9 -7
  37. package/dist/cjs/src/pro/grvt.js +1 -1
  38. package/dist/cjs/src/pro/hashkey.js +1 -1
  39. package/dist/cjs/src/pro/kraken.js +1 -1
  40. package/dist/cjs/src/pro/mudrex.js +226 -0
  41. package/dist/cjs/src/pro/okxus.js +1 -1
  42. package/js/ccxt.d.ts +8 -14
  43. package/js/ccxt.js +6 -10
  44. package/js/src/abstract/binance.d.ts +3 -0
  45. package/js/src/abstract/binancecoinm.d.ts +3 -0
  46. package/js/src/abstract/binanceus.d.ts +3 -0
  47. package/js/src/abstract/binanceusdm.d.ts +3 -0
  48. package/js/src/abstract/bybit.d.ts +39 -0
  49. package/js/src/abstract/bybiteu.d.ts +39 -0
  50. package/js/src/abstract/coincheck.d.ts +3 -0
  51. package/js/src/abstract/coinsph.d.ts +8 -1
  52. package/js/src/abstract/kucoineu.js +0 -6
  53. package/js/src/abstract/mudrex.d.ts +33 -0
  54. package/js/src/aster.js +2 -2
  55. package/js/src/base/Exchange.d.ts +10 -1
  56. package/js/src/base/Exchange.js +34 -3
  57. package/js/src/bitget.js +5 -3
  58. package/js/src/bitmex.js +1 -1
  59. package/js/src/bitstamp.js +2 -1
  60. package/js/src/bitvavo.js +1 -0
  61. package/js/src/btcbox.js +1 -1
  62. package/js/src/bullish.js +1 -1
  63. package/js/src/bybiteu.js +3 -0
  64. package/js/src/coinbase.js +3 -2
  65. package/js/src/coinbaseinternational.js +1 -1
  66. package/js/src/delta.d.ts +12 -0
  67. package/js/src/delta.js +23 -1
  68. package/js/src/derive.js +1 -1
  69. package/js/src/digifinex.d.ts +12 -0
  70. package/js/src/digifinex.js +12 -0
  71. package/js/src/dydx.d.ts +2 -2
  72. package/js/src/dydx.js +2 -2
  73. package/js/src/extended.js +1 -1
  74. package/js/src/gateeu.js +1 -0
  75. package/js/src/grvt.d.ts +1 -1
  76. package/js/src/grvt.js +1 -1
  77. package/js/src/hashkey.d.ts +40 -3
  78. package/js/src/hashkey.js +127 -6
  79. package/js/src/hibachi.d.ts +9 -5
  80. package/js/src/hibachi.js +20 -10
  81. package/js/src/hyperliquid.js +1 -1
  82. package/js/src/kraken.js +2 -0
  83. package/js/src/kucoin.js +1 -1
  84. package/js/src/kucoineu.js +3 -0
  85. package/js/src/lighter.js +6 -4
  86. package/js/src/mudrex.d.ts +310 -0
  87. package/js/src/mudrex.js +1321 -0
  88. package/js/src/myokx.js +3 -0
  89. package/js/src/okxus.js +1 -5
  90. package/js/src/onetrading.js +1 -0
  91. package/js/src/pacifica.js +1 -1
  92. package/js/src/poloniex.js +1 -1
  93. package/js/src/pro/bingx.js +4 -2
  94. package/js/src/pro/bitget.js +9 -7
  95. package/js/src/pro/grvt.d.ts +1 -1
  96. package/js/src/pro/grvt.js +1 -1
  97. package/js/src/pro/hashkey.d.ts +1 -1
  98. package/js/src/pro/hashkey.js +1 -1
  99. package/js/src/pro/kraken.js +1 -1
  100. package/js/src/pro/mudrex.d.ts +23 -0
  101. package/js/src/pro/mudrex.js +219 -0
  102. package/js/src/pro/okxus.js +1 -1
  103. package/package.json +3 -3
  104. package/dist/cjs/src/abstract/coinmetro.js +0 -11
  105. package/dist/cjs/src/abstract/novadax.js +0 -11
  106. package/dist/cjs/src/ascendex.js +0 -3780
  107. package/dist/cjs/src/coinmetro.js +0 -2030
  108. package/dist/cjs/src/novadax.js +0 -1678
  109. package/dist/cjs/src/pro/ascendex.js +0 -1013
  110. package/js/src/abstract/ascendex.d.ts +0 -80
  111. package/js/src/abstract/coinmetro.d.ts +0 -37
  112. package/js/src/abstract/coinmetro.js +0 -5
  113. package/js/src/abstract/novadax.d.ts +0 -32
  114. package/js/src/abstract/novadax.js +0 -5
  115. package/js/src/ascendex.d.ts +0 -436
  116. package/js/src/ascendex.js +0 -3773
  117. package/js/src/coinmetro.d.ts +0 -245
  118. package/js/src/coinmetro.js +0 -2023
  119. package/js/src/novadax.d.ts +0 -279
  120. package/js/src/novadax.js +0 -1671
  121. package/js/src/pro/ascendex.d.ts +0 -99
  122. package/js/src/pro/ascendex.js +0 -1006
  123. /package/dist/cjs/src/abstract/{ascendex.js → mudrex.js} +0 -0
  124. /package/js/src/abstract/{ascendex.js → mudrex.js} +0 -0
@@ -1,1006 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- import { sha256 } from '@noble/hashes/sha2.js';
3
- import ascendexRest from '../ascendex.js';
4
- import { AuthenticationError, NetworkError } from '../base/errors.js';
5
- import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById } from '../base/ws/Cache.js';
6
- // ---------------------------------------------------------------------------
7
- export default class ascendex extends ascendexRest {
8
- describe() {
9
- return this.deepExtend(super.describe(), {
10
- 'has': {
11
- 'ws': true,
12
- 'watchBalance': true,
13
- 'watchOHLCV': true,
14
- 'watchOrderBook': true,
15
- 'watchOrders': true,
16
- 'watchTicker': false,
17
- 'watchTrades': true,
18
- 'watchTradesForSymbols': true,
19
- },
20
- 'urls': {
21
- 'api': {
22
- 'ws': {
23
- 'public': 'wss://ascendex.com:443/api/pro/v2/stream',
24
- 'private': 'wss://ascendex.com:443/{accountGroup}/api/pro/v2/stream',
25
- },
26
- },
27
- 'test': {
28
- 'ws': {
29
- 'public': 'wss://api-test.ascendex-sandbox.com:443/api/pro/v2/stream',
30
- 'private': 'wss://api-test.ascendex-sandbox.com:443/{accountGroup}/api/pro/v2/stream',
31
- },
32
- },
33
- },
34
- 'options': {
35
- 'tradesLimit': 1000,
36
- 'ordersLimit': 1000,
37
- 'OHLCVLimit': 1000,
38
- 'categoriesAccount': {
39
- 'cash': 'spot',
40
- 'futures': 'swap',
41
- 'margin': 'margin',
42
- },
43
- },
44
- });
45
- }
46
- async watchPublic(messageHash, params = {}) {
47
- const url = this.urls['api']['ws']['public'];
48
- const id = this.nonce();
49
- const request = {
50
- 'id': id.toString(),
51
- 'op': 'sub',
52
- };
53
- const message = this.extend(request, params);
54
- return await this.watch(url, messageHash, message, messageHash);
55
- }
56
- async watchPublicMultiple(messageHashes, params = {}) {
57
- const url = this.urls['api']['ws']['public'];
58
- const id = this.nonce();
59
- const request = {
60
- 'id': id.toString(),
61
- 'op': 'sub',
62
- };
63
- const message = this.extend(request, params);
64
- return await this.watchMultiple(url, messageHashes, message, messageHashes);
65
- }
66
- async watchPrivate(channel, messageHash, params = {}) {
67
- await this.loadAccounts();
68
- const accountGroup = this.safeString(this.options, 'account-group');
69
- let url = this.urls['api']['ws']['private'];
70
- url = this.implodeParams(url, { 'accountGroup': accountGroup });
71
- const id = this.nonce();
72
- const request = {
73
- 'id': id.toString(),
74
- 'op': 'sub',
75
- 'ch': channel,
76
- };
77
- const message = this.extend(request, params);
78
- await this.authenticate(url, params);
79
- return await this.watch(url, messageHash, message, channel);
80
- }
81
- /**
82
- * @method
83
- * @name ascendex#watchOHLCV
84
- * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
85
- * @see https://ascendex.github.io/ascendex-pro-api/#channel-bar-data
86
- * @param {string} symbol unified symbol of the market to fetch OHLCV data for
87
- * @param {string} timeframe the length of time each candle represents
88
- * @param {int} [since] timestamp in ms of the earliest candle to fetch
89
- * @param {int} [limit] the maximum amount of candles to fetch
90
- * @param {object} [params] extra parameters specific to the exchange API endpoint
91
- * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
92
- */
93
- async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
94
- await this.loadMarkets();
95
- const market = this.market(symbol);
96
- symbol = market['symbol'];
97
- if ((limit === undefined) || (limit > 1440)) {
98
- limit = 100;
99
- }
100
- const interval = this.safeString(this.timeframes, timeframe, timeframe);
101
- const channel = 'bar' + ':' + interval + ':' + market['id'];
102
- params = {
103
- 'ch': channel,
104
- };
105
- const ohlcv = await this.watchPublic(channel, params);
106
- if (this.newUpdates) {
107
- limit = ohlcv.getLimit(symbol, limit);
108
- }
109
- return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
110
- }
111
- handleOHLCV(client, message) {
112
- //
113
- // {
114
- // "m": "bar",
115
- // "s": "ASD/USDT",
116
- // "data": {
117
- // "i": "1",
118
- // "ts": 1575398940000,
119
- // "o": "0.04993",
120
- // "c": "0.04970",
121
- // "h": "0.04993",
122
- // "l": "0.04970",
123
- // "v": "8052"
124
- // }
125
- // }
126
- //
127
- const marketId = this.safeString(message, 's');
128
- const symbol = this.safeSymbol(marketId);
129
- const channel = this.safeString(message, 'm');
130
- const data = this.safeValue(message, 'data', {});
131
- const interval = this.safeString(data, 'i');
132
- const messageHash = channel + ':' + interval + ':' + marketId;
133
- const timeframe = this.findTimeframe(interval);
134
- const market = this.market(symbol);
135
- const parsed = this.parseOHLCV(message, market);
136
- this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
137
- let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
138
- if (stored === undefined) {
139
- const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
140
- stored = new ArrayCacheByTimestamp(limit);
141
- this.ohlcvs[symbol][timeframe] = stored;
142
- }
143
- stored.append(parsed);
144
- client.resolve(stored, messageHash);
145
- return message;
146
- }
147
- /**
148
- * @method
149
- * @name ascendex#watchTrades
150
- * @description get the list of most recent trades for a particular symbol
151
- * @see https://ascendex.github.io/ascendex-pro-api/#channel-market-trades
152
- * @param {string} symbol unified symbol of the market to fetch trades for
153
- * @param {int} [since] timestamp in ms of the earliest trade to fetch
154
- * @param {int} [limit] the maximum amount of trades to fetch
155
- * @param {object} [params] extra parameters specific to the exchange API endpoint
156
- * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=public-trades}
157
- */
158
- async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
159
- return await this.watchTradesForSymbols([symbol], since, limit, params);
160
- }
161
- /**
162
- * @method
163
- * @name ascendex#watchTradesForSymbols
164
- * @description get the list of most recent trades for a list of symbols
165
- * @see https://ascendex.github.io/ascendex-pro-api/#channel-market-trades
166
- * @param {string[]} symbols unified symbol of the market to fetch trades for
167
- * @param {int} [since] timestamp in ms of the earliest trade to fetch
168
- * @param {int} [limit] the maximum amount of trades to fetch
169
- * @param {object} [params] extra parameters specific to the exchange API endpoint
170
- * @param {string} [params.name] the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
171
- * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=public-trades}
172
- */
173
- async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
174
- await this.loadMarkets();
175
- symbols = this.marketSymbols(symbols, undefined, false, true, true);
176
- const marketIds = [];
177
- const messageHashes = [];
178
- if (symbols !== undefined) {
179
- for (let i = 0; i < symbols.length; i++) {
180
- const market = this.market(symbols[i]);
181
- marketIds.push(market['id']);
182
- messageHashes.push('trades:' + market['id']);
183
- }
184
- }
185
- const channel = 'trades:' + marketIds.join(',');
186
- params = this.extend(params, {
187
- 'ch': channel,
188
- });
189
- const trades = await this.watchPublicMultiple(messageHashes, params);
190
- if (this.newUpdates) {
191
- const first = this.safeValue(trades, 0);
192
- const tradeSymbol = this.safeString(first, 'symbol');
193
- limit = trades.getLimit(tradeSymbol, limit);
194
- }
195
- return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
196
- }
197
- handleTrades(client, message) {
198
- //
199
- // {
200
- // "m": "trades",
201
- // "symbol": "BTC/USDT",
202
- // "data": [
203
- // {
204
- // "p": "40744.28",
205
- // "q": "0.00150",
206
- // "ts": 1647514330758,
207
- // "bm": true,
208
- // "seqnum": 72057633465800320
209
- // }
210
- // ]
211
- // }
212
- //
213
- const marketId = this.safeString(message, 'symbol');
214
- const symbol = this.safeSymbol(marketId);
215
- const channel = this.safeString(message, 'm');
216
- const messageHash = channel + ':' + marketId;
217
- const market = this.market(symbol);
218
- let rawData = this.safeValue(message, 'data');
219
- if (rawData === undefined) {
220
- rawData = [];
221
- }
222
- const trades = this.parseTrades(rawData, market);
223
- let tradesArray = this.safeValue(this.trades, symbol);
224
- if (tradesArray === undefined) {
225
- const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
226
- tradesArray = new ArrayCache(limit);
227
- }
228
- for (let i = 0; i < trades.length; i++) {
229
- tradesArray.append(trades[i]);
230
- }
231
- this.trades[symbol] = tradesArray;
232
- client.resolve(tradesArray, messageHash);
233
- }
234
- /**
235
- * @method
236
- * @name ascendex#watchOrderBook
237
- * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
238
- * @see https://ascendex.github.io/ascendex-pro-api/#channel-level-2-order-book-updates
239
- * @param {string} symbol unified symbol of the market to fetch the order book for
240
- * @param {int} [limit] the maximum amount of order book entries to return
241
- * @param {object} [params] extra parameters specific to the exchange API endpoint
242
- * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/?id=order-book-structure}
243
- */
244
- async watchOrderBook(symbol, limit = undefined, params = {}) {
245
- await this.loadMarkets();
246
- const market = this.market(symbol);
247
- const channel = 'depth' + ':' + market['id'];
248
- params = this.extend(params, {
249
- 'ch': channel,
250
- });
251
- const orderbook = await this.watchPublic(channel, params);
252
- return orderbook.limit();
253
- }
254
- async watchOrderBookSnapshot(symbol, limit = undefined, params = {}) {
255
- await this.loadMarkets();
256
- const market = this.market(symbol);
257
- const action = 'depth-snapshot';
258
- const channel = action + ':' + market['id'];
259
- params = this.extend(params, {
260
- 'action': action,
261
- 'args': {
262
- 'symbol': market['id'],
263
- },
264
- 'op': 'req',
265
- });
266
- const orderbook = await this.watchPublic(channel, params);
267
- return orderbook.limit();
268
- }
269
- async fetchOrderBookSnapshotCustom(symbol, limit = undefined, params = {}) {
270
- const restOrderBook = await this.fetchRestOrderBookSafe(symbol, limit, params);
271
- if (!(symbol in this.orderbooks)) {
272
- this.orderbooks[symbol] = this.orderBook();
273
- }
274
- const orderbook = this.orderbooks[symbol];
275
- orderbook.reset(restOrderBook);
276
- return orderbook;
277
- }
278
- handleOrderBookSnapshot(client, message) {
279
- //
280
- // {
281
- // "m": "depth",
282
- // "symbol": "BTC/USDT",
283
- // "data": {
284
- // "ts": 1647520500149,
285
- // "seqnum": 28590487626,
286
- // "asks": [
287
- // [Array], [Array], [Array],
288
- // [Array], [Array], [Array],
289
- // ],
290
- // "bids": [
291
- // [Array], [Array], [Array],
292
- // [Array], [Array], [Array],
293
- // ]
294
- // }
295
- // }
296
- //
297
- const marketId = this.safeString(message, 'symbol');
298
- const symbol = this.safeSymbol(marketId);
299
- const channel = this.safeString(message, 'm');
300
- const messageHash = channel + ':' + symbol;
301
- const orderbook = this.orderbooks[symbol];
302
- const data = this.safeValue(message, 'data');
303
- const snapshot = this.parseOrderBook(data, symbol);
304
- snapshot['nonce'] = this.safeInteger(data, 'seqnum');
305
- orderbook.reset(snapshot);
306
- // unroll the accumulated deltas
307
- const messages = orderbook.cache;
308
- for (let i = 0; i < messages.length; i++) {
309
- const messageItem = messages[i];
310
- this.handleOrderBookMessage(client, messageItem, orderbook);
311
- }
312
- this.orderbooks[symbol] = orderbook;
313
- client.resolve(orderbook, messageHash);
314
- }
315
- handleOrderBook(client, message) {
316
- //
317
- // {
318
- // "m": "depth",
319
- // "symbol": "BTC/USDT",
320
- // "data": {
321
- // "ts": 1647515136144,
322
- // "seqnum": 28590470736,
323
- // "asks": [ [Array], [Array] ],
324
- // "bids": [ [Array], [Array], [Array], [Array], [Array], [Array] ]
325
- // }
326
- // }
327
- //
328
- const channel = this.safeString(message, 'm');
329
- const marketId = this.safeString(message, 'symbol');
330
- const symbol = this.safeSymbol(marketId);
331
- const messageHash = channel + ':' + marketId;
332
- if (!(symbol in this.orderbooks)) {
333
- this.orderbooks[symbol] = this.orderBook({});
334
- }
335
- const orderbook = this.orderbooks[symbol];
336
- if (orderbook['nonce'] === undefined) {
337
- orderbook.cache.push(message);
338
- }
339
- else {
340
- this.handleOrderBookMessage(client, message, orderbook);
341
- client.resolve(orderbook, messageHash);
342
- }
343
- }
344
- handleDelta(bookside, delta) {
345
- //
346
- // ["40990.47","0.01619"],
347
- //
348
- const price = this.safeFloat(delta, 0);
349
- const amount = this.safeFloat(delta, 1);
350
- bookside.store(price, amount);
351
- }
352
- handleDeltas(bookside, deltas) {
353
- for (let i = 0; i < deltas.length; i++) {
354
- this.handleDelta(bookside, deltas[i]);
355
- }
356
- }
357
- handleOrderBookMessage(client, message, orderbook) {
358
- //
359
- // {
360
- // "m":"depth",
361
- // "symbol":"BTC/USDT",
362
- // "data":{
363
- // "ts":1647527417715,
364
- // "seqnum":28590257013,
365
- // "asks":[
366
- // ["40990.47","0.01619"],
367
- // ["41021.21","0"],
368
- // ["41031.59","0.06096"]
369
- // ],
370
- // "bids":[
371
- // ["40990.46","0.76114"],
372
- // ["40985.18","0"]
373
- // ]
374
- // }
375
- // }
376
- //
377
- const data = this.safeValue(message, 'data', {});
378
- const seqNum = this.safeInteger(data, 'seqnum');
379
- if (seqNum > orderbook['nonce']) {
380
- const asks = this.safeValue(data, 'asks', []);
381
- const bids = this.safeValue(data, 'bids', []);
382
- this.handleDeltas(orderbook['asks'], asks);
383
- this.handleDeltas(orderbook['bids'], bids);
384
- orderbook['nonce'] = seqNum;
385
- const timestamp = this.safeInteger(data, 'ts');
386
- orderbook['timestamp'] = timestamp;
387
- orderbook['datetime'] = this.iso8601(timestamp);
388
- }
389
- return orderbook;
390
- }
391
- /**
392
- * @method
393
- * @name ascendex#watchBalance
394
- * @description watch balance and get the amount of funds available for trading or funds locked in orders
395
- * @see https://ascendex.github.io/ascendex-pro-api/#channel-order-and-balance
396
- * @param {object} [params] extra parameters specific to the exchange API endpoint
397
- * @returns {object} a [balance structure]{@link https://docs.ccxt.com/?id=balance-structure}
398
- */
399
- async watchBalance(params = {}) {
400
- await this.loadMarkets();
401
- const [type, query] = this.handleMarketTypeAndParams('watchBalance', undefined, params);
402
- let channel = undefined;
403
- let messageHash = undefined;
404
- if ((type === 'spot') || (type === 'margin')) {
405
- const accountCategories = this.safeValue(this.options, 'accountCategories', {});
406
- let accountCategory = this.safeString(accountCategories, type, 'cash'); // cash, margin,
407
- accountCategory = accountCategory.toUpperCase();
408
- channel = 'order:' + accountCategory; // order and balance share the same channel
409
- messageHash = 'balance:' + type;
410
- }
411
- else {
412
- channel = 'futures-account-update';
413
- messageHash = 'balance:swap';
414
- }
415
- return await this.watchPrivate(channel, messageHash, query);
416
- }
417
- handleBalance(client, message) {
418
- //
419
- // cash account
420
- //
421
- // {
422
- // "m": "balance",
423
- // "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqEo",
424
- // "ac": "CASH",
425
- // "data": {
426
- // "a" : "USDT",
427
- // "sn": 8159798,
428
- // "tb": "600",
429
- // "ab": "600"
430
- // }
431
- // }
432
- //
433
- // margin account
434
- //
435
- // {
436
- // "m": "balance",
437
- // "accountId": "marOxpKJV83dxTRx0Eyxpa0gxc4Txt0P",
438
- // "ac": "MARGIN",
439
- // "data": {
440
- // "a" : "USDT",
441
- // "sn" : 8159802,
442
- // "tb" : "400", // total Balance
443
- // "ab" : "400", // available balance
444
- // "brw": "0", // borrowws
445
- // "int": "0" // interest
446
- // }
447
- // }
448
- //
449
- // futures
450
- // {
451
- // "m" : "futures-account-update", // message
452
- // "e" : "ExecutionReport", // event type
453
- // "t" : 1612508562129, // time
454
- // "acc" : "futures-account-id", // account ID
455
- // "at" : "FUTURES", // account type
456
- // "sn" : 23128, // sequence number,
457
- // "id" : "r177710001cbU3813942147C5kbFGOan",
458
- // "col": [
459
- // {
460
- // "a": "USDT", // asset code
461
- // "b": "1000000", // balance
462
- // "f": "1" // discount factor
463
- // }
464
- // ],
465
- // (...)
466
- //
467
- const channel = this.safeString(message, 'm');
468
- let result = undefined;
469
- let type = undefined;
470
- if ((channel === 'order') || (channel === 'futures-order')) {
471
- const data = this.safeValue(message, 'data');
472
- const marketId = this.safeString(data, 's');
473
- const market = this.safeMarket(marketId);
474
- const baseAccount = this.account();
475
- baseAccount['free'] = this.safeString(data, 'bab');
476
- baseAccount['total'] = this.safeString(data, 'btb');
477
- const quoteAccount = this.account();
478
- quoteAccount['free'] = this.safeString(data, 'qab');
479
- quoteAccount['total'] = this.safeString(data, 'qtb');
480
- if (market['contract']) {
481
- type = 'swap';
482
- result = this.safeValue(this.balance, type, {});
483
- }
484
- else {
485
- type = market['type'];
486
- result = this.safeValue(this.balance, type, {});
487
- }
488
- result[market['base']] = baseAccount;
489
- result[market['quote']] = quoteAccount;
490
- }
491
- else {
492
- const accountType = this.safeStringLower2(message, 'ac', 'at');
493
- const categoriesAccounts = this.safeValue(this.options, 'categoriesAccount');
494
- type = this.safeString(categoriesAccounts, accountType, 'spot');
495
- result = this.safeValue(this.balance, type, {});
496
- const data = this.safeValue(message, 'data');
497
- let balances = undefined;
498
- if (data === undefined) {
499
- balances = this.safeValue(message, 'col');
500
- }
501
- else {
502
- balances = [data];
503
- }
504
- for (let i = 0; i < balances.length; i++) {
505
- const balance = balances[i];
506
- const code = this.safeCurrencyCode(this.safeString(balance, 'a'));
507
- const account = this.account();
508
- account['free'] = this.safeString(balance, 'ab');
509
- account['total'] = this.safeString2(balance, 'tb', 'b');
510
- result[code] = account;
511
- }
512
- }
513
- const messageHash = 'balance' + ':' + type;
514
- client.resolve(this.safeBalance(result), messageHash);
515
- }
516
- /**
517
- * @method
518
- * @name ascendex#watchOrders
519
- * @see https://ascendex.github.io/ascendex-pro-api/#channel-order-and-balance
520
- * @description watches information on multiple orders made by the user
521
- * @param {string} symbol unified market symbol of the market orders were made in
522
- * @param {int} [since] the earliest time in ms to fetch orders for
523
- * @param {int} [limit] the maximum number of order structures to retrieve
524
- * @param {object} [params] extra parameters specific to the exchange API endpoint
525
- * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/?id=order-structure}
526
- */
527
- async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
528
- await this.loadMarkets();
529
- let market = undefined;
530
- if (symbol !== undefined) {
531
- market = this.market(symbol);
532
- symbol = market['symbol'];
533
- }
534
- const [type, query] = this.handleMarketTypeAndParams('watchOrders', market, params);
535
- let messageHash = undefined;
536
- let channel = undefined;
537
- if (type !== 'spot' && type !== 'margin') {
538
- channel = 'futures-order';
539
- messageHash = 'order:FUTURES';
540
- }
541
- else {
542
- const accountCategories = this.safeValue(this.options, 'accountCategories', {});
543
- let accountCategory = this.safeString(accountCategories, type, 'cash'); // cash, margin
544
- accountCategory = accountCategory.toUpperCase();
545
- messageHash = 'order' + ':' + accountCategory;
546
- channel = messageHash;
547
- }
548
- if (symbol !== undefined) {
549
- messageHash = messageHash + ':' + symbol;
550
- }
551
- const orders = await this.watchPrivate(channel, messageHash, query);
552
- if (this.newUpdates) {
553
- limit = orders.getLimit(symbol, limit);
554
- }
555
- return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
556
- }
557
- handleOrder(client, message) {
558
- //
559
- // spot order
560
- // {
561
- // "m": "order",
562
- // "accountId": "cshF5SlR9ukAXoDOuXbND4dVpBMw9gzH",
563
- // "ac": "CASH",
564
- // "data": {
565
- // "sn": 19399016185,
566
- // "orderId": "r17f9d7983faU7223046196CMlrj3bfC",
567
- // "s": "LTC/USDT",
568
- // "ot": "Limit",
569
- // "t": 1647614461160,
570
- // "p": "50",
571
- // "q": "0.1",
572
- // "sd": "Buy",
573
- // "st": "New",
574
- // "ap": "0",
575
- // "cfq": "0",
576
- // "sp": '',
577
- // "err": '',
578
- // "btb": "0",
579
- // "bab": "0",
580
- // "qtb": "8",
581
- // "qab": "2.995",
582
- // "cf": "0",
583
- // "fa": "USDT",
584
- // "ei": "NULL_VAL"
585
- // }
586
- // }
587
- //
588
- // futures order
589
- // {
590
- // "m": "futures-order",
591
- // "sn": 19399927636,
592
- // "e": "ExecutionReport",
593
- // "a": "futF5SlR9ukAXoDOuXbND4dVpBMw9gzH", // account id
594
- // "ac": "FUTURES",
595
- // "t": 1647622515434, // last execution time
596
- // (...)
597
- // }
598
- //
599
- const accountType = this.safeString(message, 'ac');
600
- const messageHash = 'order:' + accountType;
601
- const data = this.safeValue(message, 'data', message);
602
- const order = this.parseWsOrder(data);
603
- if (this.orders === undefined) {
604
- const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
605
- this.orders = new ArrayCacheBySymbolById(limit);
606
- }
607
- const orders = this.orders;
608
- orders.append(order);
609
- const symbolMessageHash = messageHash + ':' + order['symbol'];
610
- client.resolve(orders, symbolMessageHash);
611
- client.resolve(orders, messageHash);
612
- }
613
- parseWsOrder(order, market = undefined) {
614
- //
615
- // spot order
616
- // {
617
- // "sn": 19399016185, //sequence number
618
- // "orderId": "r17f9d7983faU7223046196CMlrj3bfC",
619
- // "s": "LTC/USDT",
620
- // "ot": "Limit", // order type
621
- // "t": 1647614461160, // last execution timestamp
622
- // "p": "50", // price
623
- // "q": "0.1", // quantity
624
- // "sd": "Buy", // side
625
- // "st": "New", // status
626
- // "ap": "0", // average fill price
627
- // "cfq": "0", // cumulated fill quantity
628
- // "sp": '', // stop price
629
- // "err": '',
630
- // "btb": "0", // base asset total balance
631
- // "bab": "0", // base asset available balance
632
- // "qtb": "8", // quote asset total balance
633
- // "qab": "2.995", // quote asset available balance
634
- // "cf": "0", // cumulated commission
635
- // "fa": "USDT", // fee asset
636
- // "ei": "NULL_VAL"
637
- // }
638
- //
639
- // futures order
640
- // {
641
- // "m": "futures-order",
642
- // "sn": 19399927636,
643
- // "e": "ExecutionReport",
644
- // "a": "futF5SlR9ukAXoDOuXbND4dVpBMw9gzH", // account id
645
- // "ac": "FUTURES",
646
- // "t": 1647622515434, // last execution time
647
- // "ct": 1647622515413, // order creation time
648
- // "orderId": "r17f9df469b1U7223046196Okf5Kbmd",
649
- // "sd": "Buy", // side
650
- // "ot": "Limit", // order type
651
- // "ei": "NULL_VAL",
652
- // "q": "1", // quantity
653
- // "p": "50", //price
654
- // "sp": "0", // stopPrice
655
- // "spb": '', // stopTrigger
656
- // "s": "LTC-PERP", // symbol
657
- // "st": "New", // state
658
- // "err": '',
659
- // "lp": "0", // last filled price
660
- // "lq": "0", // last filled quantity (base asset)
661
- // "ap": "0", // average filled price
662
- // "cfq": "0", // cummulative filled quantity (base asset)
663
- // "f": "0", // commission fee of the current execution
664
- // "cf": "0", // cumulative commission fee
665
- // "fa": "USDT", // fee asset
666
- // "psl": "0",
667
- // "pslt": "market",
668
- // "ptp": "0",
669
- // "ptpt": "market"
670
- // }
671
- //
672
- const status = this.parseOrderStatus(this.safeString(order, 'st'));
673
- const marketId = this.safeString(order, 's');
674
- const timestamp = this.safeInteger(order, 't');
675
- const symbol = this.safeSymbol(marketId, market, '/');
676
- const lastTradeTimestamp = this.safeInteger(order, 't');
677
- const price = this.safeString(order, 'p');
678
- const amount = this.safeString(order, 'q');
679
- const average = this.safeString(order, 'ap');
680
- const filled = this.safeString(order, 'cfq');
681
- const id = this.safeString(order, 'orderId');
682
- const type = this.safeStringLower(order, 'ot');
683
- const side = this.safeStringLower(order, 'sd');
684
- const feeCost = this.safeNumber(order, 'cf');
685
- let fee = undefined;
686
- if (feeCost !== undefined) {
687
- const feeCurrencyId = this.safeString(order, 'fa');
688
- const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
689
- fee = {
690
- 'cost': feeCost,
691
- 'currency': feeCurrencyCode,
692
- };
693
- }
694
- const stopPrice = this.parseNumber(this.omitZero(this.safeString(order, 'sp')));
695
- return this.safeOrder({
696
- 'info': order,
697
- 'id': id,
698
- 'clientOrderId': undefined,
699
- 'timestamp': timestamp,
700
- 'datetime': this.iso8601(timestamp),
701
- 'lastTradeTimestamp': lastTradeTimestamp,
702
- 'symbol': symbol,
703
- 'type': type,
704
- 'timeInForce': undefined,
705
- 'postOnly': undefined,
706
- 'side': side,
707
- 'price': price,
708
- 'stopPrice': stopPrice,
709
- 'triggerPrice': stopPrice,
710
- 'amount': amount,
711
- 'cost': undefined,
712
- 'average': average,
713
- 'filled': filled,
714
- 'remaining': undefined,
715
- 'status': status,
716
- 'fee': fee,
717
- 'trades': undefined,
718
- }, market);
719
- }
720
- handleErrorMessage(client, message) {
721
- //
722
- // {
723
- // "m": "disconnected",
724
- // "code": 100005,
725
- // "reason": "INVALID_WS_REQUEST_DATA",
726
- // "info": "Session is disconnected due to missing pong message from the client"
727
- // }
728
- //
729
- const errorCode = this.safeInteger(message, 'code');
730
- try {
731
- if (errorCode !== undefined) {
732
- const feedback = this.id + ' ' + this.json(message);
733
- this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
734
- const messageString = this.safeValue(message, 'message');
735
- if (messageString !== undefined) {
736
- this.throwBroadlyMatchedException(this.exceptions['broad'], messageString, feedback);
737
- }
738
- }
739
- return false;
740
- }
741
- catch (e) {
742
- if (e instanceof AuthenticationError) {
743
- const messageHash = 'authenticated';
744
- client.reject(e, messageHash);
745
- if (messageHash in client.subscriptions) {
746
- delete client.subscriptions[messageHash];
747
- }
748
- }
749
- else {
750
- client.reject(e);
751
- }
752
- return true;
753
- }
754
- }
755
- handleAuthenticate(client, message) {
756
- //
757
- // { m: "auth", id: "1647605234", code: 0 }
758
- //
759
- const messageHash = 'authenticated';
760
- client.resolve(message, messageHash);
761
- }
762
- handleMessage(client, message) {
763
- if (this.handleErrorMessage(client, message)) {
764
- return;
765
- }
766
- //
767
- // { m: "ping", hp: 3 }
768
- //
769
- // { m: "sub", ch: "bar:BTC/USDT", code: 0 }
770
- //
771
- // { m: 'sub', id: "1647515701", ch: "depth:BTC/USDT", code: 0 }
772
- //
773
- // { m: "connected", type: "unauth" }
774
- //
775
- // { m: "auth", id: "1647605234", code: 0 }
776
- //
777
- // order or balance sub
778
- // {
779
- // "m": "sub",
780
- // "id": "1647605952",
781
- // "ch": "order:cshF5SlR9ukAXoDOuXbND4dVpBMw9gzH", or futures-order
782
- // "code": 0
783
- // }
784
- //
785
- // ohlcv
786
- // {
787
- // "m": "bar",
788
- // "s": "BTC/USDT",
789
- // "data": {
790
- // "i": "1",
791
- // "ts": 1647510060000,
792
- // "o": "40813.93",
793
- // "c": "40804.57",
794
- // "h": "40814.21",
795
- // "l": "40804.56",
796
- // "v": "0.01537"
797
- // }
798
- // }
799
- //
800
- // trades
801
- //
802
- // {
803
- // "m": "trades",
804
- // "symbol": "BTC/USDT",
805
- // "data": [
806
- // {
807
- // "p": "40762.26",
808
- // "q": "0.01500",
809
- // "ts": 1647514306759,
810
- // "bm": true,
811
- // "seqnum": 72057633465795180
812
- // }
813
- // ]
814
- // }
815
- //
816
- // orderbook deltas
817
- //
818
- // {
819
- // "m":"depth",
820
- // "symbol":"BTC/USDT",
821
- // "data":{
822
- // "ts":1647527417715,
823
- // "seqnum":28590257013,
824
- // "asks":[
825
- // ["40990.47","0.01619"],
826
- // ["41021.21","0"],
827
- // ["41031.59","0.06096"]
828
- // ],
829
- // "bids":[
830
- // ["40990.46","0.76114"],
831
- // ["40985.18","0"]
832
- // ]
833
- // }
834
- // }
835
- //
836
- // orderbook snapshot
837
- // {
838
- // "m": "depth-snapshot",
839
- // "symbol": "BTC/USDT",
840
- // "data": {
841
- // "ts": 1647525938513,
842
- // "seqnum": 28590504772,
843
- // "asks": [
844
- // [Array], [Array], [Array], [Array], [Array], [Array], [Array],
845
- // [Array], [Array], [Array], [Array], [Array], [Array], [Array],
846
- // [Array], [Array], [Array], [Array], [Array], [Array], [Array],
847
- // (...)
848
- // ]
849
- // }
850
- //
851
- // spot order update
852
- // {
853
- // "m": "order",
854
- // "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
855
- // "ac": "CASH",
856
- // "data": {
857
- // "s": "BTC/USDT",
858
- // "sn": 8159711,
859
- // "sd": "Buy",
860
- // "ap": "0",
861
- // "bab": "2006.5974027",
862
- // "btb": "2006.5974027",
863
- // "cf": "0",
864
- // "cfq": "0",
865
- // (...)
866
- // }
867
- // }
868
- // future order update
869
- // {
870
- // "m": "futures-order",
871
- // "sn": 19404258063,
872
- // "e": "ExecutionReport",
873
- // "a": "futF5SlR9ukAXoDOuXbND4dVpBMw9gzH",
874
- // "ac": "FUTURES",
875
- // "t": 1647681792543,
876
- // "ct": 1647622515413,
877
- // "orderId": "r17f9df469b1U7223046196Okf5KbmdL",
878
- // (...)
879
- // "ptpt": "None"
880
- // }
881
- //
882
- // balance update cash
883
- // {
884
- // "m": "balance",
885
- // "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
886
- // "ac": "CASH",
887
- // "data": {
888
- // "a" : "USDT",
889
- // "sn": 8159798,
890
- // "tb": "600",
891
- // "ab": "600"
892
- // }
893
- // }
894
- //
895
- // balance update margin
896
- // {
897
- // "m": "balance",
898
- // "accountId": "marOxpKJV83dxTRx0Eyxpa0gxc4Txt0P",
899
- // "ac": "MARGIN",
900
- // "data": {
901
- // "a" : "USDT",
902
- // "sn" : 8159802,
903
- // "tb" : "400",
904
- // "ab" : "400",
905
- // "brw": "0",
906
- // "int": "0"
907
- // }
908
- // }
909
- //
910
- const subject = this.safeString(message, 'm');
911
- const methods = {
912
- 'ping': this.handlePing,
913
- 'auth': this.handleAuthenticate,
914
- 'sub': this.handleSubscriptionStatus,
915
- 'depth': this.handleOrderBook,
916
- 'depth-snapshot': this.handleOrderBookSnapshot,
917
- 'trades': this.handleTrades,
918
- 'bar': this.handleOHLCV,
919
- 'balance': this.handleBalance,
920
- 'futures-account-update': this.handleBalance,
921
- };
922
- const method = this.safeValue(methods, subject);
923
- if (method !== undefined) {
924
- method.call(this, client, message);
925
- }
926
- if ((subject === 'order') || (subject === 'futures-order')) {
927
- // this.handleOrder (client, message);
928
- // balance updates may be in the order structure
929
- // they may also be standalone balance updates related to account transfers
930
- this.handleOrder(client, message);
931
- if (subject === 'order') {
932
- this.handleBalance(client, message);
933
- }
934
- }
935
- }
936
- handleSubscriptionStatus(client, message) {
937
- //
938
- // { m: "sub", ch: "bar:BTC/USDT", code: 0 }
939
- //
940
- // { m: 'sub', id: "1647515701", ch: "depth:BTC/USDT", code: 0 }
941
- //
942
- const channel = this.safeString(message, 'ch', '');
943
- if (channel.indexOf('depth') > -1 && !(channel.indexOf('depth-snapshot') > -1)) {
944
- this.handleOrderBookSubscription(client, message);
945
- }
946
- return message;
947
- }
948
- handleOrderBookSubscription(client, message) {
949
- const channel = this.safeString(message, 'ch');
950
- const parts = channel.split(':');
951
- const marketId = parts[1];
952
- const market = this.safeMarket(marketId);
953
- const symbol = market['symbol'];
954
- if (symbol in this.orderbooks) {
955
- delete this.orderbooks[symbol];
956
- }
957
- this.orderbooks[symbol] = this.orderBook({});
958
- if (this.options['defaultType'] === 'swap' || market['contract']) {
959
- this.spawn(this.fetchOrderBookSnapshotCustom, symbol);
960
- }
961
- else {
962
- this.spawn(this.watchOrderBookSnapshot, symbol);
963
- }
964
- }
965
- async pong(client, message) {
966
- //
967
- // { m: "ping", hp: 3 }
968
- //
969
- try {
970
- await client.send({ 'op': 'pong', 'hp': this.safeInteger(message, 'hp') });
971
- }
972
- catch (e) {
973
- const error = new NetworkError(this.id + ' handlePing failed with error ' + this.exceptionMessage(e));
974
- client.reset(error);
975
- }
976
- }
977
- handlePing(client, message) {
978
- this.spawn(this.pong, client, message);
979
- }
980
- async authenticate(url, params = {}) {
981
- this.checkRequiredCredentials();
982
- const messageHash = 'authenticated';
983
- const client = this.client(url);
984
- let future = this.safeValue(client.subscriptions, messageHash);
985
- if (future === undefined) {
986
- const timestamp = this.milliseconds().toString();
987
- const urlParts = url.split('/');
988
- const partsLength = urlParts.length;
989
- const path = this.safeString(urlParts, partsLength - 1);
990
- const version = this.safeString(urlParts, partsLength - 2);
991
- const auth = timestamp + '+' + version + '/' + path;
992
- const secret = this.base64ToBinary(this.secret);
993
- const signature = this.hmac(this.encode(auth), secret, sha256, 'base64');
994
- const request = {
995
- 'op': 'auth',
996
- 'id': this.nonce().toString(),
997
- 't': timestamp,
998
- 'key': this.apiKey,
999
- 'sig': signature,
1000
- };
1001
- future = await this.watch(url, messageHash, this.extend(request, params), messageHash);
1002
- client.subscriptions[messageHash] = future;
1003
- }
1004
- return future;
1005
- }
1006
- }