ccxt 4.2.81 → 4.2.83

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 (131) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/README.md +4 -4
  3. package/dist/ccxt.browser.js +1085 -188
  4. package/dist/ccxt.browser.min.js +2 -2
  5. package/dist/cjs/ccxt.js +3 -1
  6. package/dist/cjs/src/bitget.js +1 -0
  7. package/dist/cjs/src/bithumb.js +1 -0
  8. package/dist/cjs/src/bitstamp.js +42 -15
  9. package/dist/cjs/src/delta.js +147 -0
  10. package/dist/cjs/src/deribit.js +20 -2
  11. package/dist/cjs/src/gemini.js +2 -1
  12. package/dist/cjs/src/hyperliquid.js +9 -8
  13. package/dist/cjs/src/kucoinfutures.js +147 -8
  14. package/dist/cjs/src/okx.js +139 -0
  15. package/dist/cjs/src/pro/bithumb.js +388 -0
  16. package/dist/cjs/src/pro/bitmart.js +1 -1
  17. package/dist/cjs/src/pro/bybit.js +1 -1
  18. package/dist/cjs/src/pro/cex.js +18 -5
  19. package/dist/cjs/src/pro/okx.js +2 -1
  20. package/dist/cjs/src/pro/p2b.js +14 -4
  21. package/dist/cjs/src/pro/woo.js +1 -1
  22. package/js/ccxt.d.ts +4 -1
  23. package/js/ccxt.js +3 -1
  24. package/js/src/abstract/bitstamp.d.ts +1 -1
  25. package/js/src/ace.d.ts +1 -1
  26. package/js/src/alpaca.d.ts +1 -1
  27. package/js/src/ascendex.d.ts +1 -1
  28. package/js/src/bigone.d.ts +1 -1
  29. package/js/src/binance.d.ts +1 -1
  30. package/js/src/bingx.d.ts +1 -1
  31. package/js/src/bitbank.d.ts +1 -1
  32. package/js/src/bitbns.d.ts +1 -1
  33. package/js/src/bitfinex.d.ts +1 -1
  34. package/js/src/bitfinex2.d.ts +1 -1
  35. package/js/src/bitflyer.d.ts +1 -1
  36. package/js/src/bitget.d.ts +1 -1
  37. package/js/src/bitget.js +1 -0
  38. package/js/src/bithumb.d.ts +1 -1
  39. package/js/src/bithumb.js +1 -0
  40. package/js/src/bitmart.d.ts +1 -1
  41. package/js/src/bitmex.d.ts +1 -1
  42. package/js/src/bitopro.d.ts +1 -1
  43. package/js/src/bitrue.d.ts +1 -1
  44. package/js/src/bitso.d.ts +1 -1
  45. package/js/src/bitstamp.d.ts +1 -1
  46. package/js/src/bitstamp.js +42 -15
  47. package/js/src/bitteam.d.ts +1 -1
  48. package/js/src/bitvavo.d.ts +1 -1
  49. package/js/src/blockchaincom.d.ts +1 -1
  50. package/js/src/blofin.d.ts +1 -1
  51. package/js/src/btcalpha.d.ts +1 -1
  52. package/js/src/btcmarkets.d.ts +1 -1
  53. package/js/src/btcturk.d.ts +1 -1
  54. package/js/src/bybit.d.ts +1 -1
  55. package/js/src/cex.d.ts +1 -1
  56. package/js/src/coinbase.d.ts +1 -1
  57. package/js/src/coinbaseinternational.d.ts +1 -1
  58. package/js/src/coinbasepro.d.ts +1 -1
  59. package/js/src/coinex.d.ts +1 -1
  60. package/js/src/coinlist.d.ts +1 -1
  61. package/js/src/coinmate.d.ts +1 -1
  62. package/js/src/coinmetro.d.ts +1 -1
  63. package/js/src/coinone.d.ts +1 -1
  64. package/js/src/coinsph.d.ts +1 -1
  65. package/js/src/cryptocom.d.ts +1 -1
  66. package/js/src/currencycom.d.ts +1 -1
  67. package/js/src/delta.d.ts +22 -2
  68. package/js/src/delta.js +147 -0
  69. package/js/src/deribit.d.ts +2 -2
  70. package/js/src/deribit.js +20 -2
  71. package/js/src/digifinex.d.ts +1 -1
  72. package/js/src/exmo.d.ts +1 -1
  73. package/js/src/gate.d.ts +1 -1
  74. package/js/src/gemini.d.ts +1 -1
  75. package/js/src/gemini.js +2 -1
  76. package/js/src/hitbtc.d.ts +1 -1
  77. package/js/src/hollaex.d.ts +1 -1
  78. package/js/src/htx.d.ts +1 -1
  79. package/js/src/huobijp.d.ts +1 -1
  80. package/js/src/hyperliquid.d.ts +1 -1
  81. package/js/src/hyperliquid.js +9 -8
  82. package/js/src/idex.d.ts +1 -1
  83. package/js/src/independentreserve.d.ts +1 -1
  84. package/js/src/indodax.d.ts +1 -1
  85. package/js/src/kraken.d.ts +1 -1
  86. package/js/src/krakenfutures.d.ts +1 -1
  87. package/js/src/kucoin.d.ts +1 -1
  88. package/js/src/kucoinfutures.d.ts +3 -2
  89. package/js/src/kucoinfutures.js +147 -8
  90. package/js/src/kuna.d.ts +1 -1
  91. package/js/src/latoken.d.ts +1 -1
  92. package/js/src/lbank.d.ts +1 -1
  93. package/js/src/luno.d.ts +1 -1
  94. package/js/src/lykke.d.ts +1 -1
  95. package/js/src/mercado.d.ts +1 -1
  96. package/js/src/mexc.d.ts +1 -1
  97. package/js/src/ndax.d.ts +1 -1
  98. package/js/src/novadax.d.ts +1 -1
  99. package/js/src/oceanex.d.ts +1 -1
  100. package/js/src/okcoin.d.ts +1 -1
  101. package/js/src/okx.d.ts +23 -2
  102. package/js/src/okx.js +139 -0
  103. package/js/src/onetrading.d.ts +1 -1
  104. package/js/src/p2b.d.ts +1 -1
  105. package/js/src/phemex.d.ts +1 -1
  106. package/js/src/poloniex.d.ts +1 -1
  107. package/js/src/poloniexfutures.d.ts +1 -1
  108. package/js/src/pro/bithumb.d.ts +19 -0
  109. package/js/src/pro/bithumb.js +389 -0
  110. package/js/src/pro/bitmart.js +1 -1
  111. package/js/src/pro/bybit.js +1 -1
  112. package/js/src/pro/cex.js +18 -5
  113. package/js/src/pro/okx.js +2 -1
  114. package/js/src/pro/p2b.d.ts +2 -0
  115. package/js/src/pro/p2b.js +14 -4
  116. package/js/src/pro/woo.js +1 -1
  117. package/js/src/probit.d.ts +1 -1
  118. package/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.d.ts +1 -1
  119. package/js/src/timex.d.ts +1 -1
  120. package/js/src/tokocrypto.d.ts +1 -1
  121. package/js/src/tradeogre.d.ts +1 -1
  122. package/js/src/upbit.d.ts +1 -1
  123. package/js/src/wavesexchange.d.ts +1 -1
  124. package/js/src/wazirx.d.ts +1 -1
  125. package/js/src/whitebit.d.ts +1 -1
  126. package/js/src/woo.d.ts +1 -1
  127. package/js/src/yobit.d.ts +1 -1
  128. package/js/src/zaif.d.ts +1 -1
  129. package/js/src/zonda.d.ts +1 -1
  130. package/package.json +1 -1
  131. package/skip-tests.json +17 -4
@@ -94,6 +94,8 @@ class okx extends okx$1 {
94
94
  'fetchOpenInterestHistory': true,
95
95
  'fetchOpenOrder': undefined,
96
96
  'fetchOpenOrders': true,
97
+ 'fetchOption': true,
98
+ 'fetchOptionChain': true,
97
99
  'fetchOrder': true,
98
100
  'fetchOrderBook': true,
99
101
  'fetchOrderBooks': false,
@@ -7410,6 +7412,143 @@ class okx extends okx$1 {
7410
7412
  const order = this.safeValue(data, 0);
7411
7413
  return this.parseOrder(order, market);
7412
7414
  }
7415
+ async fetchOption(symbol, params = {}) {
7416
+ /**
7417
+ * @method
7418
+ * @name okx#fetchOption
7419
+ * @description fetches option data that is commonly found in an option chain
7420
+ * @see https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-ticker
7421
+ * @param {string} symbol unified market symbol
7422
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
7423
+ * @returns {object} an [option chain structure]{@link https://docs.ccxt.com/#/?id=option-chain-structure}
7424
+ */
7425
+ await this.loadMarkets();
7426
+ const market = this.market(symbol);
7427
+ const request = {
7428
+ 'instId': market['id'],
7429
+ };
7430
+ const response = await this.publicGetMarketTicker(this.extend(request, params));
7431
+ //
7432
+ // {
7433
+ // "code": "0",
7434
+ // "msg": "",
7435
+ // "data": [
7436
+ // {
7437
+ // "instType": "OPTION",
7438
+ // "instId": "BTC-USD-241227-60000-P",
7439
+ // "last": "",
7440
+ // "lastSz": "0",
7441
+ // "askPx": "",
7442
+ // "askSz": "0",
7443
+ // "bidPx": "",
7444
+ // "bidSz": "0",
7445
+ // "open24h": "",
7446
+ // "high24h": "",
7447
+ // "low24h": "",
7448
+ // "volCcy24h": "0",
7449
+ // "vol24h": "0",
7450
+ // "ts": "1711176035035",
7451
+ // "sodUtc0": "",
7452
+ // "sodUtc8": ""
7453
+ // }
7454
+ // ]
7455
+ // }
7456
+ //
7457
+ const result = this.safeList(response, 'data', []);
7458
+ const chain = this.safeDict(result, 0, {});
7459
+ return this.parseOption(chain, undefined, market);
7460
+ }
7461
+ async fetchOptionChain(code, params = {}) {
7462
+ /**
7463
+ * @method
7464
+ * @name okx#fetchOptionChain
7465
+ * @description fetches data for an underlying asset that is commonly found in an option chain
7466
+ * @see https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-tickers
7467
+ * @param {string} currency base currency to fetch an option chain for
7468
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
7469
+ * @param {string} [params.uly] the underlying asset, can be obtained from fetchUnderlyingAssets ()
7470
+ * @returns {object} a list of [option chain structures]{@link https://docs.ccxt.com/#/?id=option-chain-structure}
7471
+ */
7472
+ await this.loadMarkets();
7473
+ const currency = this.currency(code);
7474
+ const request = {
7475
+ 'uly': currency['code'] + '-USD',
7476
+ 'instType': 'OPTION',
7477
+ };
7478
+ const response = await this.publicGetMarketTickers(this.extend(request, params));
7479
+ //
7480
+ // {
7481
+ // "code": "0",
7482
+ // "msg": "",
7483
+ // "data": [
7484
+ // {
7485
+ // "instType": "OPTION",
7486
+ // "instId": "BTC-USD-240323-52000-C",
7487
+ // "last": "",
7488
+ // "lastSz": "0",
7489
+ // "askPx": "",
7490
+ // "askSz": "0",
7491
+ // "bidPx": "",
7492
+ // "bidSz": "0",
7493
+ // "open24h": "",
7494
+ // "high24h": "",
7495
+ // "low24h": "",
7496
+ // "volCcy24h": "0",
7497
+ // "vol24h": "0",
7498
+ // "ts": "1711176207008",
7499
+ // "sodUtc0": "",
7500
+ // "sodUtc8": ""
7501
+ // },
7502
+ // ]
7503
+ // }
7504
+ //
7505
+ const result = this.safeList(response, 'data', []);
7506
+ return this.parseOptionChain(result, undefined, 'instId');
7507
+ }
7508
+ parseOption(chain, currency = undefined, market = undefined) {
7509
+ //
7510
+ // {
7511
+ // "instType": "OPTION",
7512
+ // "instId": "BTC-USD-241227-60000-P",
7513
+ // "last": "",
7514
+ // "lastSz": "0",
7515
+ // "askPx": "",
7516
+ // "askSz": "0",
7517
+ // "bidPx": "",
7518
+ // "bidSz": "0",
7519
+ // "open24h": "",
7520
+ // "high24h": "",
7521
+ // "low24h": "",
7522
+ // "volCcy24h": "0",
7523
+ // "vol24h": "0",
7524
+ // "ts": "1711176035035",
7525
+ // "sodUtc0": "",
7526
+ // "sodUtc8": ""
7527
+ // }
7528
+ //
7529
+ const marketId = this.safeString(chain, 'instId');
7530
+ market = this.safeMarket(marketId, market);
7531
+ const timestamp = this.safeInteger(chain, 'ts');
7532
+ return {
7533
+ 'info': chain,
7534
+ 'currency': undefined,
7535
+ 'symbol': market['symbol'],
7536
+ 'timestamp': timestamp,
7537
+ 'datetime': this.iso8601(timestamp),
7538
+ 'impliedVolatility': undefined,
7539
+ 'openInterest': undefined,
7540
+ 'bidPrice': this.safeNumber(chain, 'bidPx'),
7541
+ 'askPrice': this.safeNumber(chain, 'askPx'),
7542
+ 'midPrice': undefined,
7543
+ 'markPrice': undefined,
7544
+ 'lastPrice': this.safeNumber(chain, 'last'),
7545
+ 'underlyingPrice': undefined,
7546
+ 'change': undefined,
7547
+ 'percentage': undefined,
7548
+ 'baseVolume': this.safeNumber(chain, 'volCcy24h'),
7549
+ 'quoteVolume': undefined,
7550
+ };
7551
+ }
7413
7552
  handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
7414
7553
  if (!response) {
7415
7554
  return undefined; // fallback to default error handler
@@ -0,0 +1,388 @@
1
+ 'use strict';
2
+
3
+ var bithumb$1 = require('../bithumb.js');
4
+ var Cache = require('../base/ws/Cache.js');
5
+ var errors = require('../base/errors.js');
6
+
7
+ // ---------------------------------------------------------------------------
8
+ // ---------------------------------------------------------------------------
9
+ class bithumb extends bithumb$1 {
10
+ describe() {
11
+ return this.deepExtend(super.describe(), {
12
+ 'has': {
13
+ 'ws': true,
14
+ 'watchBalance': false,
15
+ 'watchTicker': true,
16
+ 'watchTickers': true,
17
+ 'watchTrades': true,
18
+ 'watchOrderBook': true,
19
+ 'watchOHLCV': false,
20
+ },
21
+ 'urls': {
22
+ 'api': {
23
+ 'ws': 'wss://pubwss.bithumb.com/pub/ws',
24
+ },
25
+ },
26
+ 'options': {},
27
+ 'streaming': {},
28
+ 'exceptions': {},
29
+ });
30
+ }
31
+ async watchTicker(symbol, params = {}) {
32
+ /**
33
+ * @method
34
+ * @name bithumb#watchTicker
35
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
36
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
37
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
38
+ * @param {string} [params.channel] the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
39
+ * @returns {object} a [ticker structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#ticker-structure}
40
+ */
41
+ const url = this.urls['api']['ws'];
42
+ await this.loadMarkets();
43
+ const market = this.market(symbol);
44
+ const messageHash = 'ticker:' + market['symbol'];
45
+ const request = {
46
+ 'type': 'ticker',
47
+ 'symbols': [market['base'] + '_' + market['quote']],
48
+ 'tickTypes': [this.safeString(params, 'tickTypes', '24H')],
49
+ };
50
+ return await this.watch(url, messageHash, this.extend(request, params), messageHash);
51
+ }
52
+ async watchTickers(symbols = undefined, params = {}) {
53
+ /**
54
+ * @method
55
+ * @name binance#watchTickers
56
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
57
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
58
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
59
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
60
+ */
61
+ await this.loadMarkets();
62
+ const url = this.urls['api']['ws'];
63
+ const marketIds = [];
64
+ const messageHashes = [];
65
+ symbols = this.marketSymbols(symbols, undefined, false, true, true);
66
+ for (let i = 0; i < symbols.length; i++) {
67
+ const symbol = symbols[i];
68
+ const market = this.market(symbol);
69
+ marketIds.push(market['base'] + '_' + market['quote']);
70
+ messageHashes.push('ticker:' + market['symbol']);
71
+ }
72
+ const request = {
73
+ 'type': 'ticker',
74
+ 'symbols': marketIds,
75
+ 'tickTypes': [this.safeString(params, 'tickTypes', '24H')],
76
+ };
77
+ const message = this.extend(request, params);
78
+ const newTicker = await this.watchMultiple(url, messageHashes, message, messageHashes);
79
+ if (this.newUpdates) {
80
+ const result = {};
81
+ result[newTicker['symbol']] = newTicker;
82
+ return result;
83
+ }
84
+ return this.filterByArray(this.tickers, 'symbol', symbols);
85
+ }
86
+ handleTicker(client, message) {
87
+ //
88
+ // {
89
+ // "type" : "ticker",
90
+ // "content" : {
91
+ // "symbol" : "BTC_KRW", // 통화코드
92
+ // "tickType" : "24H", // 변동 기준시간- 30M, 1H, 12H, 24H, MID
93
+ // "date" : "20200129", // 일자
94
+ // "time" : "121844", // 시간
95
+ // "openPrice" : "2302", // 시가
96
+ // "closePrice" : "2317", // 종가
97
+ // "lowPrice" : "2272", // 저가
98
+ // "highPrice" : "2344", // 고가
99
+ // "value" : "2831915078.07065789", // 누적거래금액
100
+ // "volume" : "1222314.51355788", // 누적거래량
101
+ // "sellVolume" : "760129.34079004", // 매도누적거래량
102
+ // "buyVolume" : "462185.17276784", // 매수누적거래량
103
+ // "prevClosePrice" : "2326", // 전일종가
104
+ // "chgRate" : "0.65", // 변동률
105
+ // "chgAmt" : "15", // 변동금액
106
+ // "volumePower" : "60.80" // 체결강도
107
+ // }
108
+ // }
109
+ //
110
+ const content = this.safeDict(message, 'content', {});
111
+ const marketId = this.safeString(content, 'symbol');
112
+ const symbol = this.safeSymbol(marketId, undefined, '_');
113
+ const ticker = this.parseWsTicker(content);
114
+ const messageHash = 'ticker:' + symbol;
115
+ this.tickers[symbol] = ticker;
116
+ client.resolve(this.tickers[symbol], messageHash);
117
+ }
118
+ parseWsTicker(ticker, market = undefined) {
119
+ //
120
+ // {
121
+ // "symbol" : "BTC_KRW", // 통화코드
122
+ // "tickType" : "24H", // 변동 기준시간- 30M, 1H, 12H, 24H, MID
123
+ // "date" : "20200129", // 일자
124
+ // "time" : "121844", // 시간
125
+ // "openPrice" : "2302", // 시가
126
+ // "closePrice" : "2317", // 종가
127
+ // "lowPrice" : "2272", // 저가
128
+ // "highPrice" : "2344", // 고가
129
+ // "value" : "2831915078.07065789", // 누적거래금액
130
+ // "volume" : "1222314.51355788", // 누적거래량
131
+ // "sellVolume" : "760129.34079004", // 매도누적거래량
132
+ // "buyVolume" : "462185.17276784", // 매수누적거래량
133
+ // "prevClosePrice" : "2326", // 전일종가
134
+ // "chgRate" : "0.65", // 변동률
135
+ // "chgAmt" : "15", // 변동금액
136
+ // "volumePower" : "60.80" // 체결강도
137
+ // }
138
+ //
139
+ const date = this.safeString(ticker, 'date', '');
140
+ const time = this.safeString(ticker, 'time', '');
141
+ const datetime = date.slice(0, 4) + '-' + date.slice(4, 6) + '-' + date.slice(6, 8) + 'T' + time.slice(0, 2) + ':' + time.slice(2, 4) + ':' + time.slice(4, 6);
142
+ const marketId = this.safeString(ticker, 'symbol');
143
+ return this.safeTicker({
144
+ 'symbol': this.safeSymbol(marketId, market, '_'),
145
+ 'timestamp': this.parse8601(datetime),
146
+ 'datetime': datetime,
147
+ 'high': this.safeString(ticker, 'highPrice'),
148
+ 'low': this.safeString(ticker, 'lowPrice'),
149
+ 'bid': undefined,
150
+ 'bidVolume': this.safeString(ticker, 'buyVolume'),
151
+ 'ask': undefined,
152
+ 'askVolume': this.safeString(ticker, 'sellVolume'),
153
+ 'vwap': undefined,
154
+ 'open': this.safeString(ticker, 'openPrice'),
155
+ 'close': this.safeString(ticker, 'closePrice'),
156
+ 'last': undefined,
157
+ 'previousClose': this.safeString(ticker, 'prevClosePrice'),
158
+ 'change': this.safeString(ticker, 'chgAmt'),
159
+ 'percentage': this.safeString(ticker, 'chgRate'),
160
+ 'average': undefined,
161
+ 'baseVolume': this.safeString(ticker, 'volume'),
162
+ 'quoteVolume': this.safeString(ticker, 'value'),
163
+ 'info': ticker,
164
+ }, market);
165
+ }
166
+ async watchOrderBook(symbol, limit = undefined, params = {}) {
167
+ /**
168
+ * @method
169
+ * @name bithumb#watchOrderBook
170
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
171
+ * @param {string} symbol unified symbol of the market to fetch the order book for
172
+ * @param {int} [limit] the maximum amount of order book entries to return
173
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
174
+ * @returns {object} A dictionary of [order book structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-book-structure} indexed by market symbols
175
+ */
176
+ await this.loadMarkets();
177
+ const url = this.urls['api']['ws'];
178
+ const market = this.market(symbol);
179
+ symbol = market['symbol'];
180
+ const messageHash = 'orderbook' + ':' + symbol;
181
+ const request = {
182
+ 'type': 'orderbookdepth',
183
+ 'symbols': [market['base'] + '_' + market['quote']],
184
+ };
185
+ const orderbook = await this.watch(url, messageHash, this.extend(request, params), messageHash);
186
+ return orderbook.limit();
187
+ }
188
+ handleOrderBook(client, message) {
189
+ //
190
+ // {
191
+ // "type" : "orderbookdepth",
192
+ // "content" : {
193
+ // "list" : [
194
+ // {
195
+ // "symbol" : "BTC_KRW",
196
+ // "orderType" : "ask", // 주문타입 – bid / ask
197
+ // "price" : "10593000", // 호가
198
+ // "quantity" : "1.11223318", // 잔량
199
+ // "total" : "3" // 건수
200
+ // },
201
+ // {"symbol" : "BTC_KRW", "orderType" : "ask", "price" : "10596000", "quantity" : "0.5495", "total" : "8"},
202
+ // {"symbol" : "BTC_KRW", "orderType" : "ask", "price" : "10598000", "quantity" : "18.2085", "total" : "10"},
203
+ // {"symbol" : "BTC_KRW", "orderType" : "bid", "price" : "10532000", "quantity" : "0", "total" : "0"},
204
+ // {"symbol" : "BTC_KRW", "orderType" : "bid", "price" : "10572000", "quantity" : "2.3324", "total" : "4"},
205
+ // {"symbol" : "BTC_KRW", "orderType" : "bid", "price" : "10571000", "quantity" : "1.469", "total" : "3"},
206
+ // {"symbol" : "BTC_KRW", "orderType" : "bid", "price" : "10569000", "quantity" : "0.5152", "total" : "2"}
207
+ // ],
208
+ // "datetime":1580268255864325 // 일시
209
+ // }
210
+ // }
211
+ //
212
+ const content = this.safeDict(message, 'content', {});
213
+ const list = this.safeList(content, 'list', []);
214
+ const first = this.safeDict(list, 0, {});
215
+ const marketId = this.safeString(first, 'symbol');
216
+ const symbol = this.safeSymbol(marketId, undefined, '_');
217
+ const timestampStr = this.safeString(content, 'datetime');
218
+ const timestamp = this.parseToInt(timestampStr.slice(0, 13));
219
+ if (!(symbol in this.orderbooks)) {
220
+ const ob = this.orderBook();
221
+ ob['symbol'] = symbol;
222
+ this.orderbooks[symbol] = ob;
223
+ }
224
+ const orderbook = this.orderbooks[symbol];
225
+ this.handleDeltas(orderbook, list);
226
+ orderbook['timestamp'] = timestamp;
227
+ orderbook['datetime'] = this.iso8601(timestamp);
228
+ const messageHash = 'orderbook' + ':' + symbol;
229
+ client.resolve(orderbook, messageHash);
230
+ }
231
+ handleDelta(orderbook, delta) {
232
+ //
233
+ // {
234
+ // symbol: "ETH_BTC",
235
+ // orderType: "bid",
236
+ // price: "0.07349517",
237
+ // quantity: "0",
238
+ // total: "0",
239
+ // }
240
+ //
241
+ const sideId = this.safeString(delta, 'orderType');
242
+ const side = (sideId === 'bid') ? 'bids' : 'asks';
243
+ const bidAsk = this.parseBidAsk(delta, 'price', 'quantity');
244
+ const orderbookSide = orderbook[side];
245
+ orderbookSide.storeArray(bidAsk);
246
+ }
247
+ handleDeltas(orderbook, deltas) {
248
+ for (let i = 0; i < deltas.length; i++) {
249
+ this.handleDelta(orderbook, deltas[i]);
250
+ }
251
+ }
252
+ async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
253
+ /**
254
+ * @method
255
+ * @name bithumb#watchTrades
256
+ * @description get the list of most recent trades for a particular symbol
257
+ * @param {string} symbol unified symbol of the market to fetch trades for
258
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
259
+ * @param {int} [limit] the maximum amount of trades to fetch
260
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
261
+ * @returns {object[]} a list of [trade structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#public-trades}
262
+ */
263
+ await this.loadMarkets();
264
+ const url = this.urls['api']['ws'];
265
+ const market = this.market(symbol);
266
+ symbol = market['symbol'];
267
+ const messageHash = 'trade:' + symbol;
268
+ const request = {
269
+ 'type': 'transaction',
270
+ 'symbols': [market['base'] + '_' + market['quote']],
271
+ };
272
+ const trades = await this.watch(url, messageHash, this.extend(request, params), messageHash);
273
+ if (this.newUpdates) {
274
+ limit = trades.getLimit(symbol, limit);
275
+ }
276
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
277
+ }
278
+ handleTrades(client, message) {
279
+ //
280
+ // {
281
+ // "type" : "transaction",
282
+ // "content" : {
283
+ // "list" : [
284
+ // {
285
+ // "symbol" : "BTC_KRW",
286
+ // "buySellGb" : "1",
287
+ // "contPrice" : "10579000",
288
+ // "contQty" : "0.01",
289
+ // "contAmt" : "105790.00",
290
+ // "contDtm" : "2020-01-29 12:24:18.830039",
291
+ // "updn" : "dn"
292
+ // }
293
+ // ]
294
+ // }
295
+ // }
296
+ //
297
+ const content = this.safeDict(message, 'content', {});
298
+ const rawTrades = this.safeList(content, 'list', []);
299
+ for (let i = 0; i < rawTrades.length; i++) {
300
+ const rawTrade = rawTrades[i];
301
+ const marketId = this.safeString(rawTrade, 'symbol');
302
+ const symbol = this.safeSymbol(marketId, undefined, '_');
303
+ if (!(symbol in this.trades)) {
304
+ const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
305
+ const stored = new Cache.ArrayCache(limit);
306
+ this.trades[symbol] = stored;
307
+ }
308
+ const trades = this.trades[symbol];
309
+ const parsed = this.parseWsTrade(rawTrade);
310
+ trades.append(parsed);
311
+ const messageHash = 'trade' + ':' + symbol;
312
+ client.resolve(trades, messageHash);
313
+ }
314
+ }
315
+ parseWsTrade(trade, market = undefined) {
316
+ //
317
+ // {
318
+ // "symbol" : "BTC_KRW",
319
+ // "buySellGb" : "1",
320
+ // "contPrice" : "10579000",
321
+ // "contQty" : "0.01",
322
+ // "contAmt" : "105790.00",
323
+ // "contDtm" : "2020-01-29 12:24:18.830039",
324
+ // "updn" : "dn"
325
+ // }
326
+ //
327
+ const marketId = this.safeString(trade, 'symbol');
328
+ const datetime = this.safeString(trade, 'contDtm');
329
+ const sideId = this.safeString(trade, 'buySellGb');
330
+ return this.safeTrade({
331
+ 'id': undefined,
332
+ 'info': trade,
333
+ 'timestamp': this.parse8601(datetime),
334
+ 'datetime': datetime,
335
+ 'symbol': this.safeSymbol(marketId, market, '_'),
336
+ 'order': undefined,
337
+ 'type': undefined,
338
+ 'side': (sideId === '1') ? 'buy' : 'sell',
339
+ 'takerOrMaker': undefined,
340
+ 'price': this.safeString(trade, 'contPrice'),
341
+ 'amount': this.safeString(trade, 'contQty'),
342
+ 'cost': this.safeString(trade, 'contAmt'),
343
+ 'fee': undefined,
344
+ }, market);
345
+ }
346
+ handleErrorMessage(client, message) {
347
+ //
348
+ // {
349
+ // "status" : "5100",
350
+ // "resmsg" : "Invalid Filter Syntax"
351
+ // }
352
+ //
353
+ if (!('status' in message)) {
354
+ return true;
355
+ }
356
+ const errorCode = this.safeString(message, 'status');
357
+ try {
358
+ if (errorCode !== '0000') {
359
+ const msg = this.safeString(message, 'resmsg');
360
+ throw new errors.ExchangeError(this.id + ' ' + msg);
361
+ }
362
+ return true;
363
+ }
364
+ catch (e) {
365
+ client.reject(e);
366
+ }
367
+ return true;
368
+ }
369
+ handleMessage(client, message) {
370
+ if (!this.handleErrorMessage(client, message)) {
371
+ return;
372
+ }
373
+ const topic = this.safeString(message, 'type');
374
+ if (topic !== undefined) {
375
+ const methods = {
376
+ 'ticker': this.handleTicker,
377
+ 'orderbookdepth': this.handleOrderBook,
378
+ 'transaction': this.handleTrades,
379
+ };
380
+ const method = this.safeValue(methods, topic);
381
+ if (method !== undefined) {
382
+ method.call(this, client, message);
383
+ }
384
+ }
385
+ }
386
+ }
387
+
388
+ module.exports = bithumb;
@@ -704,10 +704,10 @@ class bitmart extends bitmart$1 {
704
704
  // }
705
705
  //
706
706
  const data = this.safeValue(message, 'data', []);
707
- const cache = this.positions;
708
707
  if (this.positions === undefined) {
709
708
  this.positions = new Cache.ArrayCacheBySymbolBySide();
710
709
  }
710
+ const cache = this.positions;
711
711
  const newPositions = [];
712
712
  for (let i = 0; i < data.length; i++) {
713
713
  const rawPosition = data[i];
@@ -199,7 +199,7 @@ class bybit extends bybit$1 {
199
199
  /**
200
200
  * @method
201
201
  * @name bybit#watchTickers
202
- * @description n watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
202
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
203
203
  * @see https://bybit-exchange.github.io/docs/v5/websocket/public/ticker
204
204
  * @see https://bybit-exchange.github.io/docs/v5/websocket/public/etp-ticker
205
205
  * @param {string[]} symbols unified symbol of the market to fetch the ticker for
@@ -126,6 +126,7 @@ class cex extends cex$1 {
126
126
  const url = this.urls['api']['ws'];
127
127
  const messageHash = 'trades';
128
128
  const subscriptionHash = 'old:' + symbol;
129
+ this.options['currentWatchTradeSymbol'] = symbol; // exchange supports only 1 symbol for this watchTrades channel
129
130
  const client = this.safeValue(this.clients, url);
130
131
  if (client !== undefined) {
131
132
  const subscriptionKeys = Object.keys(client.subscriptions);
@@ -167,11 +168,16 @@ class cex extends cex$1 {
167
168
  const data = this.safeList(message, 'data', []);
168
169
  const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
169
170
  const stored = new Cache.ArrayCache(limit);
171
+ const symbol = this.safeString(this.options, 'currentWatchTradeSymbol');
172
+ if (symbol === undefined) {
173
+ return;
174
+ }
175
+ const market = this.market(symbol);
170
176
  const dataLength = data.length;
171
177
  for (let i = 0; i < dataLength; i++) {
172
178
  const index = dataLength - 1 - i;
173
179
  const rawTrade = data[index];
174
- const parsed = this.parseWsOldTrade(rawTrade);
180
+ const parsed = this.parseWsOldTrade(rawTrade, market);
175
181
  stored.append(parsed);
176
182
  }
177
183
  const messageHash = 'trades';
@@ -198,7 +204,7 @@ class cex extends cex$1 {
198
204
  'id': id,
199
205
  'timestamp': timestamp,
200
206
  'datetime': this.iso8601(timestamp),
201
- 'symbol': undefined,
207
+ 'symbol': this.safeString(market, 'symbol'),
202
208
  'type': undefined,
203
209
  'side': side,
204
210
  'order': undefined,
@@ -220,8 +226,10 @@ class cex extends cex$1 {
220
226
  //
221
227
  const data = this.safeValue(message, 'data', []);
222
228
  const stored = this.trades; // to do fix this, this.trades is not meant to be used like this
223
- for (let i = 0; i < data.length; i++) {
224
- const rawTrade = data[i];
229
+ const dataLength = data.length;
230
+ for (let i = 0; i < dataLength; i++) {
231
+ const index = dataLength - 1 - i;
232
+ const rawTrade = data[index];
225
233
  const parsed = this.parseWsOldTrade(rawTrade);
226
234
  stored.append(parsed);
227
235
  }
@@ -337,12 +345,17 @@ class cex extends cex$1 {
337
345
  const data = this.safeValue(message, 'data', {});
338
346
  const ticker = this.parseWsTicker(data);
339
347
  const symbol = ticker['symbol'];
348
+ if (symbol === undefined) {
349
+ return;
350
+ }
340
351
  this.tickers[symbol] = ticker;
341
352
  let messageHash = 'ticker:' + symbol;
342
353
  client.resolve(ticker, messageHash);
343
354
  client.resolve(ticker, 'tickers');
344
355
  messageHash = this.safeString(message, 'oid');
345
- client.resolve(ticker, messageHash);
356
+ if (messageHash !== undefined) {
357
+ client.resolve(ticker, messageHash);
358
+ }
346
359
  }
347
360
  parseWsTicker(ticker, market = undefined) {
348
361
  //
@@ -1321,7 +1321,8 @@ class okx extends okx$1 {
1321
1321
  this.handleErrors(undefined, undefined, client.url, method, undefined, stringMsg, stringMsg, undefined, undefined);
1322
1322
  }
1323
1323
  const orders = this.parseOrders(args, undefined, undefined, undefined);
1324
- client.resolve(orders, messageHash);
1324
+ const first = this.safeDict(orders, 0, {});
1325
+ client.resolve(first, messageHash);
1325
1326
  }
1326
1327
  async editOrderWs(id, symbol, type, side, amount, price = undefined, params = {}) {
1327
1328
  /**