ccxt 4.2.15 → 4.2.17

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 (46) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +647 -168
  3. package/dist/ccxt.browser.min.js +2 -2
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/js/ccxt.js +3 -1
  6. package/dist/cjs/js/src/ascendex.js +11 -6
  7. package/dist/cjs/js/src/base/Exchange.js +12 -12
  8. package/dist/cjs/js/src/binance.js +1 -0
  9. package/dist/cjs/js/src/bingx.js +37 -3
  10. package/dist/cjs/js/src/bitmex.js +3 -6
  11. package/dist/cjs/js/src/coinlist.js +10 -2
  12. package/dist/cjs/js/src/coinone.js +1 -1
  13. package/dist/cjs/js/src/coinsph.js +2 -2
  14. package/dist/cjs/js/src/phemex.js +28 -25
  15. package/dist/cjs/js/src/pro/binance.js +2 -2
  16. package/dist/cjs/js/src/pro/coinone.js +411 -0
  17. package/dist/cjs/js/src/pro/hitbtc.js +5 -4
  18. package/dist/cjs/js/src/pro/krakenfutures.js +7 -1
  19. package/dist/cjs/js/src/pro/kucoin.js +3 -1
  20. package/dist/cjs/js/src/pro/poloniex.js +2 -2
  21. package/js/ccxt.d.ts +4 -1
  22. package/js/ccxt.js +3 -1
  23. package/js/src/abstract/binance.d.ts +1 -0
  24. package/js/src/abstract/binancecoinm.d.ts +1 -0
  25. package/js/src/abstract/binanceus.d.ts +1 -0
  26. package/js/src/abstract/binanceusdm.d.ts +1 -0
  27. package/js/src/abstract/coinlist.d.ts +8 -0
  28. package/js/src/ascendex.js +11 -6
  29. package/js/src/base/Exchange.js +12 -12
  30. package/js/src/binance.js +1 -0
  31. package/js/src/bingx.d.ts +1 -0
  32. package/js/src/bingx.js +38 -4
  33. package/js/src/bitmex.js +3 -6
  34. package/js/src/coinlist.js +10 -2
  35. package/js/src/coinone.js +1 -1
  36. package/js/src/coinsph.js +2 -2
  37. package/js/src/phemex.js +28 -25
  38. package/js/src/pro/binance.js +2 -2
  39. package/js/src/pro/coinone.d.ts +21 -0
  40. package/js/src/pro/coinone.js +412 -0
  41. package/js/src/pro/hitbtc.js +5 -4
  42. package/js/src/pro/krakenfutures.js +7 -1
  43. package/js/src/pro/kucoin.js +3 -1
  44. package/js/src/pro/poloniex.js +2 -2
  45. package/package.json +1 -1
  46. package/skip-tests.json +1 -0
@@ -0,0 +1,412 @@
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 coinoneRest from '../coinone.js';
9
+ import { AuthenticationError } from '../base/errors.js';
10
+ import { ArrayCache } from '../base/ws/Cache.js';
11
+ // ---------------------------------------------------------------------------
12
+ export default class coinone extends coinoneRest {
13
+ describe() {
14
+ return this.deepExtend(super.describe(), {
15
+ 'has': {
16
+ 'ws': true,
17
+ 'watchOrderBook': true,
18
+ 'watchOrders': false,
19
+ 'watchTrades': true,
20
+ 'watchOHLCV': false,
21
+ 'watchTicker': true,
22
+ 'watchTickers': false,
23
+ },
24
+ 'urls': {
25
+ 'api': {
26
+ 'ws': 'wss://stream.coinone.co.kr',
27
+ },
28
+ },
29
+ 'options': {
30
+ 'expiresIn': '',
31
+ 'userId': '',
32
+ 'wsSessionToken': '',
33
+ 'watchOrderBook': {
34
+ 'snapshotDelay': 6,
35
+ 'snapshotMaxRetries': 3,
36
+ },
37
+ 'tradesLimit': 1000,
38
+ 'OHLCVLimit': 1000,
39
+ },
40
+ 'exceptions': {
41
+ 'exact': {
42
+ '4009': AuthenticationError,
43
+ },
44
+ },
45
+ 'streaming': {
46
+ 'ping': this.ping,
47
+ 'keepAlive': 20000,
48
+ },
49
+ });
50
+ }
51
+ async watchOrderBook(symbol, limit = undefined, params = {}) {
52
+ /**
53
+ * @method
54
+ * @name coinone#watchOrderBook
55
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
56
+ * @see https://docs.coinone.co.kr/reference/public-websocket-orderbook
57
+ * @param {string} symbol unified symbol of the market to fetch the order book for
58
+ * @param {int} [limit] the maximum amount of order book entries to return
59
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
60
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
61
+ */
62
+ await this.loadMarkets();
63
+ const market = this.market(symbol);
64
+ const messageHash = 'orderbook:' + market['symbol'];
65
+ const url = this.urls['api']['ws'];
66
+ const request = {
67
+ 'request_type': 'SUBSCRIBE',
68
+ 'channel': 'ORDERBOOK',
69
+ 'topic': {
70
+ 'quote_currency': market['quote'],
71
+ 'target_currency': market['base'],
72
+ },
73
+ };
74
+ const message = this.extend(request, params);
75
+ const orderbook = await this.watch(url, messageHash, message, messageHash);
76
+ return orderbook.limit();
77
+ }
78
+ handleOrderBook(client, message) {
79
+ //
80
+ // {
81
+ // "response_type": "DATA",
82
+ // "channel": "ORDERBOOK",
83
+ // "data": {
84
+ // "quote_currency": "KRW",
85
+ // "target_currency": "BTC",
86
+ // "timestamp": 1705288918649,
87
+ // "id": "1705288918649001",
88
+ // "asks": [
89
+ // {
90
+ // "price": "58412000",
91
+ // "qty": "0.59919807"
92
+ // }
93
+ // ],
94
+ // "bids": [
95
+ // {
96
+ // "price": "58292000",
97
+ // "qty": "0.1045"
98
+ // }
99
+ // ]
100
+ // }
101
+ // }
102
+ //
103
+ const data = this.safeValue(message, 'data', {});
104
+ const baseId = this.safeStringUpper(data, 'target_currency');
105
+ const quoteId = this.safeStringUpper(data, 'quote_currency');
106
+ const base = this.safeCurrencyCode(baseId);
107
+ const quote = this.safeCurrencyCode(quoteId);
108
+ const symbol = this.symbol(base + '/' + quote);
109
+ const timestamp = this.safeInteger(data, 'timestamp');
110
+ let orderbook = this.safeValue(this.orderbooks, symbol);
111
+ if (orderbook === undefined) {
112
+ orderbook = this.orderBook();
113
+ }
114
+ else {
115
+ orderbook.reset();
116
+ }
117
+ orderbook['symbol'] = symbol;
118
+ const asks = this.safeValue(data, 'asks', []);
119
+ const bids = this.safeValue(data, 'bids', []);
120
+ this.handleDeltas(orderbook['asks'], asks);
121
+ this.handleDeltas(orderbook['bids'], bids);
122
+ orderbook['timestamp'] = timestamp;
123
+ orderbook['datetime'] = this.iso8601(timestamp);
124
+ const messageHash = 'orderbook:' + symbol;
125
+ this.orderbooks[symbol] = orderbook;
126
+ client.resolve(orderbook, messageHash);
127
+ }
128
+ handleDelta(bookside, delta) {
129
+ const bidAsk = this.parseBidAsk(delta, 'price', 'qty');
130
+ bookside.storeArray(bidAsk);
131
+ }
132
+ async watchTicker(symbol, params = {}) {
133
+ /**
134
+ * @method
135
+ * @name coinone#watchTicker
136
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
137
+ * @see https://docs.coinone.co.kr/reference/public-websocket-ticker
138
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
139
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
140
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
141
+ */
142
+ await this.loadMarkets();
143
+ const market = this.market(symbol);
144
+ const messageHash = 'ticker:' + market['symbol'];
145
+ const url = this.urls['api']['ws'];
146
+ const request = {
147
+ 'request_type': 'SUBSCRIBE',
148
+ 'channel': 'TICKER',
149
+ 'topic': {
150
+ 'quote_currency': market['quote'],
151
+ 'target_currency': market['base'],
152
+ },
153
+ };
154
+ const message = this.extend(request, params);
155
+ return await this.watch(url, messageHash, message, messageHash);
156
+ }
157
+ handleTicker(client, message) {
158
+ //
159
+ // {
160
+ // "response_type": "DATA",
161
+ // "channel": "TICKER",
162
+ // "data": {
163
+ // "quote_currency": "KRW",
164
+ // "target_currency": "BTC",
165
+ // "timestamp": 1705301117198,
166
+ // "quote_volume": "19521465345.504",
167
+ // "target_volume": "334.81445168",
168
+ // "high": "58710000",
169
+ // "low": "57276000",
170
+ // "first": "57293000",
171
+ // "last": "58532000",
172
+ // "volume_power": "100",
173
+ // "ask_best_price": "58537000",
174
+ // "ask_best_qty": "0.1961",
175
+ // "bid_best_price": "58532000",
176
+ // "bid_best_qty": "0.00009258",
177
+ // "id": "1705301117198001",
178
+ // "yesterday_high": "59140000",
179
+ // "yesterday_low": "57273000",
180
+ // "yesterday_first": "58897000",
181
+ // "yesterday_last": "57301000",
182
+ // "yesterday_quote_volume": "12967227517.4262",
183
+ // "yesterday_target_volume": "220.09232233"
184
+ // }
185
+ // }
186
+ //
187
+ const data = this.safeValue(message, 'data', {});
188
+ const ticker = this.parseWsTicker(data);
189
+ const symbol = ticker['symbol'];
190
+ this.tickers[symbol] = ticker;
191
+ const messageHash = 'ticker:' + symbol;
192
+ client.resolve(this.tickers[symbol], messageHash);
193
+ }
194
+ parseWsTicker(ticker, market = undefined) {
195
+ //
196
+ // {
197
+ // "quote_currency": "KRW",
198
+ // "target_currency": "BTC",
199
+ // "timestamp": 1705301117198,
200
+ // "quote_volume": "19521465345.504",
201
+ // "target_volume": "334.81445168",
202
+ // "high": "58710000",
203
+ // "low": "57276000",
204
+ // "first": "57293000",
205
+ // "last": "58532000",
206
+ // "volume_power": "100",
207
+ // "ask_best_price": "58537000",
208
+ // "ask_best_qty": "0.1961",
209
+ // "bid_best_price": "58532000",
210
+ // "bid_best_qty": "0.00009258",
211
+ // "id": "1705301117198001",
212
+ // "yesterday_high": "59140000",
213
+ // "yesterday_low": "57273000",
214
+ // "yesterday_first": "58897000",
215
+ // "yesterday_last": "57301000",
216
+ // "yesterday_quote_volume": "12967227517.4262",
217
+ // "yesterday_target_volume": "220.09232233"
218
+ // }
219
+ //
220
+ const timestamp = this.safeInteger(ticker, 'timestamp');
221
+ const last = this.safeString(ticker, 'last');
222
+ const baseId = this.safeString(ticker, 'target_currency');
223
+ const quoteId = this.safeString(ticker, 'quote_currency');
224
+ const base = this.safeCurrencyCode(baseId);
225
+ const quote = this.safeCurrencyCode(quoteId);
226
+ const symbol = this.symbol(base + '/' + quote);
227
+ return this.safeTicker({
228
+ 'symbol': symbol,
229
+ 'timestamp': timestamp,
230
+ 'datetime': this.iso8601(timestamp),
231
+ 'high': this.safeString(ticker, 'high'),
232
+ 'low': this.safeString(ticker, 'low'),
233
+ 'bid': this.safeNumber(ticker, 'bid_best_price'),
234
+ 'bidVolume': this.safeNumber(ticker, 'bid_best_qty'),
235
+ 'ask': this.safeNumber(ticker, 'ask_best_price'),
236
+ 'askVolume': this.safeNumber(ticker, 'ask_best_qty'),
237
+ 'vwap': undefined,
238
+ 'open': this.safeString(ticker, 'first'),
239
+ 'close': last,
240
+ 'last': last,
241
+ 'previousClose': undefined,
242
+ 'change': undefined,
243
+ 'percentage': undefined,
244
+ 'average': undefined,
245
+ 'baseVolume': this.safeString(ticker, 'target_volume'),
246
+ 'quoteVolume': this.safeString(ticker, 'quote_volume'),
247
+ 'info': ticker,
248
+ }, market);
249
+ }
250
+ async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
251
+ /**
252
+ * @method
253
+ * @name coinone#watchTrades
254
+ * @description watches information on multiple trades made in a market
255
+ * @see https://docs.coinone.co.kr/reference/public-websocket-trade
256
+ * @param {string} symbol unified market symbol of the market trades were made in
257
+ * @param {int} [since] the earliest time in ms to fetch trades for
258
+ * @param {int} [limit] the maximum number of trade structures to retrieve
259
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
260
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
261
+ */
262
+ await this.loadMarkets();
263
+ const market = this.market(symbol);
264
+ const messageHash = 'trade:' + market['symbol'];
265
+ const url = this.urls['api']['ws'];
266
+ const request = {
267
+ 'request_type': 'SUBSCRIBE',
268
+ 'channel': 'TRADE',
269
+ 'topic': {
270
+ 'quote_currency': market['quote'],
271
+ 'target_currency': market['base'],
272
+ },
273
+ };
274
+ const message = this.extend(request, params);
275
+ const trades = await this.watch(url, messageHash, message, messageHash);
276
+ if (this.newUpdates) {
277
+ limit = trades.getLimit(market['symbol'], limit);
278
+ }
279
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
280
+ }
281
+ handleTrades(client, message) {
282
+ //
283
+ // {
284
+ // "response_type": "DATA",
285
+ // "channel": "TRADE",
286
+ // "data": {
287
+ // "quote_currency": "KRW",
288
+ // "target_currency": "BTC",
289
+ // "id": "1705303667916001",
290
+ // "timestamp": 1705303667916,
291
+ // "price": "58490000",
292
+ // "qty": "0.0008",
293
+ // "is_seller_maker": false
294
+ // }
295
+ // }
296
+ //
297
+ const data = this.safeValue(message, 'data', {});
298
+ const trade = this.parseWsTrade(data);
299
+ const symbol = trade['symbol'];
300
+ let stored = this.safeValue(this.trades, symbol);
301
+ if (stored === undefined) {
302
+ const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
303
+ stored = new ArrayCache(limit);
304
+ this.trades[symbol] = stored;
305
+ }
306
+ stored.append(trade);
307
+ const messageHash = 'trade:' + symbol;
308
+ client.resolve(stored, messageHash);
309
+ }
310
+ parseWsTrade(trade, market = undefined) {
311
+ //
312
+ // {
313
+ // "quote_currency": "KRW",
314
+ // "target_currency": "BTC",
315
+ // "id": "1705303667916001",
316
+ // "timestamp": 1705303667916,
317
+ // "price": "58490000",
318
+ // "qty": "0.0008",
319
+ // "is_seller_maker": false
320
+ // }
321
+ //
322
+ const baseId = this.safeStringUpper(trade, 'target_currency');
323
+ const quoteId = this.safeStringUpper(trade, 'quote_currency');
324
+ const base = this.safeCurrencyCode(baseId);
325
+ const quote = this.safeCurrencyCode(quoteId);
326
+ const symbol = base + '/' + quote;
327
+ const timestamp = this.safeInteger(trade, 'timestamp');
328
+ market = this.safeMarket(symbol, market);
329
+ const isSellerMaker = this.safeValue(trade, 'is_seller_maker');
330
+ let side = undefined;
331
+ if (isSellerMaker !== undefined) {
332
+ side = isSellerMaker ? 'sell' : 'buy';
333
+ }
334
+ const priceString = this.safeString(trade, 'price');
335
+ const amountString = this.safeString(trade, 'qty');
336
+ return this.safeTrade({
337
+ 'id': this.safeString(trade, 'id'),
338
+ 'info': trade,
339
+ 'timestamp': timestamp,
340
+ 'datetime': this.iso8601(timestamp),
341
+ 'order': undefined,
342
+ 'symbol': market['symbol'],
343
+ 'type': undefined,
344
+ 'side': side,
345
+ 'takerOrMaker': undefined,
346
+ 'price': priceString,
347
+ 'amount': amountString,
348
+ 'cost': undefined,
349
+ 'fee': undefined,
350
+ }, market);
351
+ }
352
+ handleErrorMessage(client, message) {
353
+ //
354
+ // {
355
+ // "response_type": "ERROR",
356
+ // "error_code": 160012,
357
+ // "message": "Invalid Topic"
358
+ // }
359
+ //
360
+ const type = this.safeString(message, 'response_type', '');
361
+ if (type === 'ERROR') {
362
+ return true;
363
+ }
364
+ return false;
365
+ }
366
+ handleMessage(client, message) {
367
+ if (this.handleErrorMessage(client, message)) {
368
+ return;
369
+ }
370
+ const type = this.safeString(message, 'response_type');
371
+ if (type === 'PONG') {
372
+ this.handlePong(client, message);
373
+ return;
374
+ }
375
+ if (type === 'DATA') {
376
+ const topic = this.safeString(message, 'channel', '');
377
+ const methods = {
378
+ 'ORDERBOOK': this.handleOrderBook,
379
+ 'TICKER': this.handleTicker,
380
+ 'TRADE': this.handleTrades,
381
+ };
382
+ const exacMethod = this.safeValue(methods, topic);
383
+ if (exacMethod !== undefined) {
384
+ exacMethod.call(this, client, message);
385
+ return;
386
+ }
387
+ const keys = Object.keys(methods);
388
+ for (let i = 0; i < keys.length; i++) {
389
+ const key = keys[i];
390
+ if (topic.indexOf(keys[i]) >= 0) {
391
+ const method = methods[key];
392
+ method.call(this, client, message);
393
+ return;
394
+ }
395
+ }
396
+ }
397
+ }
398
+ ping(client) {
399
+ return {
400
+ 'request_type': 'PING',
401
+ };
402
+ }
403
+ handlePong(client, message) {
404
+ //
405
+ // {
406
+ // "response_type":"PONG"
407
+ // }
408
+ //
409
+ client.lastPong = this.milliseconds();
410
+ return message;
411
+ }
412
+ }
@@ -310,7 +310,8 @@ export default class hitbtc extends hitbtcRest {
310
310
  'symbols': [market['id']],
311
311
  },
312
312
  };
313
- return await this.subscribePublic(name, [symbol], this.deepExtend(request, params));
313
+ const result = await this.subscribePublic(name, [symbol], this.deepExtend(request, params));
314
+ return this.safeValue(result, symbol);
314
315
  }
315
316
  async watchTickers(symbols = undefined, params = {}) {
316
317
  /**
@@ -393,16 +394,16 @@ export default class hitbtc extends hitbtcRest {
393
394
  const data = this.safeValue(message, 'data', {});
394
395
  const marketIds = Object.keys(data);
395
396
  const channel = this.safeString(message, 'ch');
396
- const newTickers = [];
397
+ const newTickers = {};
397
398
  for (let i = 0; i < marketIds.length; i++) {
398
399
  const marketId = marketIds[i];
399
400
  const market = this.safeMarket(marketId);
400
401
  const symbol = market['symbol'];
401
402
  const ticker = this.parseWsTicker(data[marketId], market);
402
403
  this.tickers[symbol] = ticker;
403
- newTickers.push(ticker);
404
+ newTickers[symbol] = ticker;
404
405
  const messageHash = channel + '::' + symbol;
405
- client.resolve(this.tickers[symbol], messageHash);
406
+ client.resolve(newTickers, messageHash);
406
407
  }
407
408
  const messageHashes = this.findMessageHashes(client, channel + '::');
408
409
  for (let i = 0; i < messageHashes.length; i++) {
@@ -181,7 +181,13 @@ export default class krakenfutures extends krakenfuturesRest {
181
181
  const name = this.safeString2(params, 'method', 'watchTickerMethod', method);
182
182
  params = this.omit(params, ['watchTickerMethod', 'method']);
183
183
  symbols = this.marketSymbols(symbols, undefined, false);
184
- return await this.subscribePublic(name, symbols, params);
184
+ const ticker = await this.subscribePublic(name, symbols, params);
185
+ if (this.newUpdates) {
186
+ const tickers = {};
187
+ tickers[ticker['symbol']] = ticker;
188
+ return tickers;
189
+ }
190
+ return this.filterByArray(this.tickers, 'symbol', symbols);
185
191
  }
186
192
  async watchTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
187
193
  /**
@@ -261,7 +261,9 @@ export default class kucoin extends kucoinRest {
261
261
  const messageHash = 'ticker:' + symbol;
262
262
  client.resolve(ticker, messageHash);
263
263
  // watchTickers
264
- client.resolve(ticker, 'tickers');
264
+ const allTickers = {};
265
+ allTickers[symbol] = ticker;
266
+ client.resolve(allTickers, 'tickers');
265
267
  const messageHashes = this.findMessageHashes(client, 'tickers::');
266
268
  for (let i = 0; i < messageHashes.length; i++) {
267
269
  const currentMessageHash = messageHashes[i];
@@ -943,7 +943,7 @@ export default class poloniex extends poloniexRest {
943
943
  // }
944
944
  //
945
945
  const data = this.safeValue(message, 'data', []);
946
- const newTickers = [];
946
+ const newTickers = {};
947
947
  for (let i = 0; i < data.length; i++) {
948
948
  const item = data[i];
949
949
  const marketId = this.safeString(item, 'symbol');
@@ -951,7 +951,7 @@ export default class poloniex extends poloniexRest {
951
951
  const ticker = this.parseTicker(item);
952
952
  const symbol = ticker['symbol'];
953
953
  this.tickers[symbol] = ticker;
954
- newTickers.push(ticker);
954
+ newTickers[symbol] = ticker;
955
955
  }
956
956
  }
957
957
  const messageHashes = this.findMessageHashes(client, 'ticker::');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.2.15",
3
+ "version": "4.2.17",
4
4
  "description": "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges",
5
5
  "unpkg": "dist/ccxt.browser.js",
6
6
  "type": "module",
package/skip-tests.json CHANGED
@@ -674,6 +674,7 @@
674
674
  }
675
675
  },
676
676
  "coinone": {
677
+ "skipWs": true,
677
678
  "skipMethods": {
678
679
  "loadMarkets": {
679
680
  "active":"is undefined"