ccxt 4.4.73 → 4.4.75

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 (89) hide show
  1. package/README.md +4 -4
  2. package/dist/ccxt.browser.min.js +2 -2
  3. package/dist/cjs/ccxt.js +1 -11
  4. package/dist/cjs/src/ace.js +9 -6
  5. package/dist/cjs/src/alpaca.js +3 -0
  6. package/dist/cjs/src/ascendex.js +6 -0
  7. package/dist/cjs/src/base/Exchange.js +36 -14
  8. package/dist/cjs/src/bequant.js +1 -0
  9. package/dist/cjs/src/binanceusdm.js +1 -1
  10. package/dist/cjs/src/bit2c.js +30 -4
  11. package/dist/cjs/src/bitbank.js +32 -0
  12. package/dist/cjs/src/bitbns.js +1 -1
  13. package/dist/cjs/src/bitflyer.js +1 -0
  14. package/dist/cjs/src/bithumb.js +34 -0
  15. package/dist/cjs/src/bitmart.js +74 -7
  16. package/dist/cjs/src/bitopro.js +37 -0
  17. package/dist/cjs/src/blofin.js +1 -1
  18. package/dist/cjs/src/bybit.js +14 -1
  19. package/dist/cjs/src/coinlist.js +87 -11
  20. package/dist/cjs/src/deribit.js +29 -1
  21. package/dist/cjs/src/gate.js +12 -7
  22. package/dist/cjs/src/hitbtc.js +7 -1
  23. package/dist/cjs/src/okx.js +29 -25
  24. package/dist/cjs/src/pro/ascendex.js +1 -1
  25. package/dist/cjs/src/pro/bingx.js +10 -1
  26. package/dist/cjs/src/pro/bitget.js +10 -1
  27. package/dist/cjs/src/pro/bitmart.js +10 -1
  28. package/dist/cjs/src/pro/bitopro.js +5 -4
  29. package/dist/cjs/src/pro/onetrading.js +7 -7
  30. package/js/ccxt.d.ts +2 -14
  31. package/js/ccxt.js +2 -10
  32. package/js/src/abstract/bitmart.d.ts +2 -0
  33. package/js/src/abstract/coinlist.d.ts +3 -0
  34. package/js/src/ace.js +9 -6
  35. package/js/src/alpaca.js +3 -0
  36. package/js/src/ascendex.js +6 -0
  37. package/js/src/base/Exchange.d.ts +1 -0
  38. package/js/src/base/Exchange.js +36 -14
  39. package/js/src/bequant.js +1 -0
  40. package/js/src/binanceusdm.js +1 -1
  41. package/js/src/bit2c.js +30 -4
  42. package/js/src/bitbank.js +32 -0
  43. package/js/src/bitbns.js +1 -1
  44. package/js/src/bitflyer.js +1 -0
  45. package/js/src/bithumb.js +34 -0
  46. package/js/src/bitmart.d.ts +24 -0
  47. package/js/src/bitmart.js +74 -7
  48. package/js/src/bitopro.js +37 -0
  49. package/js/src/blofin.js +1 -1
  50. package/js/src/bybit.js +14 -1
  51. package/js/src/coinlist.js +87 -11
  52. package/js/src/deribit.js +29 -1
  53. package/js/src/gate.js +12 -7
  54. package/js/src/hitbtc.js +7 -1
  55. package/js/src/okx.js +29 -25
  56. package/js/src/pro/ascendex.js +1 -1
  57. package/js/src/pro/bingx.js +10 -1
  58. package/js/src/pro/bitget.js +10 -1
  59. package/js/src/pro/bitmart.js +10 -1
  60. package/js/src/pro/bitopro.js +5 -4
  61. package/js/src/pro/onetrading.d.ts +7 -7
  62. package/js/src/pro/onetrading.js +7 -7
  63. package/package.json +1 -1
  64. package/js/src/abstract/bitcoincom.d.ts +0 -118
  65. package/js/src/abstract/bitcoincom.js +0 -11
  66. package/js/src/abstract/bitfinex1.d.ts +0 -72
  67. package/js/src/abstract/bitfinex1.js +0 -11
  68. package/js/src/abstract/bitpanda.d.ts +0 -26
  69. package/js/src/abstract/bitpanda.js +0 -11
  70. package/js/src/abstract/poloniexfutures.d.ts +0 -51
  71. package/js/src/abstract/poloniexfutures.js +0 -11
  72. package/js/src/abstract/wazirx.d.ts +0 -33
  73. package/js/src/abstract/wazirx.js +0 -11
  74. package/js/src/bitcoincom.d.ts +0 -4
  75. package/js/src/bitcoincom.js +0 -18
  76. package/js/src/bitpanda.d.ts +0 -4
  77. package/js/src/bitpanda.js +0 -17
  78. package/js/src/poloniexfutures.d.ts +0 -321
  79. package/js/src/poloniexfutures.js +0 -1941
  80. package/js/src/pro/bitcoincom.d.ts +0 -4
  81. package/js/src/pro/bitcoincom.js +0 -34
  82. package/js/src/pro/bitpanda.d.ts +0 -4
  83. package/js/src/pro/bitpanda.js +0 -17
  84. package/js/src/pro/poloniexfutures.d.ts +0 -108
  85. package/js/src/pro/poloniexfutures.js +0 -1042
  86. package/js/src/pro/wazirx.d.ts +0 -102
  87. package/js/src/pro/wazirx.js +0 -784
  88. package/js/src/static_dependencies/starknet/utils/json.d.ts +0 -24
  89. package/js/src/static_dependencies/starknet/utils/json.js +0 -43
@@ -1,1042 +0,0 @@
1
- // ----------------------------------------------------------------------------
2
-
3
- // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
- // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
- // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
-
7
- // ---------------------------------------------------------------------------
8
- import poloniexfuturesRest from '../poloniexfutures.js';
9
- import { AuthenticationError, BadRequest, ChecksumError } from '../base/errors.js';
10
- import { ArrayCache, ArrayCacheBySymbolById } from '../base/ws/Cache.js';
11
- // ---------------------------------------------------------------------------
12
- export default class poloniexfutures extends poloniexfuturesRest {
13
- describe() {
14
- return this.deepExtend(super.describe(), {
15
- 'has': {
16
- 'ws': true,
17
- 'cancelAllOrdersWs': false,
18
- 'cancelOrdersWs': false,
19
- 'cancelOrderWs': false,
20
- 'createOrderWs': false,
21
- 'editOrderWs': false,
22
- 'fetchBalanceWs': false,
23
- 'fetchOpenOrdersWs': false,
24
- 'fetchOrderWs': false,
25
- 'fetchTradesWs': false,
26
- 'watchOHLCV': false,
27
- 'watchOrderBook': true,
28
- 'watchTicker': true,
29
- 'watchTickers': false,
30
- 'watchTrades': true,
31
- 'watchTradesForSymbols': false,
32
- 'watchBalance': true,
33
- 'watchOrders': true,
34
- 'watchMyTrades': false,
35
- 'watchPosition': undefined,
36
- 'watchPositions': false,
37
- },
38
- 'urls': {
39
- 'api': {
40
- 'ws': 'wss://futures-apiws.poloniex.com/endpoint',
41
- },
42
- },
43
- 'options': {
44
- 'tradesLimit': 1000,
45
- 'ordersLimit': 1000,
46
- 'watchTicker': {
47
- 'method': '/contractMarket/ticker', // can also be /contractMarket/snapshot
48
- },
49
- 'watchOrders': {
50
- 'method': '/contractMarket/tradeOrders', // can also be /contractMarket/advancedOrders
51
- },
52
- 'watchOrderBook': {
53
- 'method': '/contractMarket/level2',
54
- 'snapshotDelay': 5,
55
- 'snapshotMaxRetries': 3,
56
- 'checksum': true,
57
- },
58
- 'streamLimit': 5,
59
- 'streamBySubscriptionsHash': {},
60
- 'streamIndex': -1,
61
- },
62
- 'streaming': {
63
- 'keepAlive': 30000,
64
- 'maxPingPongMisses': 2.0,
65
- },
66
- });
67
- }
68
- async negotiate(privateChannel, params = {}) {
69
- const connectId = privateChannel ? 'private' : 'public';
70
- const urls = this.safeValue(this.options, 'urls', {});
71
- if (connectId in urls) {
72
- // return urls[connectId];
73
- const storedFuture = urls[connectId];
74
- return await storedFuture;
75
- }
76
- // we store an awaitable to the url
77
- // so that multiple calls don't asynchronously
78
- // fetch different urls and overwrite each other
79
- urls[connectId] = this.spawn(this.negotiateHelper, privateChannel, params);
80
- this.options['urls'] = urls;
81
- const future = urls[connectId];
82
- return await future;
83
- }
84
- async negotiateHelper(privateChannel, params = {}) {
85
- let response = undefined;
86
- const connectId = privateChannel ? 'private' : 'public';
87
- try {
88
- if (privateChannel) {
89
- response = await this.privatePostBulletPrivate(params);
90
- //
91
- // {
92
- // "code": "200000",
93
- // "data": {
94
- // "instanceServers": [
95
- // {
96
- // "pingInterval": 50000,
97
- // "endpoint": "wss://push-private.kucoin.com/endpoint",
98
- // "protocol": "websocket",
99
- // "encrypt": true,
100
- // "pingTimeout": 10000
101
- // }
102
- // ],
103
- // "token": "2neAiuYvAU61ZDXANAGAsiL4-iAExhsBXZxftpOeh_55i3Ysy2q2LEsEWU64mdzUOPusi34M_wGoSf7iNyEWJ1UQy47YbpY4zVdzilNP-Bj3iXzrjjGlWtiYB9J6i9GjsxUuhPw3BlrzazF6ghq4Lzf7scStOz3KkxjwpsOBCH4=.WNQmhZQeUKIkh97KYgU0Lg=="
104
- // }
105
- // }
106
- //
107
- }
108
- else {
109
- response = await this.publicPostBulletPublic(params);
110
- }
111
- const data = this.safeValue(response, 'data', {});
112
- const instanceServers = this.safeValue(data, 'instanceServers', []);
113
- const firstInstanceServer = this.safeValue(instanceServers, 0);
114
- const pingInterval = this.safeInteger(firstInstanceServer, 'pingInterval');
115
- const endpoint = this.safeString(firstInstanceServer, 'endpoint');
116
- const token = this.safeString(data, 'token');
117
- const result = endpoint + '?' + this.urlencode({
118
- 'token': token,
119
- 'privateChannel': privateChannel,
120
- 'connectId': connectId,
121
- });
122
- const client = this.client(result);
123
- client.keepAlive = pingInterval;
124
- return result;
125
- }
126
- catch (e) {
127
- const future = this.safeValue(this.options['urls'], connectId);
128
- future.reject(e);
129
- delete this.options['urls'][connectId];
130
- }
131
- return undefined;
132
- }
133
- requestId() {
134
- const requestId = this.sum(this.safeInteger(this.options, 'requestId', 0), 1);
135
- this.options['requestId'] = requestId;
136
- return requestId;
137
- }
138
- /**
139
- * @ignore
140
- * @method
141
- * @description Connects to a websocket channel
142
- * @param {string} name name of the channel and suscriptionHash
143
- * @param {bool} isPrivate true for the authenticated url, false for the public url
144
- * @param {string} symbol is required for all public channels, not required for private channels (except position)
145
- * @param {object} subscription subscription parameters
146
- * @param {object} [params] extra parameters specific to the poloniex api
147
- * @returns {object} data from the websocket stream
148
- */
149
- async subscribe(name, isPrivate, symbol = undefined, subscription = undefined, params = {}) {
150
- const url = await this.negotiate(isPrivate);
151
- if (symbol !== undefined) {
152
- const market = this.market(symbol);
153
- const marketId = market['id'];
154
- name += ':' + marketId;
155
- }
156
- const messageHash = name;
157
- const tunnelId = await this.stream(url, messageHash);
158
- const requestId = this.requestId();
159
- const subscribe = {
160
- 'id': requestId,
161
- 'type': 'subscribe',
162
- 'topic': name,
163
- 'privateChannel': isPrivate,
164
- 'response': true,
165
- 'tunnelId': tunnelId,
166
- };
167
- const subscriptionRequest = {
168
- 'id': requestId,
169
- };
170
- if (subscription === undefined) {
171
- subscription = subscriptionRequest;
172
- }
173
- else {
174
- subscription = this.extend(subscriptionRequest, subscription);
175
- }
176
- const request = this.extend(subscribe, params);
177
- return await this.watch(url, messageHash, request, name, subscriptionRequest);
178
- }
179
- onClose(client, error) {
180
- this.options['streamBySubscriptionsHash'] = {};
181
- super.onClose(client, error);
182
- }
183
- async stream(url, subscriptionHash) {
184
- const streamBySubscriptionsHash = this.safeValue(this.options, 'streamBySubscriptionsHash', {});
185
- let stream = this.safeString(streamBySubscriptionsHash, subscriptionHash);
186
- if (stream === undefined) {
187
- let streamIndex = this.safeInteger(this.options, 'streamIndex', -1);
188
- const streamLimit = this.safeValue(this.options, 'streamLimit');
189
- streamIndex = streamIndex + 1;
190
- const normalizedIndex = streamIndex % streamLimit;
191
- this.options['streamIndex'] = streamIndex;
192
- const streamIndexString = this.numberToString(normalizedIndex);
193
- stream = 'stream-' + streamIndexString;
194
- this.options['streamBySubscriptionsHash'][subscriptionHash] = stream;
195
- const messageHash = 'tunnel:' + stream;
196
- const request = {
197
- 'id': messageHash,
198
- 'type': 'openTunnel',
199
- 'newTunnelId': stream,
200
- 'response': true,
201
- };
202
- const subscription = {
203
- 'id': messageHash,
204
- 'method': this.handleNewStream,
205
- };
206
- await this.watch(url, messageHash, request, messageHash, subscription);
207
- }
208
- return stream;
209
- }
210
- handleOrderBookSubscription(client, message, subscription) {
211
- const symbol = this.safeString(subscription, 'symbol');
212
- const limit = this.safeInteger(subscription, 'limit');
213
- this.orderbooks[symbol] = this.orderBook({}, limit);
214
- }
215
- handleSubscriptionStatus(client, message) {
216
- //
217
- // {
218
- // "id": "1578090438322",
219
- // "type": "ack"
220
- // }
221
- //
222
- const id = this.safeString(message, 'id');
223
- const subscriptionsById = this.indexBy(client.subscriptions, 'id');
224
- const subscription = this.safeValue(subscriptionsById, id, {});
225
- const method = this.safeValue(subscription, 'method');
226
- if (method !== undefined) {
227
- method.call(this, client, message, subscription);
228
- }
229
- return message;
230
- }
231
- handleNewStream(client, message, subscription) {
232
- //
233
- // {
234
- // "id": "1545910840805",
235
- // "type": "ack"
236
- // }
237
- //
238
- const messageHash = this.safeString(message, 'id');
239
- client.resolve(message, messageHash);
240
- }
241
- /**
242
- * @method
243
- * @name poloniexfutures#watchTicker
244
- * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
245
- * @see https://api-docs.poloniex.com/futures/websocket/public#get-real-time-symbol-ticker
246
- * @param {string} symbol unified symbol of the market to fetch the ticker for
247
- * @param {object} [params] extra parameters specific to the exchange API endpoint
248
- * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
249
- */
250
- async watchTicker(symbol, params = {}) {
251
- await this.loadMarkets();
252
- symbol = this.symbol(symbol);
253
- const name = '/contractMarket/ticker';
254
- return await this.subscribe(name, false, symbol, undefined, params);
255
- }
256
- /**
257
- * @method
258
- * @name poloniexfutures#watchTrades
259
- * @description get the list of most recent trades for a particular symbol
260
- * @see https://api-docs.poloniex.com/futures/websocket/public#full-matching-engine-datalevel-3
261
- * @param {string} symbol unified symbol of the market to fetch trades for
262
- * @param {int} [since] timestamp in ms of the earliest trade to fetch
263
- * @param {int} [limit] the maximum amount of trades to fetch
264
- * @param {object} [params] extra parameters specific to the exchange API endpoint
265
- * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
266
- */
267
- async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
268
- await this.loadMarkets();
269
- const options = this.safeValue(this.options, 'watchTrades');
270
- let name = this.safeString(options, 'method', '/contractMarket/execution'); // can also be /contractMarket/snapshot
271
- [name, params] = this.handleOptionAndParams(params, 'method', 'name', name);
272
- symbol = this.symbol(symbol);
273
- const trades = await this.subscribe(name, false, symbol, undefined, params);
274
- if (this.newUpdates) {
275
- limit = trades.getLimit(symbol, limit);
276
- }
277
- return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
278
- }
279
- /**
280
- * @method
281
- * @name poloniexfutures#watchOrderBook
282
- * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
283
- * @see https://api-docs.poloniex.com/futures/websocket/public#level-2-market-data
284
- * @param {string} symbol unified symbol of the market to fetch the order book for
285
- * @param {int} [limit] not used by poloniexfutures watchOrderBook
286
- * @param {object} [params] extra parameters specific to the exchange API endpoint
287
- * @param {string} [params.method] the method to use. Defaults to /contractMarket/level2 can also be /contractMarket/level3v2 to receive the raw stream of orders
288
- * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
289
- */
290
- async watchOrderBook(symbol, limit = undefined, params = {}) {
291
- await this.loadMarkets();
292
- const options = this.safeValue(this.options, 'watchOrderBook');
293
- let name = this.safeString(options, 'method', '/contractMarket/level2'); // can also be /contractMarket/level2, /contractMarket/level2Depth5:{symbol}, /contractMarket/level2Depth50:{symbol}
294
- [name, params] = this.handleOptionAndParams(params, 'method', 'name', name);
295
- if (name === '/contractMarket/level2' && limit !== undefined) {
296
- if (limit !== 5 && limit !== 50) {
297
- throw new BadRequest(this.id + ' watchOrderBook limit argument must be none, 5 or 50 if using method /contractMarket/level2');
298
- }
299
- name += 'Depth' + this.numberToString(limit);
300
- }
301
- const subscription = {
302
- 'symbol': symbol,
303
- 'limit': limit,
304
- 'method': this.handleOrderBookSubscription,
305
- };
306
- const orderbook = await this.subscribe(name, false, symbol, subscription, params);
307
- return orderbook.limit();
308
- }
309
- /**
310
- * @method
311
- * @name poloniexfutures#watchOrders
312
- * @description watches information on multiple orders made by the user
313
- * @see https://api-docs.poloniex.com/futures/websocket/user-messages#private-messages
314
- * @param {string} symbol filter by unified market symbol of the market orders were made in
315
- * @param {int} [since] the earliest time in ms to fetch orders for
316
- * @param {int} [limit] the maximum number of order structures to retrieve
317
- * @param {object} [params] extra parameters specific to the exchange API endpoint
318
- * @param {string} [params.method] the method to use will default to /contractMarket/tradeOrders. Set to /contractMarket/advancedOrders to watch stop orders
319
- * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
320
- */
321
- async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
322
- await this.loadMarkets();
323
- const options = this.safeValue(this.options, 'watchOrders');
324
- const name = this.safeString(options, 'method', '/contractMarket/tradeOrders');
325
- let orders = await this.subscribe(name, true, undefined, undefined, params);
326
- if (this.newUpdates) {
327
- limit = orders.getLimit(symbol, limit);
328
- }
329
- orders = this.filterBySymbolSinceLimit(orders, symbol, since, limit);
330
- const length = orders.length;
331
- if (length === 0) {
332
- return await this.watchOrders(symbol, since, limit, params);
333
- }
334
- return orders;
335
- }
336
- /**
337
- * @method
338
- * @name poloniexfutures#watchBalance
339
- * @description watch balance and get the amount of funds available for trading or funds locked in orders
340
- * @see https://api-docs.poloniex.com/futures/websocket/user-messages#account-balance-events
341
- * @param {object} [params] extra parameters specific to the exchange API endpoint
342
- * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
343
- */
344
- async watchBalance(params = {}) {
345
- await this.loadMarkets();
346
- const name = '/contractAccount/wallet';
347
- return await this.subscribe(name, true, undefined, undefined, params);
348
- }
349
- handleTrade(client, message) {
350
- //
351
- // {
352
- // "data": {
353
- // "makerUserId": "1410336",
354
- // "symbol": "BTCUSDTPERP",
355
- // "sequence": 267913,
356
- // "side": "buy",
357
- // "size": 2,
358
- // "price": 28409.5,
359
- // "takerOrderId": "6426f9f15782c8000776995f",
360
- // "makerOrderId": "6426f9f141406b0008df976e",
361
- // "takerUserId": "1410880",
362
- // "tradeId": "6426f9f1de029f0001e334dd",
363
- // "ts": 1680275953739092500,
364
- // },
365
- // "subject": "match",
366
- // "topic": "/contractMarket/execution:BTCUSDTPERP",
367
- // "type": "message",
368
- // }
369
- //
370
- const data = this.safeValue(message, 'data', {});
371
- const marketId = this.safeString(data, 'symbol');
372
- if (marketId !== undefined) {
373
- const trade = this.parseWsTrade(data);
374
- const symbol = trade['symbol'];
375
- const messageHash = '/contractMarket/execution:' + marketId;
376
- let stored = this.safeValue(this.trades, symbol);
377
- if (stored === undefined) {
378
- const tradesLimit = this.safeInteger(this.options, 'tradesLimit', 1000);
379
- stored = new ArrayCache(tradesLimit);
380
- this.trades[symbol] = stored;
381
- }
382
- stored.append(trade);
383
- client.resolve(stored, messageHash);
384
- }
385
- return message;
386
- }
387
- parseWsTrade(trade, market = undefined) {
388
- //
389
- // handleTrade
390
- //
391
- // {
392
- // "makerUserId": "1410880",
393
- // "symbol": "BTCUSDTPERP",
394
- // "sequence": 731390,
395
- // "side": "sell",
396
- // "size": 2,
397
- // "price": 29372.4,
398
- // "takerOrderId": "644ef0fdd64748000759218a",
399
- // "makerOrderId": "644ef0fd25f4a50007f12fc5",
400
- // "takerUserId": "1410880",
401
- // "tradeId": "644ef0fdde029f0001eec346",
402
- // "ts": 1682895101923194000
403
- // }
404
- //
405
- const marketId = this.safeString(trade, 'symbol');
406
- market = this.safeMarket(marketId, market);
407
- const timestamp = this.safeIntegerProduct(trade, 'ts', 0.000001);
408
- return this.safeTrade({
409
- 'info': trade,
410
- 'id': this.safeString(trade, 'tradeId'),
411
- 'symbol': this.safeString(market, 'symbol'),
412
- 'timestamp': timestamp,
413
- 'datetime': this.iso8601(timestamp),
414
- 'order': this.safeString2(trade, 'takerOrderId', 'makerOrderId'),
415
- 'type': undefined,
416
- 'side': this.safeString(trade, 'side'),
417
- 'takerOrMaker': undefined,
418
- 'price': this.safeString(trade, 'price'),
419
- 'amount': this.safeString2(trade, 'matchSize', 'size'),
420
- 'cost': undefined,
421
- 'fee': undefined,
422
- }, market);
423
- }
424
- parseWsOrderTrade(trade, market = undefined) {
425
- //
426
- // {
427
- // "symbol": "BTC_USDT",
428
- // "type": "LIMIT",
429
- // "quantity": "1",
430
- // "orderId": "32471407854219264",
431
- // "tradeFee": "0",
432
- // "clientOrderId": "",
433
- // "accountType": "SPOT",
434
- // "feeCurrency": "",
435
- // "eventType": "place",
436
- // "source": "API",
437
- // "side": "BUY",
438
- // "filledQuantity": "0",
439
- // "filledAmount": "0",
440
- // "matchRole": "MAKER",
441
- // "state": "NEW",
442
- // "tradeTime": 0,
443
- // "tradeAmount": "0",
444
- // "orderAmount": "0",
445
- // "createTime": 1648708186922,
446
- // "price": "47112.1",
447
- // "tradeQty": "0",
448
- // "tradePrice": "0",
449
- // "tradeId": "0",
450
- // "ts": 1648708187469
451
- // }
452
- //
453
- const timestamp = this.safeInteger(trade, 'tradeTime');
454
- const marketId = this.safeString(trade, 'symbol');
455
- return this.safeTrade({
456
- 'info': trade,
457
- 'id': this.safeString(trade, 'tradeId'),
458
- 'symbol': this.safeSymbol(marketId, market),
459
- 'timestamp': timestamp,
460
- 'datetime': this.iso8601(timestamp),
461
- 'order': this.safeString(trade, 'orderId'),
462
- 'type': this.safeStringLower(trade, 'type'),
463
- 'side': this.safeString(trade, 'side'),
464
- 'takerOrMaker': this.safeStringLower(trade, 'matchRole'),
465
- 'price': this.safeString(trade, 'price'),
466
- 'amount': this.safeString(trade, 'tradeAmount'),
467
- 'cost': undefined,
468
- 'fee': {
469
- 'rate': undefined,
470
- 'cost': this.safeString(trade, 'tradeFee'),
471
- 'currency': this.safeString(trade, 'feeCurrency'),
472
- },
473
- }, market);
474
- }
475
- handleOrder(client, message) {
476
- //
477
- // {
478
- // "data": {
479
- // "symbol": "ADAUSDTPERP",
480
- // "orderType": "limit",
481
- // "side": "buy",
482
- // "canceledSize": "1",
483
- // "orderId": "642b4d4c0494cd0007c76813",
484
- // "type": "canceled",
485
- // "orderTime": "1680559436101909048",
486
- // "size": "1",
487
- // "filledSize": "0",
488
- // "marginType": 1,
489
- // "price": "0.25",
490
- // "remainSize": "0",
491
- // "clientOid": "112cbbf1-95a3-4917-957c-d3a87d81f853",
492
- // "status": "done",
493
- // "ts": 1680559677560686600
494
- // },
495
- // "subject": "orderChange",
496
- // "topic": "/contractMarket/tradeOrders",
497
- // "channelType": "private",
498
- // "type": "message",
499
- // "userId": "1139790"
500
- // }
501
- // stop order
502
- // {
503
- // "data": {
504
- // "orderType": "stop",
505
- // "symbol": "BTCUSDTPERP",
506
- // "side": "buy",
507
- // "stopPriceType": "TP",
508
- // "orderId": "64514fe1850d2100074378f6",
509
- // "type": "open",
510
- // "createdAt": 1683050465847,
511
- // "stopPrice": "29000",
512
- // "size": 2,
513
- // "stop": "up",
514
- // "marginType": 0,
515
- // "orderPrice": "28552.9",
516
- // "ts": 1683050465847597300
517
- // },
518
- // "subject": "stopOrder",
519
- // "topic": "/contractMarket/advancedOrders",
520
- // "channelType": "private",
521
- // "id": "64514fe1850d2100074378fa",
522
- // "type": "message",
523
- // "userId": "1160396"
524
- // }
525
- //
526
- const data = this.safeValue(message, 'data', {});
527
- let orders = this.orders;
528
- if (orders === undefined) {
529
- const limit = this.safeInteger(this.options, 'ordersLimit');
530
- orders = new ArrayCacheBySymbolById(limit);
531
- this.orders = orders;
532
- }
533
- const messageHash = '/contractMarket/tradeOrders';
534
- const parsed = this.parseWsOrder(data);
535
- orders.append(parsed);
536
- client.resolve(orders, messageHash);
537
- return message;
538
- }
539
- parseOrderStatus(status, type) {
540
- /**
541
- * @ignore
542
- * @method
543
- * @param {string} status "match", "open", "done"
544
- * @param {string} type "open", "match", "filled", "canceled", "update"
545
- * @returns {string}
546
- */
547
- const types = {
548
- 'canceled': 'canceled',
549
- 'cancel': 'canceled',
550
- 'filled': 'closed',
551
- };
552
- let parsedStatus = this.safeString(types, type);
553
- if (parsedStatus === undefined) {
554
- const statuses = {
555
- 'open': 'open',
556
- 'match': 'open',
557
- 'done': 'closed',
558
- };
559
- parsedStatus = this.safeString(statuses, status, status);
560
- }
561
- return parsedStatus;
562
- }
563
- parseWsOrder(order, market = undefined) {
564
- //
565
- // {
566
- // "symbol": "ADAUSDTPERP",
567
- // "orderType": "limit",
568
- // "side": "buy",
569
- // "canceledSize": "1",
570
- // "orderId": "642b4d4c0494cd0007c76813",
571
- // "type": "canceled",
572
- // "orderTime": "1680559436101909048",
573
- // "size": "1",
574
- // "filledSize": "0",
575
- // "marginType": 1,
576
- // "price": "0.25",
577
- // "remainSize": "0",
578
- // "clientOid": "112cbbf1-95a3-4917-957c-d3a87d81f853",
579
- // "status": "done",
580
- // "ts": 1680559677560686600
581
- // }
582
- // stop
583
- // {
584
- // "orderType": "stop",
585
- // "symbol": "BTCUSDTPERP",
586
- // "side": "buy",
587
- // "stopPriceType": "TP",
588
- // "orderId": "64514fe1850d2100074378f6",
589
- // "type": "open",
590
- // "createdAt": 1683050465847,
591
- // "stopPrice": "29000",
592
- // "size": 2,
593
- // "stop": "up",
594
- // "marginType": 0,
595
- // "orderPrice": "28552.9",
596
- // "ts": 1683050465847597300
597
- // }
598
- //
599
- const id = this.safeString(order, 'orderId');
600
- const clientOrderId = this.safeString(order, 'clientOid');
601
- const marketId = this.safeString(order, 'symbol');
602
- const timestamp = this.safeIntegerProduct2(order, 'orderTime', 'ts', 0.000001);
603
- const status = this.safeString(order, 'status');
604
- const messageType = this.safeString(order, 'type');
605
- return this.safeOrder({
606
- 'info': order,
607
- 'symbol': this.safeSymbol(marketId, market),
608
- 'id': id,
609
- 'clientOrderId': clientOrderId,
610
- 'timestamp': timestamp,
611
- 'datetime': this.iso8601(timestamp),
612
- 'lastTradeTimestamp': undefined,
613
- 'type': this.safeString(order, 'orderType'),
614
- 'timeInForce': undefined,
615
- 'postOnly': undefined,
616
- 'side': this.safeString(order, 'side'),
617
- 'price': this.safeString2(order, 'price', 'orderPrice'),
618
- 'stopPrice': this.safeString(order, 'stopPrice'),
619
- 'triggerPrice': undefined,
620
- 'amount': this.safeString(order, 'size'),
621
- 'cost': undefined,
622
- 'average': undefined,
623
- 'filled': this.safeString(order, 'filledSize'),
624
- 'remaining': this.safeString(order, 'remainSize'),
625
- 'status': this.parseOrderStatus(status, messageType),
626
- 'fee': undefined,
627
- 'trades': undefined,
628
- });
629
- }
630
- handleTicker(client, message) {
631
- //
632
- // {
633
- // "subject": "ticker",
634
- // "topic": "/contractMarket/ticker:BTCUSDTPERP",
635
- // "data": {
636
- // "symbol": "BTCUSDTPERP", // Market of the symbol
637
- // "sequence": 45, // Sequence number which is used to judge the continuity of the pushed messages
638
- // "side": "sell", // Transaction side of the last traded taker order
639
- // "price": 3600.00, // Filled price
640
- // "size": 16, // Filled quantity
641
- // "tradeId": "5c9dcf4170744d6f5a3d32fb", // Order ID
642
- // "bestBidSize": 795, // Best bid size
643
- // "bestBidPrice": 3200.00, // Best bid
644
- // "bestAskPrice": 3600.00, // Best ask size
645
- // "bestAskSize": 284, // Best ask
646
- // "ts": 1553846081210004941 // Filled time - nanosecond
647
- // },
648
- // "type": "message",
649
- // }
650
- //
651
- // {
652
- // "topic": "/contractMarket/snapshot:BTCUSDTPERP",
653
- // "subject": "snapshot.24h",
654
- // "data": {
655
- // "volume": 30449670, //24h Volume
656
- // "turnover": 845169919063, //24h Turnover
657
- // "lastPrice": 3551, //Last price
658
- // "priceChgPct": 0.0043, //24h Change
659
- // "ts": 1547697294838004923 //Snapshot time (nanosecond)
660
- // }
661
- // }
662
- //
663
- const data = this.safeValue(message, 'data', {});
664
- const messageHash = this.safeString(message, 'topic');
665
- const symbol = this.getSymbolFromTopic(messageHash);
666
- if (symbol !== undefined) {
667
- const ticker = this.parseTicker(data);
668
- this.tickers[symbol] = ticker;
669
- client.resolve(ticker, messageHash);
670
- }
671
- return message;
672
- }
673
- handleL3OrderBook(client, message) {
674
- //
675
- // {
676
- // "data": {
677
- // "symbol": "BTCUSDTPERP",
678
- // "sequence": 1679593048010,
679
- // "orderId": "6426fec8586b9500089d64d8",
680
- // "clientOid": "14e6ee8e-8757-462c-84db-ed12c2b62f55",
681
- // "ts": 1680277192127513900
682
- // },
683
- // "subject": "received",
684
- // "topic": "/contractMarket/level3v2:BTCUSDTPERP",
685
- // "type": "message"
686
- // }
687
- //
688
- // {
689
- // "data": {
690
- // "symbol": "BTCUSDTPERP",
691
- // "sequence": 1679593047982,
692
- // "side": "sell",
693
- // "orderTime": "1680277191900131371",
694
- // "size": "1",
695
- // "orderId": "6426fec7d32b6e000790268b",
696
- // "price": "28376.4",
697
- // "ts": 1680277191939042300
698
- // },
699
- // "subject": "open",
700
- // "topic": "/contractMarket/level3v2:BTCUSDTPERP",
701
- // "type": "message"
702
- // }
703
- //
704
- // {
705
- // "data": {
706
- // "symbol": "BTCUSDTPERP",
707
- // "reason": "canceled", // or "filled"
708
- // "sequence": 1679593047983,
709
- // "orderId": "6426fec74026fa0008e7046f",
710
- // "ts": 1680277191949842000
711
- // },
712
- // "subject": "done",
713
- // "topic": "/contractMarket/level3v2:BTCUSDTPERP",
714
- // "type": "message"
715
- // }
716
- //
717
- const messageHash = this.safeString(message, 'topic');
718
- const subject = this.safeString(message, 'subject');
719
- if (subject === 'received') {
720
- return;
721
- }
722
- // At the time of writting this, there is no implementation to easily convert each order into the orderbook so raw messages are returned
723
- client.resolve(message, messageHash);
724
- }
725
- handleLevel2(client, message) {
726
- // {
727
- // "subject": "level2",
728
- // "topic": "/contractMarket/level2:BTCUSDTPERP",
729
- // "type": "message",
730
- // "data": {
731
- // "sequence": 18, // Sequence number which is used to judge the continuity of pushed messages
732
- // "change": "5000.0,sell,83" // Price, side, quantity
733
- // "timestamp": 1551770400000
734
- // }
735
- // }
736
- const topic = this.safeString(message, 'topic');
737
- const isSnapshot = topic.indexOf('Depth') >= 0;
738
- if (isSnapshot) {
739
- this.handeL2Snapshot(client, message);
740
- return;
741
- }
742
- this.handleL2OrderBook(client, message);
743
- }
744
- handleL2OrderBook(client, message) {
745
- //
746
- // {
747
- // "id": 1545910660740,
748
- // "type": "subscribe",
749
- // "topic": "/contractMarket/level2:BTCUSDTPERP",
750
- // "response": true
751
- // }
752
- //
753
- // {
754
- // "subject": "level2",
755
- // "topic": "/contractMarket/level2:BTCUSDTPERP",
756
- // "type": "message",
757
- // "data": {
758
- // "sequence": 18, // Sequence number which is used to judge the continuity of pushed messages
759
- // "change": "5000.0,sell,83" // Price, side, quantity
760
- // "timestamp": 1551770400000
761
- // }
762
- // }
763
- //
764
- const data = this.safeValue(message, 'data', {});
765
- const messageHash = this.safeString(message, 'topic', '');
766
- const symbol = this.getSymbolFromTopic(messageHash);
767
- let orderBook = this.safeValue(this.orderbooks, symbol);
768
- if (orderBook === undefined) {
769
- this.orderbooks[symbol] = this.orderBook({});
770
- orderBook = this.orderbooks[symbol];
771
- orderBook['symbol'] = symbol;
772
- }
773
- const nonce = this.safeInteger(orderBook, 'nonce');
774
- if (nonce === undefined) {
775
- const cacheLength = orderBook.cache.length;
776
- const snapshotDelay = this.handleOption('watchOrderBook', 'snapshotDelay', 5);
777
- if (cacheLength === snapshotDelay) {
778
- const limit = 0;
779
- this.spawn(this.loadOrderBook, client, messageHash, symbol, limit, {});
780
- }
781
- orderBook.cache.push(data);
782
- return;
783
- }
784
- try {
785
- this.handleDelta(orderBook, data);
786
- client.resolve(orderBook, messageHash);
787
- }
788
- catch (e) {
789
- delete this.orderbooks[symbol];
790
- client.reject(e, messageHash);
791
- }
792
- }
793
- handeL2Snapshot(client, message) {
794
- //
795
- // {
796
- // "type": "message",
797
- // "topic": "/contractMarket/level2Depth5:BTCUSDTPERP",
798
- // "subject": "level2",
799
- // "data": {
800
- // "asks": [
801
- // ["9993", "3"],
802
- // ["9992", "3"],
803
- // ["9991", "47"],
804
- // ["9990", "32"],
805
- // ["9989", "8"]
806
- // ],
807
- // "bids": [
808
- // ["9988", "56"],
809
- // ["9987", "15"],
810
- // ["9986", "100"],
811
- // ["9985", "10"],
812
- // ["9984", "10"]
813
- // ],
814
- // "timestamp": 1682993050531,
815
- // }
816
- // }
817
- //
818
- const data = this.safeValue(message, 'data', {});
819
- const messageHash = this.safeString(message, 'topic', '');
820
- const symbol = this.getSymbolFromTopic(messageHash);
821
- const timestamp = this.safeInteger(data, 'timestamp');
822
- const snapshot = this.parseOrderBook(data, symbol, timestamp, 'bids', 'asks');
823
- const orderbook = this.orderBook(snapshot);
824
- this.orderbooks[symbol] = orderbook;
825
- client.resolve(orderbook, messageHash);
826
- }
827
- getSymbolFromTopic(topic) {
828
- const splitTopic = topic.split(':');
829
- const marketId = this.safeString(splitTopic, 1);
830
- return this.safeSymbol(marketId);
831
- }
832
- getCacheIndex(orderbook, cache) {
833
- const firstDelta = this.safeValue(cache, 0);
834
- const nonce = this.safeInteger(orderbook, 'nonce');
835
- const firstDeltaSequence = this.safeInteger(firstDelta, 'sequence');
836
- if (firstDeltaSequence > nonce + 1) {
837
- return -1;
838
- }
839
- for (let i = 0; i < cache.length; i++) {
840
- const delta = cache[i];
841
- const sequence = this.safeInteger(delta, 'sequence');
842
- if (nonce === sequence - 1) {
843
- return i;
844
- }
845
- }
846
- return cache.length;
847
- }
848
- handleDelta(orderbook, delta) {
849
- //
850
- // {
851
- // sequence: 123677914,
852
- // lastSequence: 123677913,
853
- // change: '80.36,buy,4924',
854
- // changes: [ '80.19,buy,0',"80.15,buy,10794" ],
855
- // timestamp: 1715643483528
856
- // },
857
- //
858
- const sequence = this.safeInteger(delta, 'sequence');
859
- const lastSequence = this.safeInteger(delta, 'lastSequence');
860
- const nonce = this.safeInteger(orderbook, 'nonce');
861
- if (nonce > sequence) {
862
- return;
863
- }
864
- if (nonce !== lastSequence) {
865
- const checksum = this.handleOption('watchOrderBook', 'checksum', true);
866
- if (checksum) {
867
- throw new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(''));
868
- }
869
- }
870
- const changes = this.safeList(delta, 'changes');
871
- for (let i = 0; i < changes.length; i++) {
872
- const change = changes[i];
873
- const splitChange = change.split(',');
874
- const price = this.safeNumber(splitChange, 0);
875
- const side = this.safeString(splitChange, 1);
876
- const size = this.safeNumber(splitChange, 2);
877
- const orderBookSide = (side === 'buy') ? orderbook['bids'] : orderbook['asks'];
878
- orderBookSide.store(price, size);
879
- }
880
- const timestamp = this.safeInteger(delta, 'timestamp');
881
- orderbook['timestamp'] = timestamp;
882
- orderbook['datetime'] = this.iso8601(timestamp);
883
- orderbook['nonce'] = sequence;
884
- }
885
- handleBalance(client, message) {
886
- //
887
- // {
888
- // "data": {
889
- // "currency": "USDT",
890
- // "availableBalance": "4.0000000000",
891
- // "timestamp": "1680557568670"
892
- // },
893
- // "subject": "availableBalance.change",
894
- // "topic": "/contractAccount/wallet",
895
- // "channelType": "private",
896
- // "id": "642b4600cae86800074b5ab7",
897
- // "type": "message",
898
- // "userId": "1139790"
899
- // }
900
- //
901
- // {
902
- // "data": {
903
- // "currency": "USDT",
904
- // "orderMargin": "0.0000000000",
905
- // "timestamp": "1680558743307"
906
- // },
907
- // "subject": "orderMargin.change",
908
- // "topic": "/contractAccount/wallet",
909
- // "channelType": "private",
910
- // "id": "642b4a97b58e360007c3a237",
911
- // "type": "message",
912
- // "userId": "1139790"
913
- // }
914
- //
915
- const data = this.safeValue(message, 'data', []);
916
- const messageHash = '/contractAccount/wallet';
917
- const currencyId = this.safeString(data, 'currency');
918
- const currency = this.currency(currencyId);
919
- const code = currency['code'];
920
- this.balance[code] = this.parseWsBalance(data);
921
- client.resolve(this.balance[code], messageHash);
922
- return message;
923
- }
924
- parseWsBalance(response) {
925
- //
926
- // {
927
- // "currency": "USDT",
928
- // "availableBalance": "4.0000000000",
929
- // "timestamp": "1680557568670"
930
- // }
931
- //
932
- // {
933
- // "currency": "USDT",
934
- // "orderMargin": "0.0000000000",
935
- // "timestamp": "1680558743307"
936
- // }
937
- //
938
- const timestamp = this.safeInteger(response, 'timestamp');
939
- const result = {
940
- 'info': response,
941
- 'timestamp': timestamp,
942
- 'datetime': this.iso8601(timestamp),
943
- };
944
- const currencyId = this.safeString(response, 'currency');
945
- const code = this.safeCurrencyCode(currencyId);
946
- const newAccount = this.account();
947
- newAccount['free'] = this.safeString(response, 'availableBalance');
948
- result[code] = newAccount;
949
- return this.safeBalance(result);
950
- }
951
- handleSystemStatus(client, message) {
952
- //
953
- // {
954
- // "id": "1578090234088", // connectId
955
- // "type": "welcome",
956
- // }
957
- //
958
- return message;
959
- }
960
- handleSubject(client, message) {
961
- const subject = this.safeString(message, 'subject');
962
- const methods = {
963
- 'auth': this.handleAuthenticate,
964
- 'received': this.handleL3OrderBook,
965
- 'open': this.handleL3OrderBook,
966
- 'update': this.handleL3OrderBook,
967
- 'done': this.handleL3OrderBook,
968
- 'level2': this.handleLevel2,
969
- 'ticker': this.handleTicker,
970
- 'snapshot.24h': this.handleTicker,
971
- 'match': this.handleTrade,
972
- 'orderChange': this.handleOrder,
973
- 'stopOrder': this.handleOrder,
974
- 'availableBalance.change': this.handleBalance,
975
- 'orderMargin.change': this.handleBalance,
976
- };
977
- const method = this.safeValue(methods, subject);
978
- if (method !== undefined) {
979
- method.call(this, client, message);
980
- }
981
- }
982
- ping(client) {
983
- const id = this.requestId().toString();
984
- return {
985
- 'id': id,
986
- 'type': 'ping',
987
- };
988
- }
989
- handlePong(client, message) {
990
- client.lastPong = this.milliseconds();
991
- return message;
992
- }
993
- handleErrorMessage(client, message) {
994
- //
995
- // {
996
- // "code": 404,
997
- // "data": "tunnel stream-0 is not exist",
998
- // "id": "3",
999
- // "type": "error"
1000
- // }
1001
- //
1002
- client.reject(message);
1003
- }
1004
- handleMessage(client, message) {
1005
- const type = this.safeString(message, 'type');
1006
- const methods = {
1007
- 'welcome': this.handleSystemStatus,
1008
- 'ack': this.handleSubscriptionStatus,
1009
- 'message': this.handleSubject,
1010
- 'pong': this.handlePong,
1011
- 'error': this.handleErrorMessage,
1012
- };
1013
- const method = this.safeValue(methods, type);
1014
- if (method !== undefined) {
1015
- method.call(this, client, message);
1016
- }
1017
- }
1018
- handleAuthenticate(client, message) {
1019
- //
1020
- // {
1021
- // "success": true,
1022
- // "ret_msg": '',
1023
- // "op": "auth",
1024
- // "conn_id": "ce3dpomvha7dha97tvp0-2xh"
1025
- // }
1026
- //
1027
- const data = this.safeValue(message, 'data');
1028
- const success = this.safeValue(data, 'success');
1029
- const messageHash = 'authenticated';
1030
- if (success) {
1031
- client.resolve(message, messageHash);
1032
- }
1033
- else {
1034
- const error = new AuthenticationError(this.id + ' ' + this.json(message));
1035
- client.reject(error, messageHash);
1036
- if (messageHash in client.subscriptions) {
1037
- delete client.subscriptions[messageHash];
1038
- }
1039
- }
1040
- return message;
1041
- }
1042
- }