ccxt 4.5.56 → 4.5.57

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 (261) hide show
  1. package/README.md +10 -9
  2. package/dist/ccxt.browser.min.js +10 -10
  3. package/dist/cjs/ccxt.js +6 -11
  4. package/dist/cjs/src/apex.js +1 -1
  5. package/dist/cjs/src/arkham.js +3 -3
  6. package/dist/cjs/src/ascendex.js +2 -2
  7. package/dist/cjs/src/aster.js +7 -4
  8. package/dist/cjs/src/backpack.js +4 -4
  9. package/dist/cjs/src/base/Exchange.js +69 -32
  10. package/dist/cjs/src/base/functions/io.js +25 -0
  11. package/dist/cjs/src/base/functions.js +1 -0
  12. package/dist/cjs/src/bigone.js +3 -3
  13. package/dist/cjs/src/binance.js +192 -194
  14. package/dist/cjs/src/bingx.js +3 -3
  15. package/dist/cjs/src/bitfinex.js +71 -58
  16. package/dist/cjs/src/bitget.js +2 -2
  17. package/dist/cjs/src/bitmart.js +13 -6
  18. package/dist/cjs/src/bitmex.js +1 -1
  19. package/dist/cjs/src/bitopro.js +1 -1
  20. package/dist/cjs/src/bitrue.js +2 -2
  21. package/dist/cjs/src/bitso.js +1 -1
  22. package/dist/cjs/src/bitstamp.js +2 -1
  23. package/dist/cjs/src/bitteam.js +1 -1
  24. package/dist/cjs/src/bittrade.js +0 -1
  25. package/dist/cjs/src/bitvavo.js +457 -34
  26. package/dist/cjs/src/blofin.js +26 -3
  27. package/dist/cjs/src/bullish.js +6 -5
  28. package/dist/cjs/src/bydfi.js +1 -1
  29. package/dist/cjs/src/cex.js +3 -3
  30. package/dist/cjs/src/coinbase.js +75 -65
  31. package/dist/cjs/src/coinbaseexchange.js +2 -2
  32. package/dist/cjs/src/coinbaseinternational.js +2 -1
  33. package/dist/cjs/src/coinex.js +74 -74
  34. package/dist/cjs/src/coinmetro.js +1 -1
  35. package/dist/cjs/src/coinsph.js +1 -1
  36. package/dist/cjs/src/cryptocom.js +46 -48
  37. package/dist/cjs/src/cryptomus.js +43 -39
  38. package/dist/cjs/src/deepcoin.js +3 -2
  39. package/dist/cjs/src/delta.js +51 -52
  40. package/dist/cjs/src/deribit.js +31 -33
  41. package/dist/cjs/src/derive.js +26 -28
  42. package/dist/cjs/src/digifinex.js +43 -44
  43. package/dist/cjs/src/exmo.js +92 -83
  44. package/dist/cjs/src/extended.js +3497 -0
  45. package/dist/cjs/src/foxbit.js +71 -75
  46. package/dist/cjs/src/gate.js +53 -53
  47. package/dist/cjs/src/gemini.js +41 -43
  48. package/dist/cjs/src/grvt.js +4 -4
  49. package/dist/cjs/src/hashkey.js +52 -54
  50. package/dist/cjs/src/hitbtc.js +3 -13
  51. package/dist/cjs/src/hollaex.js +51 -54
  52. package/dist/cjs/src/htx.js +75 -67
  53. package/dist/cjs/src/hyperliquid.js +41 -42
  54. package/dist/cjs/src/indodax.js +2 -2
  55. package/dist/cjs/src/kraken.js +57 -58
  56. package/dist/cjs/src/kucoin.js +3 -2
  57. package/dist/cjs/src/latoken.js +30 -32
  58. package/dist/cjs/src/lbank.js +56 -56
  59. package/dist/cjs/src/lighter.js +35 -37
  60. package/dist/cjs/src/luno.js +35 -43
  61. package/dist/cjs/src/mexc.js +48 -49
  62. package/dist/cjs/src/modetrade.js +50 -52
  63. package/dist/cjs/src/ndax.js +35 -37
  64. package/dist/cjs/src/okx.js +17 -2
  65. package/dist/cjs/src/onetrading.js +21 -23
  66. package/dist/cjs/src/phemex.js +43 -45
  67. package/dist/cjs/src/poloniex.js +17 -12
  68. package/dist/cjs/src/pro/alpaca.js +1 -1
  69. package/dist/cjs/src/pro/apex.js +1 -1
  70. package/dist/cjs/src/pro/arkham.js +1 -1
  71. package/dist/cjs/src/pro/backpack.js +1 -1
  72. package/dist/cjs/src/pro/binance.js +3 -3
  73. package/dist/cjs/src/pro/bitget.js +1 -1
  74. package/dist/cjs/src/pro/bithumb.js +1 -1
  75. package/dist/cjs/src/pro/bitstamp.js +1 -1
  76. package/dist/cjs/src/pro/blockchaincom.js +1 -1
  77. package/dist/cjs/src/pro/bybit.js +1 -1
  78. package/dist/cjs/src/pro/cex.js +1 -1
  79. package/dist/cjs/src/pro/coinex.js +1 -1
  80. package/dist/cjs/src/pro/coinone.js +1 -1
  81. package/dist/cjs/src/pro/cryptocom.js +3 -1
  82. package/dist/cjs/src/pro/dydx.js +1 -1
  83. package/dist/cjs/src/pro/exmo.js +1 -1
  84. package/dist/cjs/src/pro/extended.js +865 -0
  85. package/dist/cjs/src/pro/gate.js +1 -1
  86. package/dist/cjs/src/pro/independentreserve.js +1 -1
  87. package/dist/cjs/src/pro/kucoin.js +1 -1
  88. package/dist/cjs/src/pro/luno.js +3 -3
  89. package/dist/cjs/src/pro/onetrading.js +1 -1
  90. package/dist/cjs/src/pro/toobit.js +1 -1
  91. package/dist/cjs/src/pro/weex.js +1 -1
  92. package/dist/cjs/src/static_dependencies/starknet/utils/hash/classHash.js +7 -7
  93. package/dist/cjs/src/tokocrypto.js +1 -1
  94. package/dist/cjs/src/toobit.js +2 -2
  95. package/dist/cjs/src/upbit.js +3 -3
  96. package/dist/cjs/src/weex.js +57 -62
  97. package/dist/cjs/src/whitebit.js +61 -63
  98. package/dist/cjs/src/woo.js +65 -54
  99. package/dist/cjs/src/woofipro.js +53 -47
  100. package/dist/cjs/src/xt.js +1 -1
  101. package/dist/cjs/src/zebpay.js +70 -72
  102. package/js/ccxt.d.ts +8 -14
  103. package/js/ccxt.js +6 -10
  104. package/js/src/abstract/bitvavo.d.ts +15 -7
  105. package/js/src/abstract/extended.d.ts +58 -0
  106. package/js/src/apex.js +1 -1
  107. package/js/src/arkham.js +3 -3
  108. package/js/src/ascendex.js +2 -2
  109. package/js/src/aster.js +7 -4
  110. package/js/src/backpack.js +4 -4
  111. package/js/src/base/Exchange.d.ts +10 -6
  112. package/js/src/base/Exchange.js +69 -32
  113. package/js/src/base/functions/io.d.ts +7 -0
  114. package/js/src/base/functions/io.js +24 -0
  115. package/js/src/bigone.js +3 -3
  116. package/js/src/binance.d.ts +2 -0
  117. package/js/src/binance.js +196 -198
  118. package/js/src/bingx.js +3 -3
  119. package/js/src/bitfinex.d.ts +2 -0
  120. package/js/src/bitfinex.js +71 -58
  121. package/js/src/bitget.js +2 -2
  122. package/js/src/bitmart.js +13 -6
  123. package/js/src/bitmex.js +1 -1
  124. package/js/src/bitopro.js +1 -1
  125. package/js/src/bitrue.js +2 -2
  126. package/js/src/bitso.js +1 -1
  127. package/js/src/bitstamp.js +2 -1
  128. package/js/src/bitteam.js +1 -1
  129. package/js/src/bittrade.js +0 -1
  130. package/js/src/bitvavo.d.ts +114 -21
  131. package/js/src/bitvavo.js +457 -34
  132. package/js/src/blofin.d.ts +1 -0
  133. package/js/src/blofin.js +26 -3
  134. package/js/src/bullish.js +6 -5
  135. package/js/src/bydfi.js +1 -1
  136. package/js/src/cex.js +3 -3
  137. package/js/src/coinbase.d.ts +63 -56
  138. package/js/src/coinbase.js +75 -65
  139. package/js/src/coinbaseexchange.js +2 -2
  140. package/js/src/coinbaseinternational.js +2 -1
  141. package/js/src/coinex.d.ts +1 -0
  142. package/js/src/coinex.js +74 -74
  143. package/js/src/coinmetro.d.ts +1 -1
  144. package/js/src/coinmetro.js +1 -1
  145. package/js/src/coinsph.js +1 -1
  146. package/js/src/cryptocom.d.ts +1 -0
  147. package/js/src/cryptocom.js +46 -48
  148. package/js/src/cryptomus.d.ts +2 -1
  149. package/js/src/cryptomus.js +43 -39
  150. package/js/src/deepcoin.js +3 -2
  151. package/js/src/delta.d.ts +1 -0
  152. package/js/src/delta.js +51 -52
  153. package/js/src/deribit.d.ts +1 -0
  154. package/js/src/deribit.js +31 -33
  155. package/js/src/derive.d.ts +1 -0
  156. package/js/src/derive.js +26 -28
  157. package/js/src/digifinex.d.ts +1 -0
  158. package/js/src/digifinex.js +43 -44
  159. package/js/src/exmo.d.ts +1 -0
  160. package/js/src/exmo.js +92 -83
  161. package/js/src/extended.d.ts +554 -0
  162. package/js/src/extended.js +3490 -0
  163. package/js/src/foxbit.d.ts +1 -0
  164. package/js/src/foxbit.js +71 -75
  165. package/js/src/gate.d.ts +1 -0
  166. package/js/src/gate.js +53 -53
  167. package/js/src/gemini.d.ts +2 -1
  168. package/js/src/gemini.js +41 -43
  169. package/js/src/grvt.js +4 -4
  170. package/js/src/hashkey.d.ts +1 -0
  171. package/js/src/hashkey.js +52 -54
  172. package/js/src/hitbtc.d.ts +0 -1
  173. package/js/src/hitbtc.js +3 -13
  174. package/js/src/hollaex.d.ts +1 -0
  175. package/js/src/hollaex.js +51 -54
  176. package/js/src/htx.d.ts +1 -0
  177. package/js/src/htx.js +75 -67
  178. package/js/src/hyperliquid.d.ts +1 -0
  179. package/js/src/hyperliquid.js +41 -42
  180. package/js/src/indodax.js +2 -2
  181. package/js/src/kraken.d.ts +2 -1
  182. package/js/src/kraken.js +57 -58
  183. package/js/src/kucoin.js +3 -2
  184. package/js/src/latoken.d.ts +1 -0
  185. package/js/src/latoken.js +30 -32
  186. package/js/src/lbank.d.ts +1 -0
  187. package/js/src/lbank.js +56 -56
  188. package/js/src/lighter.d.ts +1 -0
  189. package/js/src/lighter.js +35 -37
  190. package/js/src/luno.d.ts +1 -0
  191. package/js/src/luno.js +35 -43
  192. package/js/src/mexc.d.ts +2 -1
  193. package/js/src/mexc.js +48 -49
  194. package/js/src/modetrade.d.ts +1 -0
  195. package/js/src/modetrade.js +50 -52
  196. package/js/src/ndax.d.ts +1 -0
  197. package/js/src/ndax.js +35 -37
  198. package/js/src/okx.js +17 -2
  199. package/js/src/onetrading.d.ts +2 -1
  200. package/js/src/onetrading.js +21 -23
  201. package/js/src/phemex.d.ts +1 -0
  202. package/js/src/phemex.js +43 -45
  203. package/js/src/poloniex.js +17 -12
  204. package/js/src/pro/alpaca.js +1 -1
  205. package/js/src/pro/apex.js +1 -1
  206. package/js/src/pro/arkham.js +1 -1
  207. package/js/src/pro/backpack.js +1 -1
  208. package/js/src/pro/binance.js +3 -3
  209. package/js/src/pro/bitget.js +1 -1
  210. package/js/src/pro/bithumb.js +1 -1
  211. package/js/src/pro/bitstamp.js +1 -1
  212. package/js/src/pro/blockchaincom.js +1 -1
  213. package/js/src/pro/bybit.js +1 -1
  214. package/js/src/pro/cex.js +1 -1
  215. package/js/src/pro/coinex.js +1 -1
  216. package/js/src/pro/coinone.js +1 -1
  217. package/js/src/pro/cryptocom.js +3 -1
  218. package/js/src/pro/dydx.js +1 -1
  219. package/js/src/pro/exmo.js +1 -1
  220. package/js/src/pro/extended.d.ts +126 -0
  221. package/js/src/pro/extended.js +858 -0
  222. package/js/src/pro/gate.js +1 -1
  223. package/js/src/pro/independentreserve.js +1 -1
  224. package/js/src/pro/kucoin.js +1 -1
  225. package/js/src/pro/luno.d.ts +1 -1
  226. package/js/src/pro/luno.js +3 -3
  227. package/js/src/pro/onetrading.js +1 -1
  228. package/js/src/pro/toobit.js +1 -1
  229. package/js/src/pro/weex.js +1 -1
  230. package/js/src/tokocrypto.js +1 -1
  231. package/js/src/toobit.js +2 -2
  232. package/js/src/upbit.js +3 -3
  233. package/js/src/weex.d.ts +1 -0
  234. package/js/src/weex.js +57 -62
  235. package/js/src/whitebit.d.ts +1 -0
  236. package/js/src/whitebit.js +61 -63
  237. package/js/src/woo.d.ts +1 -0
  238. package/js/src/woo.js +65 -54
  239. package/js/src/woofipro.d.ts +1 -0
  240. package/js/src/woofipro.js +53 -47
  241. package/js/src/xt.js +1 -1
  242. package/js/src/zebpay.d.ts +2 -1
  243. package/js/src/zebpay.js +70 -72
  244. package/package.json +7 -7
  245. package/dist/cjs/src/gateio.js +0 -18
  246. package/dist/cjs/src/oxfun.js +0 -2933
  247. package/dist/cjs/src/pro/gateio.js +0 -18
  248. package/dist/cjs/src/pro/oxfun.js +0 -1113
  249. package/js/src/abstract/gateio.d.ts +0 -346
  250. package/js/src/abstract/gateio.js +0 -5
  251. package/js/src/abstract/oxfun.d.ts +0 -37
  252. package/js/src/gateio.d.ts +0 -4
  253. package/js/src/gateio.js +0 -11
  254. package/js/src/oxfun.d.ts +0 -442
  255. package/js/src/oxfun.js +0 -2926
  256. package/js/src/pro/gateio.d.ts +0 -4
  257. package/js/src/pro/gateio.js +0 -11
  258. package/js/src/pro/oxfun.d.ts +0 -234
  259. package/js/src/pro/oxfun.js +0 -1106
  260. /package/dist/cjs/src/abstract/{oxfun.js → extended.js} +0 -0
  261. /package/js/src/abstract/{oxfun.js → extended.js} +0 -0
@@ -0,0 +1,858 @@
1
+ // ----------------------------------------------------------------------------
2
+ import extendedRest from '../extended.js';
3
+ import { ExchangeError, InvalidNonce } from '../base/errors.js';
4
+ import { ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp } from '../base/ws/Cache.js';
5
+ // ----------------------------------------------------------------------------
6
+ export default class extended extends extendedRest {
7
+ describe() {
8
+ return this.deepExtend(super.describe(), {
9
+ 'has': {
10
+ 'ws': true,
11
+ 'watchFundingRate': true,
12
+ 'watchOHLCV': true,
13
+ 'watchOrderBook': true,
14
+ 'watchIndexPrice': true,
15
+ 'watchMarkPrice': true,
16
+ 'watchTrades': true,
17
+ 'watchBalance': true,
18
+ 'watchMyTrades': true,
19
+ 'watchOrders': true,
20
+ 'watchPositions': true,
21
+ },
22
+ 'urls': {
23
+ 'api': {
24
+ 'ws': 'wss://api.starknet.extended.exchange/stream.extended.exchange/v1',
25
+ },
26
+ 'test': {
27
+ 'ws': 'wss://api.starknet.sepolia.extended.exchange/stream.extended.exchange/v1',
28
+ },
29
+ },
30
+ 'options': {
31
+ 'ws': {
32
+ 'options': {
33
+ 'headers': {
34
+ 'User-Agent': this.userAgents['chrome'],
35
+ },
36
+ },
37
+ },
38
+ },
39
+ });
40
+ }
41
+ /**
42
+ * @method
43
+ * @name extended#watchOrderBook
44
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
45
+ * @see https://api.docs.extended.exchange/#order-book-stream
46
+ * @param {string} symbol unified symbol of the market to fetch the order book for
47
+ * @param {int} [limit] the maximum amount of order book entries to return
48
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
49
+ * @param {string} [params.depth] set to '1' to receive best bid and ask snapshots only
50
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/?id=order-book-structure} indexed by market symbols
51
+ */
52
+ async watchOrderBook(symbol, limit = undefined, params = {}) {
53
+ await this.loadMarkets();
54
+ const market = this.market(symbol);
55
+ symbol = market['symbol'];
56
+ const messageHash = 'orderbook:' + symbol;
57
+ const query = this.urlencode(params);
58
+ let url = this.urls['api']['ws'] + '/orderbooks/' + market['id'];
59
+ if (query.length > 0) {
60
+ url += '?' + query;
61
+ }
62
+ const orderbook = await this.watch(url, messageHash, undefined, messageHash, {
63
+ 'symbol': symbol,
64
+ 'limit': limit,
65
+ });
66
+ return orderbook.limit();
67
+ }
68
+ handleOrderBook(client, message) {
69
+ //
70
+ // {
71
+ // "ts": 1701563440000,
72
+ // "type": "SNAPSHOT",
73
+ // "data": {
74
+ // "m": "BTC-USD",
75
+ // "b": [
76
+ // { "p": "25670", "q": "0.1" }
77
+ // ],
78
+ // "a": [
79
+ // { "p": "25770", "q": "0.1" }
80
+ // ]
81
+ // },
82
+ // "seq": 1
83
+ // }
84
+ //
85
+ const data = this.safeDict(message, 'data', {});
86
+ const marketId = this.safeString(data, 'm');
87
+ const market = this.safeMarket(marketId);
88
+ const symbol = market['symbol'];
89
+ const messageHash = 'orderbook:' + symbol;
90
+ const timestamp = this.safeInteger(message, 'ts');
91
+ const nonce = this.safeInteger(message, 'seq');
92
+ const type = this.safeString(message, 'type', this.safeString(data, 't'));
93
+ if (!(symbol in this.orderbooks)) {
94
+ const defaultLimit = this.safeInteger(this.options, 'watchOrderBookLimit', 1000);
95
+ const subscription = this.safeDict(client.subscriptions, messageHash, {});
96
+ const limit = this.safeInteger(subscription, 'limit', defaultLimit);
97
+ this.orderbooks[symbol] = this.orderBook({}, limit);
98
+ }
99
+ const orderbook = this.orderbooks[symbol];
100
+ if (type === 'SNAPSHOT') {
101
+ const snapshot = this.parseOrderBook(data, symbol, timestamp, 'b', 'a', 'p', 'q');
102
+ snapshot['nonce'] = nonce;
103
+ orderbook.reset(snapshot);
104
+ client.resolve(orderbook, messageHash);
105
+ return;
106
+ }
107
+ const previousNonce = this.safeInteger(orderbook, 'nonce');
108
+ if ((previousNonce !== undefined) && (nonce !== previousNonce + 1)) {
109
+ delete client.subscriptions[messageHash];
110
+ delete this.orderbooks[symbol];
111
+ const error = new InvalidNonce(this.id + ' watchOrderBook received invalid nonce');
112
+ client.reject(error, messageHash);
113
+ return;
114
+ }
115
+ this.handleDeltas(orderbook['bids'], this.safeList(data, 'b', []));
116
+ this.handleDeltas(orderbook['asks'], this.safeList(data, 'a', []));
117
+ orderbook['timestamp'] = timestamp;
118
+ orderbook['datetime'] = this.iso8601(timestamp);
119
+ orderbook['nonce'] = nonce;
120
+ client.resolve(orderbook, messageHash);
121
+ }
122
+ handleDelta(bookside, delta) {
123
+ const price = this.safeFloat(delta, 'p');
124
+ const amount = this.safeFloat2(delta, 'c', 'q');
125
+ bookside.store(price, amount);
126
+ }
127
+ handleDeltas(bookside, deltas) {
128
+ for (let i = 0; i < deltas.length; i++) {
129
+ this.handleDelta(bookside, deltas[i]);
130
+ }
131
+ }
132
+ async watchPrivate(messageHash, subscription = undefined) {
133
+ this.checkRequiredCredentials();
134
+ const url = this.urls['api']['ws'] + '/account';
135
+ if ((this.clients === undefined) || !(url in this.clients)) {
136
+ const defaultOptions = {
137
+ 'ws': {
138
+ 'options': {
139
+ 'headers': {},
140
+ },
141
+ },
142
+ };
143
+ this.extendExchangeOptions(defaultOptions);
144
+ const originalOptions = this.options['ws']['options'];
145
+ const originalHeaders = this.safeDict(originalOptions, 'headers', {});
146
+ this.options['ws']['options'] = this.extend(this.extend({}, originalOptions), {
147
+ 'headers': this.extend(this.extend({
148
+ 'User-Agent': this.userAgents['chrome'],
149
+ }, originalHeaders), {
150
+ 'X-Api-Key': this.apiKey,
151
+ }),
152
+ });
153
+ this.client(url);
154
+ this.options['ws']['options'] = originalOptions;
155
+ }
156
+ return await this.watch(url, messageHash, undefined, messageHash, subscription);
157
+ }
158
+ /**
159
+ * @method
160
+ * @name extended#watchOrders
161
+ * @description watches information on multiple orders made by the user
162
+ * @see https://api.docs.extended.exchange/#account-updates-stream
163
+ * @param {string} symbol unified market symbol of the market orders were made in
164
+ * @param {int} [since] the earliest time in ms to fetch orders for
165
+ * @param {int} [limit] the maximum number of order structures to retrieve
166
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
167
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/?id=order-structure}
168
+ */
169
+ async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
170
+ await this.loadMarkets();
171
+ let messageHash = 'orders';
172
+ if (symbol !== undefined) {
173
+ const market = this.market(symbol);
174
+ symbol = market['symbol'];
175
+ messageHash += ':' + symbol;
176
+ }
177
+ const orders = await this.watchPrivate(messageHash, {
178
+ 'symbol': symbol,
179
+ 'limit': limit,
180
+ });
181
+ if (this.newUpdates) {
182
+ limit = orders.getLimit(symbol, limit);
183
+ }
184
+ return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
185
+ }
186
+ /**
187
+ * @method
188
+ * @name extended#watchBalance
189
+ * @description watches balance updates
190
+ * @see https://api.docs.extended.exchange/#account-updates-stream
191
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
192
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/?id=balance-structure}
193
+ */
194
+ async watchBalance(params = {}) {
195
+ await this.loadMarkets();
196
+ return await this.watchPrivate('balance', params);
197
+ }
198
+ handleBalance(client, message) {
199
+ //
200
+ // {
201
+ // "type": "BALANCE",
202
+ // "data": {
203
+ // "balance": {
204
+ // "collateralName": "BTC",
205
+ // "balance": "100.000000",
206
+ // "equity": "20.000000",
207
+ // "availableForTrade": "3.000000",
208
+ // "availableForWithdrawal": "4.000000",
209
+ // "updatedTime": 1699976104901
210
+ // },
211
+ // "spotBalances": [
212
+ // {
213
+ // "asset": "BTC",
214
+ // "balance": "0.5",
215
+ // "availableToWithdraw": "0.5",
216
+ // "updatedAt": 1701563440
217
+ // }
218
+ // ]
219
+ // },
220
+ // "ts": 1715885952304,
221
+ // "seq": 1
222
+ // }
223
+ //
224
+ const data = this.safeDict(message, 'data', {});
225
+ const result = {
226
+ 'info': data,
227
+ };
228
+ const balance = this.safeDict(data, 'balance');
229
+ if (balance !== undefined) {
230
+ const currencyId = this.safeString(balance, 'collateralName');
231
+ const code = this.safeCurrencyCode(currencyId);
232
+ if (code !== undefined) {
233
+ const account = this.account();
234
+ account['free'] = this.safeString(balance, 'availableForWithdrawal');
235
+ account['total'] = this.safeString(balance, 'balance');
236
+ result[code] = account;
237
+ }
238
+ }
239
+ const spotBalances = this.safeList(data, 'spotBalances', []);
240
+ for (let i = 0; i < spotBalances.length; i++) {
241
+ const spotBalance = this.safeDict(spotBalances, i, {});
242
+ const currencyId = this.safeString(spotBalance, 'asset');
243
+ const code = this.safeCurrencyCode(currencyId);
244
+ if (code !== undefined) {
245
+ const account = this.account();
246
+ account['free'] = this.safeString(spotBalance, 'availableToWithdraw');
247
+ account['total'] = this.safeString(spotBalance, 'balance');
248
+ result[code] = account;
249
+ }
250
+ }
251
+ const timestamp = this.safeInteger(message, 'ts');
252
+ result['timestamp'] = timestamp;
253
+ result['datetime'] = this.iso8601(timestamp);
254
+ this.balance = this.safeBalance(this.deepExtend(this.balance, result));
255
+ client.resolve(this.balance, 'balance');
256
+ }
257
+ /**
258
+ * @method
259
+ * @name extended#watchMyTrades
260
+ * @description watches information on multiple trades made by the user
261
+ * @see https://api.docs.extended.exchange/#account-updates-stream
262
+ * @param {string} [symbol] unified market symbol of the trades
263
+ * @param {int} [since] the earliest time in ms to fetch trades for
264
+ * @param {int} [limit] the maximum number of trade structures to retrieve
265
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
266
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
267
+ */
268
+ async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
269
+ await this.loadMarkets();
270
+ let messageHash = 'myTrades';
271
+ if (symbol !== undefined) {
272
+ const market = this.market(symbol);
273
+ symbol = market['symbol'];
274
+ messageHash += ':' + symbol;
275
+ }
276
+ const trades = await this.watchPrivate(messageHash, {
277
+ 'symbol': symbol,
278
+ 'limit': limit,
279
+ });
280
+ if (this.newUpdates) {
281
+ limit = trades.getLimit(symbol, limit);
282
+ }
283
+ return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
284
+ }
285
+ handleMyTrades(client, message) {
286
+ //
287
+ // {
288
+ // "type": "TRADE",
289
+ // "data": {
290
+ // "trades": [
291
+ // {
292
+ // "id": 1784963886257016832,
293
+ // "accountId": 3017,
294
+ // "market": "BTC-USD",
295
+ // "orderId": 9223372036854775808,
296
+ // "externalOrderId": "ext-1",
297
+ // "side": "BUY",
298
+ // "price": "58853.4000000000000000",
299
+ // "qty": "0.0900000000000000",
300
+ // "value": "5296.8060000000000000",
301
+ // "fee": "0.0000000000000000",
302
+ // "tradeType": "DELEVERAGE",
303
+ // "createdTime": 1701563440000,
304
+ // "isTaker": true
305
+ // }
306
+ // ]
307
+ // },
308
+ // "ts": 1715886400000,
309
+ // "seq": 1
310
+ // }
311
+ //
312
+ if (this.myTrades === undefined) {
313
+ const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
314
+ this.myTrades = new ArrayCacheBySymbolById(limit);
315
+ }
316
+ const stored = this.myTrades;
317
+ const data = this.safeDict(message, 'data', {});
318
+ const rawTrades = this.safeList(data, 'trades', []);
319
+ const symbols = {};
320
+ const first = this.safeDict(rawTrades, 0);
321
+ if (first === undefined) {
322
+ return;
323
+ }
324
+ for (let i = 0; i < rawTrades.length; i++) {
325
+ const trade = this.parseTrade(rawTrades[i]);
326
+ const symbol = this.safeString(trade, 'symbol');
327
+ symbols[symbol] = true;
328
+ stored.append(trade);
329
+ }
330
+ const keys = Object.keys(symbols);
331
+ for (let i = 0; i < keys.length; i++) {
332
+ const messageHash = 'myTrades:' + keys[i];
333
+ client.resolve(stored, messageHash);
334
+ }
335
+ client.resolve(stored, 'myTrades');
336
+ const subscriptions = Object.keys(client.subscriptions);
337
+ for (let i = 0; i < subscriptions.length; i++) {
338
+ const messageHash = subscriptions[i];
339
+ if (messageHash.indexOf('myTrades:') === 0) {
340
+ client.resolve(stored, messageHash);
341
+ }
342
+ }
343
+ }
344
+ /**
345
+ * @method
346
+ * @name extended#watchPositions
347
+ * @description watches information on multiple positions
348
+ * @see https://api.docs.extended.exchange/#account-updates-stream
349
+ * @param {string[]} [symbols] unified market symbols
350
+ * @param {int} [since] the earliest time in ms to fetch positions for
351
+ * @param {int} [limit] the maximum number of position structures to retrieve
352
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
353
+ * @returns {object[]} a list of [position structures]{@link https://docs.ccxt.com/#/?id=position-structure}
354
+ */
355
+ async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
356
+ await this.loadMarkets();
357
+ symbols = this.marketSymbols(symbols);
358
+ let messageHash = 'positions';
359
+ if (symbols !== undefined) {
360
+ messageHash += '::' + symbols.join(',');
361
+ }
362
+ const positions = await this.watchPrivate(messageHash, {
363
+ 'symbols': symbols,
364
+ 'limit': limit,
365
+ });
366
+ if (this.newUpdates) {
367
+ return positions;
368
+ }
369
+ return this.filterBySymbolsSinceLimit(this.positions, symbols, since, limit, true);
370
+ }
371
+ handlePositions(client, message) {
372
+ //
373
+ // {
374
+ // "type": "POSITION",
375
+ // "data": {
376
+ // "positions": [
377
+ // {
378
+ // "id": 1,
379
+ // "accountId": 1,
380
+ // "market": "BTC-USD",
381
+ // "side": "LONG",
382
+ // "leverage": "10",
383
+ // "size": "0.1",
384
+ // "value": "4000",
385
+ // "openPrice": "39000",
386
+ // "markPrice": "40000",
387
+ // "updatedAt": 1701563440000
388
+ // }
389
+ // ]
390
+ // },
391
+ // "ts": 1715886400000,
392
+ // "seq": 1
393
+ // }
394
+ //
395
+ if (this.positions === undefined) {
396
+ this.positions = new ArrayCacheBySymbolBySide();
397
+ }
398
+ const stored = this.positions;
399
+ const data = this.safeDict(message, 'data', {});
400
+ const rawPositions = this.safeList(data, 'positions', []);
401
+ const newPositions = [];
402
+ const first = this.safeDict(rawPositions, 0);
403
+ if (first === undefined) {
404
+ return;
405
+ }
406
+ for (let i = 0; i < rawPositions.length; i++) {
407
+ const rawPosition = rawPositions[i];
408
+ const marketId = this.safeString(rawPosition, 'market');
409
+ if (marketId === undefined) {
410
+ continue;
411
+ }
412
+ const position = this.parsePosition(rawPosition);
413
+ newPositions.push(position);
414
+ stored.append(position);
415
+ }
416
+ const messageHashes = this.findMessageHashes(client, 'positions::');
417
+ for (let i = 0; i < messageHashes.length; i++) {
418
+ const messageHash = messageHashes[i];
419
+ const parts = messageHash.split('::');
420
+ const symbolsString = parts[1];
421
+ const symbols = symbolsString.split(',');
422
+ const filtered = this.filterByArray(newPositions, 'symbol', symbols, false);
423
+ if (!this.isEmpty(filtered)) {
424
+ client.resolve(filtered, messageHash);
425
+ }
426
+ }
427
+ client.resolve(newPositions, 'positions');
428
+ }
429
+ handleOrders(client, message) {
430
+ //
431
+ // {
432
+ // "type": "ORDER",
433
+ // "data": {
434
+ // "orders": [
435
+ // {
436
+ // "id": 1791181340771614723,
437
+ // "accountId": 1791181340771614721,
438
+ // "externalId": "-1771812132822291885",
439
+ // "market": "BTC-USD",
440
+ // "type": "LIMIT",
441
+ // "side": "BUY",
442
+ // "status": "NEW",
443
+ // "price": "12400.000000",
444
+ // "averagePrice": "13140.000000",
445
+ // "qty": "10.000000",
446
+ // "filledQty": "3.513000",
447
+ // "payedFee": "0.513000",
448
+ // "reduceOnly": true,
449
+ // "postOnly": false,
450
+ // "createdTime": 1715885888571,
451
+ // "updatedTime": 1715885888571,
452
+ // "expireTime": 1715885888571
453
+ // }
454
+ // ]
455
+ // },
456
+ // "ts": 1715885884837,
457
+ // "seq": 1
458
+ // }
459
+ //
460
+ if (this.orders === undefined) {
461
+ const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
462
+ this.orders = new ArrayCacheBySymbolById(limit);
463
+ }
464
+ const orders = this.orders;
465
+ const data = this.safeDict(message, 'data', {});
466
+ const rawOrders = this.safeList(data, 'orders');
467
+ const symbols = {};
468
+ const first = this.safeDict(rawOrders, 0);
469
+ if (first === undefined) {
470
+ return;
471
+ }
472
+ for (let i = 0; i < rawOrders.length; i++) {
473
+ const order = this.parseOrder(rawOrders[i]);
474
+ const symbol = this.safeString(order, 'symbol');
475
+ symbols[symbol] = true;
476
+ orders.append(order);
477
+ }
478
+ const keys = Object.keys(symbols);
479
+ for (let i = 0; i < keys.length; i++) {
480
+ const messageHash = 'orders:' + keys[i];
481
+ client.resolve(orders, messageHash);
482
+ }
483
+ client.resolve(orders, 'orders');
484
+ const subscriptions = Object.keys(client.subscriptions);
485
+ for (let i = 0; i < subscriptions.length; i++) {
486
+ const messageHash = subscriptions[i];
487
+ if (messageHash.indexOf('orders:') === 0) {
488
+ client.resolve(orders, messageHash);
489
+ }
490
+ }
491
+ }
492
+ /**
493
+ * @method
494
+ * @name extended#watchFundingRate
495
+ * @description watch the current funding rate
496
+ * @see https://api.docs.extended.exchange/#funding-rates-stream
497
+ * @param {string} symbol unified market symbol
498
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
499
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/?id=funding-rate-structure}
500
+ */
501
+ async watchFundingRate(symbol, params = {}) {
502
+ await this.loadMarkets();
503
+ const market = this.market(symbol);
504
+ symbol = market['symbol'];
505
+ const messageHash = 'fundingRate:' + symbol;
506
+ const query = this.urlencode(params);
507
+ let url = this.urls['api']['ws'] + '/funding/' + market['id'];
508
+ if (query.length > 0) {
509
+ url += '?' + query;
510
+ }
511
+ return await this.watch(url, messageHash, undefined, messageHash, {
512
+ 'symbol': symbol,
513
+ 'messageHash': messageHash,
514
+ });
515
+ }
516
+ handleFundingRate(client, message) {
517
+ //
518
+ // {
519
+ // "ts": 1701563440000,
520
+ // "data": {
521
+ // "m": "BTC-USD",
522
+ // "T": 1701563440000,
523
+ // "f": "0.001"
524
+ // },
525
+ // "seq": 2
526
+ // }
527
+ //
528
+ const data = this.safeDict(message, 'data', {});
529
+ const fundingRate = this.parseWsFundingRate(data, undefined, message);
530
+ const symbol = this.safeString(fundingRate, 'symbol');
531
+ this.fundingRates[symbol] = fundingRate;
532
+ const messageHash = 'fundingRate:' + symbol;
533
+ client.resolve(fundingRate, messageHash);
534
+ }
535
+ parseWsFundingRate(fundingRate, market = undefined, message = undefined) {
536
+ const marketId = this.safeString(fundingRate, 'm');
537
+ market = this.safeMarket(marketId, market);
538
+ const timestamp = this.safeInteger(message, 'ts');
539
+ const fundingTimestamp = this.safeInteger(fundingRate, 'T');
540
+ return {
541
+ 'info': fundingRate,
542
+ 'symbol': market['symbol'],
543
+ 'markPrice': undefined,
544
+ 'indexPrice': undefined,
545
+ 'interestRate': undefined,
546
+ 'estimatedSettlePrice': undefined,
547
+ 'timestamp': timestamp,
548
+ 'datetime': this.iso8601(timestamp),
549
+ 'fundingRate': this.safeNumber(fundingRate, 'f'),
550
+ 'fundingTimestamp': fundingTimestamp,
551
+ 'fundingDatetime': this.iso8601(fundingTimestamp),
552
+ 'nextFundingRate': undefined,
553
+ 'nextFundingTimestamp': undefined,
554
+ 'nextFundingDatetime': undefined,
555
+ 'previousFundingRate': undefined,
556
+ 'previousFundingTimestamp': undefined,
557
+ 'previousFundingDatetime': undefined,
558
+ 'interval': undefined,
559
+ };
560
+ }
561
+ /**
562
+ * @method
563
+ * @name extended#watchMarkPrice
564
+ * @description watches a mark price for a specific market
565
+ * @see https://api.docs.extended.exchange/#mark-price-stream
566
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
567
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
568
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/?id=ticker-structure}
569
+ */
570
+ async watchMarkPrice(symbol, params = {}) {
571
+ await this.loadMarkets();
572
+ const market = this.market(symbol);
573
+ symbol = market['symbol'];
574
+ const messageHash = 'markPrice:' + symbol;
575
+ const query = this.urlencode(params);
576
+ let url = this.urls['api']['ws'] + '/prices/mark/' + market['id'];
577
+ if (query.length > 0) {
578
+ url += '?' + query;
579
+ }
580
+ return await this.watch(url, messageHash, undefined, messageHash, {
581
+ 'name': 'markPrice',
582
+ 'symbol': symbol,
583
+ 'messageHash': messageHash,
584
+ });
585
+ }
586
+ handleMarkPrice(client, message) {
587
+ //
588
+ // {
589
+ // "type": "MP",
590
+ // "data": {
591
+ // "m": "BTC-USD",
592
+ // "p": "80988.400408625006",
593
+ // "ts": 0
594
+ // },
595
+ // "ts": 1778641421485,
596
+ // "seq": 1
597
+ // }
598
+ //
599
+ const data = this.safeDict(message, 'data', {});
600
+ const marketId = this.safeString(data, 'm');
601
+ const market = this.safeMarket(marketId);
602
+ const symbol = market['symbol'];
603
+ let timestamp = this.safeInteger(data, 'ts');
604
+ if ((timestamp === undefined) || (timestamp === 0)) {
605
+ timestamp = this.safeInteger(message, 'ts');
606
+ }
607
+ const ticker = this.safeTicker({
608
+ 'symbol': symbol,
609
+ 'timestamp': timestamp,
610
+ 'datetime': this.iso8601(timestamp),
611
+ 'markPrice': this.safeString(data, 'p'),
612
+ 'info': message,
613
+ }, market);
614
+ this.tickers[symbol] = ticker;
615
+ const messageHash = 'markPrice:' + symbol;
616
+ client.resolve(ticker, messageHash);
617
+ }
618
+ /**
619
+ * @method
620
+ * @name extended#watchTrades
621
+ * @description get the list of most recent trades for a particular symbol
622
+ * @see https://api.docs.extended.exchange/#trades-stream
623
+ * @param {string} symbol unified symbol of the market to fetch trades for
624
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
625
+ * @param {int} [limit] the maximum amount of trades to fetch
626
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
627
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=public-trades}
628
+ */
629
+ async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
630
+ await this.loadMarkets();
631
+ const market = this.market(symbol);
632
+ symbol = market['symbol'];
633
+ const messageHash = 'trades:' + symbol;
634
+ const query = this.urlencode(params);
635
+ let url = this.urls['api']['ws'] + '/publicTrades/' + market['id'];
636
+ if (query.length > 0) {
637
+ url += '?' + query;
638
+ }
639
+ const trades = await this.watch(url, messageHash, undefined, messageHash, {
640
+ 'symbol': symbol,
641
+ 'limit': limit,
642
+ });
643
+ if (this.newUpdates) {
644
+ limit = trades.getLimit(symbol, limit);
645
+ }
646
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
647
+ }
648
+ handleTrades(client, message) {
649
+ //
650
+ // {
651
+ // "ts": 1701563440000,
652
+ // "data": [
653
+ // {
654
+ // "m": "BTC-USD",
655
+ // "S": "BUY",
656
+ // "tT": "TRADE",
657
+ // "T": 1701563440000,
658
+ // "p": "25670",
659
+ // "q": "0.1",
660
+ // "i": 25124
661
+ // }
662
+ // ],
663
+ // "seq": 2
664
+ // }
665
+ //
666
+ const data = this.safeList(message, 'data', []);
667
+ const first = this.safeDict(data, 0);
668
+ if (first === undefined) {
669
+ return;
670
+ }
671
+ const marketId = this.safeString(first, 'm');
672
+ const market = this.safeMarket(marketId);
673
+ const symbol = market['symbol'];
674
+ const messageHash = 'trades:' + symbol;
675
+ const subscription = this.safeDict(client.subscriptions, messageHash, {});
676
+ let stored = this.safeValue(this.trades, symbol);
677
+ if (stored === undefined) {
678
+ const defaultLimit = this.safeInteger(this.options, 'tradesLimit', 1000);
679
+ const limit = this.safeInteger(subscription, 'limit', defaultLimit);
680
+ stored = new ArrayCache(limit);
681
+ this.trades[symbol] = stored;
682
+ }
683
+ const previousNonce = this.safeInteger(subscription, 'nonce');
684
+ const nonce = this.safeInteger(message, 'seq');
685
+ if ((previousNonce !== undefined) && (nonce !== undefined) && (nonce <= previousNonce)) {
686
+ return;
687
+ }
688
+ subscription['nonce'] = nonce;
689
+ for (let i = 0; i < data.length; i++) {
690
+ const trade = this.parseTrade(data[i], market);
691
+ stored.append(trade);
692
+ }
693
+ client.resolve(stored, messageHash);
694
+ }
695
+ /**
696
+ * @method
697
+ * @name extended#watchOHLCV
698
+ * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
699
+ * @see https://api.docs.extended.exchange/#candles-stream
700
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
701
+ * @param {string} timeframe the length of time each candle represents
702
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
703
+ * @param {int} [limit] the maximum amount of candles to fetch
704
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
705
+ * @param {string} [params.candleType] candle type: 'trades' (default), 'mark-prices', or 'index-prices'
706
+ * @param {string} [params.price] *ignored if params.candleType is set* 'mark' or 'index' for mark price and index price candles
707
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
708
+ */
709
+ async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
710
+ await this.loadMarkets();
711
+ const market = this.market(symbol);
712
+ symbol = market['symbol'];
713
+ const price = this.safeString(params, 'price');
714
+ let candleType = this.safeString(params, 'candleType');
715
+ if (candleType === undefined) {
716
+ if (price === 'mark') {
717
+ candleType = 'mark-prices';
718
+ }
719
+ else if (price === 'index') {
720
+ candleType = 'index-prices';
721
+ }
722
+ else {
723
+ candleType = 'trades';
724
+ }
725
+ }
726
+ params = this.omit(params, ['candleType', 'price']);
727
+ const interval = this.safeString(this.timeframes, timeframe, timeframe);
728
+ const messageHash = 'ohlcv:' + symbol + ':' + timeframe + ':' + candleType;
729
+ const query = this.urlencode(this.extend({ 'interval': interval }, params));
730
+ const url = this.urls['api']['ws'] + '/candles/' + market['id'] + '/' + candleType + '?' + query;
731
+ const ohlcv = await this.watch(url, messageHash, undefined, messageHash, {
732
+ 'name': 'ohlcv',
733
+ 'symbol': symbol,
734
+ 'timeframe': timeframe,
735
+ 'candleType': candleType,
736
+ 'limit': limit,
737
+ 'messageHash': messageHash,
738
+ });
739
+ if (this.newUpdates) {
740
+ limit = ohlcv.getLimit(symbol, limit);
741
+ }
742
+ return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
743
+ }
744
+ handleOHLCV(client, message) {
745
+ //
746
+ // {
747
+ // "ts": 1695738675123,
748
+ // "data": [
749
+ // {
750
+ // "T": 1695738674000,
751
+ // "o": "1000.0000",
752
+ // "l": "800.0000",
753
+ // "h": "2400.0000",
754
+ // "c": "2100.0000",
755
+ // "v": "10.0000"
756
+ // }
757
+ // ],
758
+ // "seq": 1
759
+ // }
760
+ //
761
+ const subscription = this.findSubscription(client, 'ohlcv');
762
+ if (subscription === undefined) {
763
+ return;
764
+ }
765
+ const symbol = this.safeString(subscription, 'symbol');
766
+ const timeframe = this.safeString(subscription, 'timeframe');
767
+ const candleType = this.safeString(subscription, 'candleType');
768
+ const cacheKey = (candleType === 'trades') ? timeframe : timeframe + ':' + candleType;
769
+ const messageHash = this.safeString(subscription, 'messageHash');
770
+ this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
771
+ let stored = this.safeValue(this.ohlcvs[symbol], cacheKey);
772
+ if (stored === undefined) {
773
+ const defaultLimit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
774
+ const limit = this.safeInteger(subscription, 'limit', defaultLimit);
775
+ stored = new ArrayCacheByTimestamp(limit);
776
+ this.ohlcvs[symbol][cacheKey] = stored;
777
+ }
778
+ const previousNonce = this.safeInteger(subscription, 'nonce');
779
+ const nonce = this.safeInteger(message, 'seq');
780
+ if ((previousNonce !== undefined) && (nonce !== undefined) && (nonce <= previousNonce)) {
781
+ return;
782
+ }
783
+ subscription['nonce'] = nonce;
784
+ const data = this.safeList(message, 'data', []);
785
+ for (let i = 0; i < data.length; i++) {
786
+ const parsed = this.parseOHLCV(data[i]);
787
+ stored.append(parsed);
788
+ }
789
+ client.resolve(stored, messageHash);
790
+ }
791
+ findSubscription(client, name) {
792
+ const keys = Object.keys(client.subscriptions);
793
+ for (let i = 0; i < keys.length; i++) {
794
+ const key = keys[i];
795
+ const subscription = this.safeDict(client.subscriptions, key);
796
+ const subscriptionName = this.safeString(subscription, 'name');
797
+ if (subscriptionName === name) {
798
+ return subscription;
799
+ }
800
+ }
801
+ return undefined;
802
+ }
803
+ handleErrorMessage(client, message) {
804
+ //
805
+ // { "status": "ERROR", "error": { "code": 1001, "message": "Market not found." } }
806
+ //
807
+ const error = this.safeValue(message, 'error');
808
+ if (error === undefined) {
809
+ return false;
810
+ }
811
+ const feedback = this.id + ' ' + this.json(message);
812
+ const errorCode = this.safeString(error, 'code');
813
+ this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
814
+ const errorMessage = this.safeString(error, 'message');
815
+ this.throwBroadlyMatchedException(this.exceptions['broad'], errorMessage, feedback);
816
+ throw new ExchangeError(feedback);
817
+ }
818
+ handleMessage(client, message) {
819
+ if (this.handleErrorMessage(client, message)) {
820
+ return;
821
+ }
822
+ const type = this.safeString(message, 'type');
823
+ const data = this.safeValue(message, 'data');
824
+ if (Array.isArray(data)) {
825
+ const first = this.safeDict(data, 0, {});
826
+ const side = this.safeString(first, 'S');
827
+ if (side !== undefined) {
828
+ this.handleTrades(client, message);
829
+ }
830
+ else {
831
+ this.handleOHLCV(client, message);
832
+ }
833
+ }
834
+ else if (data !== undefined) {
835
+ if ((type === 'ORDER') || ('orders' in data)) {
836
+ this.handleOrders(client, message);
837
+ }
838
+ if ((type === 'TRADE') || ('trades' in data)) {
839
+ this.handleMyTrades(client, message);
840
+ }
841
+ if ((type === 'POSITION') || ('positions' in data)) {
842
+ this.handlePositions(client, message);
843
+ }
844
+ if ((type === 'BALANCE') || ('balance' in data) || ('spotBalances' in data)) {
845
+ this.handleBalance(client, message);
846
+ }
847
+ if (type === 'MP') {
848
+ this.handleMarkPrice(client, message);
849
+ }
850
+ else if ('f' in data) {
851
+ this.handleFundingRate(client, message);
852
+ }
853
+ else {
854
+ this.handleOrderBook(client, message);
855
+ }
856
+ }
857
+ }
858
+ }