ccxt-ir 4.3.46.0.3__py2.py3-none-any.whl → 4.5.0__py2.py3-none-any.whl

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 (529) hide show
  1. ccxt/__init__.py +39 -35
  2. ccxt/abantether.py +8 -8
  3. ccxt/abstract/alpaca.py +4 -0
  4. ccxt/abstract/apex.py +31 -0
  5. ccxt/abstract/bigone.py +1 -1
  6. ccxt/abstract/binance.py +106 -48
  7. ccxt/abstract/binancecoinm.py +106 -48
  8. ccxt/abstract/binanceus.py +141 -83
  9. ccxt/abstract/binanceusdm.py +106 -48
  10. ccxt/abstract/bingx.py +50 -1
  11. ccxt/abstract/bitbank.py +5 -0
  12. ccxt/abstract/bitfinex.py +136 -65
  13. ccxt/abstract/bitflyer.py +1 -0
  14. ccxt/abstract/bitget.py +67 -0
  15. ccxt/abstract/bitmart.py +19 -1
  16. ccxt/abstract/bitopro.py +1 -0
  17. ccxt/abstract/bitrue.py +68 -68
  18. ccxt/abstract/bitstamp.py +1 -0
  19. ccxt/abstract/blofin.py +30 -0
  20. ccxt/abstract/btcbox.py +2 -0
  21. ccxt/abstract/bybit.py +28 -13
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbaseexchange.py +1 -0
  24. ccxt/abstract/coinbaseinternational.py +1 -1
  25. ccxt/abstract/cryptocom.py +16 -0
  26. ccxt/abstract/cryptomus.py +20 -0
  27. ccxt/abstract/defx.py +69 -0
  28. ccxt/abstract/deribit.py +1 -0
  29. ccxt/abstract/derive.py +117 -0
  30. ccxt/abstract/digifinex.py +1 -0
  31. ccxt/abstract/ellipx.py +25 -0
  32. ccxt/abstract/foxbit.py +26 -0
  33. ccxt/abstract/gate.py +19 -0
  34. ccxt/abstract/gateio.py +19 -0
  35. ccxt/abstract/gemini.py +1 -0
  36. ccxt/abstract/hibachi.py +26 -0
  37. ccxt/abstract/hyperliquid.py +1 -1
  38. ccxt/abstract/independentreserve.py +6 -0
  39. ccxt/abstract/kraken.py +1 -0
  40. ccxt/abstract/krakenfutures.py +4 -0
  41. ccxt/abstract/kucoin.py +10 -0
  42. ccxt/abstract/kucoinfutures.py +18 -0
  43. ccxt/abstract/lbank.py +2 -1
  44. ccxt/abstract/luno.py +1 -0
  45. ccxt/abstract/mexc.py +2 -0
  46. ccxt/abstract/modetrade.py +119 -0
  47. ccxt/abstract/myokx.py +349 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +25 -0
  50. ccxt/abstract/okxus.py +349 -0
  51. ccxt/abstract/onetrading.py +0 -12
  52. ccxt/abstract/paradex.py +23 -0
  53. ccxt/abstract/phemex.py +2 -0
  54. ccxt/abstract/poloniex.py +36 -0
  55. ccxt/abstract/tradeogre.py +3 -1
  56. ccxt/abstract/upbit.py +51 -34
  57. ccxt/abstract/whitebit.py +16 -0
  58. ccxt/abstract/woo.py +64 -6
  59. ccxt/abstract/xt.py +10 -5
  60. ccxt/afratether.py +7 -7
  61. ccxt/alpaca.py +828 -51
  62. ccxt/apex.py +1875 -0
  63. ccxt/arzinja.py +7 -7
  64. ccxt/arzplus.py +9 -9
  65. ccxt/ascendex.py +501 -306
  66. ccxt/async_support/__init__.py +39 -35
  67. ccxt/async_support/abantether.py +8 -8
  68. ccxt/async_support/afratether.py +9 -9
  69. ccxt/async_support/alpaca.py +828 -51
  70. ccxt/async_support/apex.py +1875 -0
  71. ccxt/async_support/arzinja.py +10 -10
  72. ccxt/async_support/arzplus.py +12 -12
  73. ccxt/async_support/ascendex.py +502 -306
  74. ccxt/async_support/base/exchange.py +303 -89
  75. ccxt/async_support/base/ws/cache.py +9 -3
  76. ccxt/async_support/base/ws/client.py +173 -38
  77. ccxt/async_support/base/ws/future.py +25 -37
  78. ccxt/async_support/bequant.py +5 -3
  79. ccxt/async_support/bigone.py +279 -144
  80. ccxt/async_support/binance.py +2347 -1158
  81. ccxt/async_support/binancecoinm.py +9 -3
  82. ccxt/async_support/binanceus.py +17 -3
  83. ccxt/async_support/binanceusdm.py +9 -4
  84. ccxt/async_support/bingx.py +2962 -920
  85. ccxt/async_support/bit2c.py +147 -27
  86. ccxt/async_support/bitbank.py +151 -23
  87. ccxt/async_support/bitbns.py +104 -30
  88. ccxt/async_support/bitfinex.py +3291 -1113
  89. ccxt/async_support/bitflyer.py +202 -27
  90. ccxt/async_support/bitget.py +3683 -1538
  91. ccxt/async_support/bithumb.py +195 -38
  92. ccxt/async_support/bitimen.py +12 -12
  93. ccxt/async_support/bitir.py +38 -38
  94. ccxt/async_support/bitmart.py +1288 -350
  95. ccxt/async_support/bitmex.py +260 -75
  96. ccxt/async_support/bitopro.py +262 -62
  97. ccxt/async_support/bitpin.py +17 -16
  98. ccxt/async_support/bitrue.py +459 -290
  99. ccxt/async_support/bitso.py +199 -54
  100. ccxt/async_support/bitstamp.py +230 -96
  101. ccxt/async_support/bitteam.py +167 -25
  102. ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
  103. ccxt/async_support/bitvavo.py +213 -49
  104. ccxt/async_support/blockchaincom.py +160 -46
  105. ccxt/async_support/blofin.py +502 -120
  106. ccxt/async_support/btcalpha.py +169 -31
  107. ccxt/async_support/btcbox.py +292 -23
  108. ccxt/async_support/btcmarkets.py +211 -58
  109. ccxt/async_support/btcturk.py +161 -38
  110. ccxt/async_support/bybit.py +1775 -1030
  111. ccxt/async_support/cex.py +1440 -1303
  112. ccxt/async_support/coinbase.py +724 -212
  113. ccxt/async_support/coinbaseadvanced.py +2 -1
  114. ccxt/async_support/coinbaseexchange.py +388 -89
  115. ccxt/async_support/coinbaseinternational.py +412 -57
  116. ccxt/async_support/coincatch.py +177 -78
  117. ccxt/async_support/coincheck.py +135 -19
  118. ccxt/async_support/coinex.py +606 -232
  119. ccxt/async_support/coinmate.py +189 -63
  120. ccxt/async_support/coinmetro.py +195 -54
  121. ccxt/async_support/coinone.py +158 -51
  122. ccxt/async_support/coinsph.py +336 -61
  123. ccxt/async_support/coinspot.py +151 -52
  124. ccxt/async_support/cryptocom.py +661 -111
  125. ccxt/async_support/cryptomus.py +1137 -0
  126. ccxt/async_support/defx.py +2071 -0
  127. ccxt/async_support/delta.py +299 -99
  128. ccxt/async_support/deribit.py +348 -126
  129. ccxt/async_support/derive.py +2572 -0
  130. ccxt/async_support/digifinex.py +430 -214
  131. ccxt/async_support/ellipx.py +2029 -0
  132. ccxt/async_support/eterex.py +10 -10
  133. ccxt/async_support/excoino.py +31 -31
  134. ccxt/async_support/exir.py +14 -14
  135. ccxt/async_support/exmo.py +344 -131
  136. ccxt/async_support/exnovin.py +10 -10
  137. ccxt/async_support/farhadexchange.py +12 -12
  138. ccxt/async_support/fmfwio.py +2 -1
  139. ccxt/async_support/foxbit.py +1935 -0
  140. ccxt/async_support/gate.py +1351 -529
  141. ccxt/async_support/gateio.py +2 -1
  142. ccxt/async_support/gemini.py +144 -39
  143. ccxt/async_support/hashkey.py +152 -109
  144. ccxt/async_support/hibachi.py +2080 -0
  145. ccxt/async_support/hitbtc.py +395 -167
  146. ccxt/async_support/hitobit.py +12 -12
  147. ccxt/async_support/hollaex.py +307 -119
  148. ccxt/async_support/htx.py +851 -383
  149. ccxt/async_support/huobi.py +2 -1
  150. ccxt/async_support/hyperliquid.py +1848 -536
  151. ccxt/async_support/independentreserve.py +288 -15
  152. ccxt/async_support/indodax.py +190 -33
  153. ccxt/async_support/jibitex.py +12 -12
  154. ccxt/async_support/kraken.py +795 -351
  155. ccxt/async_support/krakenfutures.py +214 -62
  156. ccxt/async_support/kucoin.py +715 -396
  157. ccxt/async_support/kucoinfutures.py +652 -89
  158. ccxt/async_support/latoken.py +217 -113
  159. ccxt/async_support/lbank.py +425 -97
  160. ccxt/async_support/luno.py +382 -35
  161. ccxt/async_support/mercado.py +113 -6
  162. ccxt/async_support/mexc.py +874 -437
  163. ccxt/async_support/modetrade.py +2818 -0
  164. ccxt/async_support/myokx.py +54 -0
  165. ccxt/async_support/ndax.py +221 -64
  166. ccxt/async_support/nobitex.py +31 -37
  167. ccxt/async_support/novadax.py +190 -34
  168. ccxt/async_support/oceanex.py +217 -28
  169. ccxt/async_support/okcoin.py +253 -145
  170. ccxt/async_support/okexchange.py +11 -11
  171. ccxt/async_support/okx.py +1088 -351
  172. ccxt/async_support/okxus.py +54 -0
  173. ccxt/async_support/ompfinex.py +25 -24
  174. ccxt/async_support/onetrading.py +213 -392
  175. ccxt/async_support/oxfun.py +245 -166
  176. ccxt/async_support/p2b.py +151 -29
  177. ccxt/async_support/paradex.py +562 -49
  178. ccxt/async_support/paymium.py +82 -19
  179. ccxt/async_support/phemex.py +713 -172
  180. ccxt/async_support/poloniex.py +1602 -283
  181. ccxt/async_support/probit.py +224 -95
  182. ccxt/async_support/ramzinex.py +30 -27
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +14 -13
  186. ccxt/async_support/tetherland.py +9 -9
  187. ccxt/async_support/timex.py +210 -51
  188. ccxt/async_support/tokocrypto.py +167 -47
  189. ccxt/async_support/tradeogre.py +266 -31
  190. ccxt/async_support/twox.py +9 -9
  191. ccxt/async_support/ubitex.py +12 -12
  192. ccxt/async_support/upbit.py +568 -165
  193. ccxt/async_support/vertex.py +160 -32
  194. ccxt/async_support/wallex.py +12 -12
  195. ccxt/async_support/wavesexchange.py +165 -30
  196. ccxt/async_support/whitebit.py +975 -127
  197. ccxt/async_support/woo.py +1918 -1016
  198. ccxt/async_support/woofipro.py +433 -141
  199. ccxt/async_support/xt.py +649 -193
  200. ccxt/async_support/yobit.py +195 -70
  201. ccxt/async_support/zaif.py +91 -15
  202. ccxt/async_support/zonda.py +151 -36
  203. ccxt/base/decimal_to_precision.py +14 -10
  204. ccxt/base/errors.py +49 -18
  205. ccxt/base/exchange.py +1556 -450
  206. ccxt/base/precise.py +10 -0
  207. ccxt/base/types.py +114 -6
  208. ccxt/bequant.py +5 -3
  209. ccxt/bigone.py +279 -144
  210. ccxt/binance.py +2347 -1158
  211. ccxt/binancecoinm.py +9 -3
  212. ccxt/binanceus.py +17 -3
  213. ccxt/binanceusdm.py +9 -4
  214. ccxt/bingx.py +2962 -920
  215. ccxt/bit2c.py +147 -27
  216. ccxt/bitbank.py +151 -23
  217. ccxt/bitbns.py +104 -30
  218. ccxt/bitfinex.py +3290 -1113
  219. ccxt/bitflyer.py +202 -27
  220. ccxt/bitget.py +3683 -1538
  221. ccxt/bithumb.py +194 -38
  222. ccxt/bitimen.py +9 -9
  223. ccxt/bitir.py +35 -35
  224. ccxt/bitmart.py +1288 -350
  225. ccxt/bitmex.py +260 -75
  226. ccxt/bitopro.py +262 -62
  227. ccxt/bitpin.py +15 -14
  228. ccxt/bitrue.py +459 -290
  229. ccxt/bitso.py +199 -54
  230. ccxt/bitstamp.py +230 -96
  231. ccxt/bitteam.py +167 -25
  232. ccxt/{huobijp.py → bittrade.py} +158 -30
  233. ccxt/bitvavo.py +213 -49
  234. ccxt/blockchaincom.py +160 -46
  235. ccxt/blofin.py +502 -120
  236. ccxt/btcalpha.py +169 -31
  237. ccxt/btcbox.py +291 -23
  238. ccxt/btcmarkets.py +211 -58
  239. ccxt/btcturk.py +161 -38
  240. ccxt/bybit.py +1775 -1030
  241. ccxt/cex.py +1439 -1303
  242. ccxt/coinbase.py +724 -212
  243. ccxt/coinbaseadvanced.py +2 -1
  244. ccxt/coinbaseexchange.py +388 -89
  245. ccxt/coinbaseinternational.py +412 -57
  246. ccxt/coincatch.py +177 -78
  247. ccxt/coincheck.py +135 -19
  248. ccxt/coinex.py +606 -232
  249. ccxt/coinmate.py +189 -63
  250. ccxt/coinmetro.py +194 -54
  251. ccxt/coinone.py +158 -51
  252. ccxt/coinsph.py +336 -61
  253. ccxt/coinspot.py +151 -52
  254. ccxt/cryptocom.py +661 -111
  255. ccxt/cryptomus.py +1137 -0
  256. ccxt/defx.py +2070 -0
  257. ccxt/delta.py +299 -99
  258. ccxt/deribit.py +348 -126
  259. ccxt/derive.py +2571 -0
  260. ccxt/digifinex.py +430 -214
  261. ccxt/ellipx.py +2029 -0
  262. ccxt/eterex.py +7 -7
  263. ccxt/excoino.py +29 -29
  264. ccxt/exir.py +11 -11
  265. ccxt/exmo.py +343 -131
  266. ccxt/exnovin.py +8 -8
  267. ccxt/farhadexchange.py +10 -10
  268. ccxt/fmfwio.py +2 -1
  269. ccxt/foxbit.py +1935 -0
  270. ccxt/gate.py +1351 -529
  271. ccxt/gateio.py +2 -1
  272. ccxt/gemini.py +144 -39
  273. ccxt/hashkey.py +152 -109
  274. ccxt/hibachi.py +2079 -0
  275. ccxt/hitbtc.py +395 -167
  276. ccxt/hitobit.py +9 -9
  277. ccxt/hollaex.py +307 -119
  278. ccxt/htx.py +851 -383
  279. ccxt/huobi.py +2 -1
  280. ccxt/hyperliquid.py +1848 -536
  281. ccxt/independentreserve.py +287 -15
  282. ccxt/indodax.py +190 -33
  283. ccxt/jibitex.py +9 -9
  284. ccxt/kraken.py +794 -351
  285. ccxt/krakenfutures.py +214 -62
  286. ccxt/kucoin.py +715 -396
  287. ccxt/kucoinfutures.py +652 -89
  288. ccxt/latoken.py +217 -113
  289. ccxt/lbank.py +425 -97
  290. ccxt/luno.py +382 -35
  291. ccxt/mercado.py +113 -6
  292. ccxt/mexc.py +873 -437
  293. ccxt/modetrade.py +2818 -0
  294. ccxt/myokx.py +54 -0
  295. ccxt/ndax.py +221 -64
  296. ccxt/nobitex.py +29 -35
  297. ccxt/novadax.py +190 -34
  298. ccxt/oceanex.py +217 -28
  299. ccxt/okcoin.py +253 -145
  300. ccxt/okexchange.py +9 -9
  301. ccxt/okx.py +1088 -351
  302. ccxt/okxus.py +54 -0
  303. ccxt/ompfinex.py +22 -21
  304. ccxt/onetrading.py +213 -392
  305. ccxt/oxfun.py +245 -166
  306. ccxt/p2b.py +151 -29
  307. ccxt/paradex.py +562 -49
  308. ccxt/paymium.py +82 -19
  309. ccxt/phemex.py +712 -172
  310. ccxt/poloniex.py +1601 -283
  311. ccxt/pro/__init__.py +76 -17
  312. ccxt/pro/alpaca.py +21 -6
  313. ccxt/pro/apex.py +984 -0
  314. ccxt/pro/ascendex.py +58 -10
  315. ccxt/pro/bequant.py +6 -1
  316. ccxt/pro/binance.py +728 -156
  317. ccxt/pro/binancecoinm.py +6 -2
  318. ccxt/pro/binanceus.py +8 -4
  319. ccxt/pro/binanceusdm.py +7 -2
  320. ccxt/pro/bingx.py +333 -142
  321. ccxt/pro/bitfinex.py +727 -262
  322. ccxt/pro/bitget.py +570 -79
  323. ccxt/pro/bithumb.py +20 -6
  324. ccxt/pro/bitmart.py +216 -87
  325. ccxt/pro/bitmex.py +47 -9
  326. ccxt/pro/bitopro.py +26 -14
  327. ccxt/pro/bitrue.py +22 -22
  328. ccxt/pro/bitstamp.py +54 -21
  329. ccxt/pro/{huobijp.py → bittrade.py} +7 -6
  330. ccxt/pro/bitvavo.py +191 -67
  331. ccxt/pro/blockchaincom.py +21 -8
  332. ccxt/pro/blofin.py +9 -1
  333. ccxt/pro/bybit.py +632 -245
  334. ccxt/pro/cex.py +59 -24
  335. ccxt/pro/coinbase.py +102 -73
  336. ccxt/pro/coinbaseadvanced.py +2 -1
  337. ccxt/pro/coinbaseexchange.py +8 -8
  338. ccxt/pro/coinbaseinternational.py +181 -25
  339. ccxt/pro/coincatch.py +6 -7
  340. ccxt/pro/coincheck.py +11 -6
  341. ccxt/pro/coinex.py +967 -665
  342. ccxt/pro/coinone.py +16 -9
  343. ccxt/pro/cryptocom.py +448 -45
  344. ccxt/pro/defx.py +831 -0
  345. ccxt/pro/deribit.py +150 -14
  346. ccxt/pro/derive.py +704 -0
  347. ccxt/pro/exmo.py +239 -6
  348. ccxt/pro/gate.py +623 -65
  349. ccxt/pro/gateio.py +2 -1
  350. ccxt/pro/gemini.py +27 -11
  351. ccxt/pro/hashkey.py +2 -2
  352. ccxt/pro/hitbtc.py +196 -91
  353. ccxt/pro/hollaex.py +23 -7
  354. ccxt/pro/htx.py +51 -14
  355. ccxt/pro/huobi.py +2 -1
  356. ccxt/pro/hyperliquid.py +591 -27
  357. ccxt/pro/independentreserve.py +9 -6
  358. ccxt/pro/kraken.py +640 -320
  359. ccxt/pro/krakenfutures.py +62 -35
  360. ccxt/pro/kucoin.py +267 -46
  361. ccxt/pro/kucoinfutures.py +165 -21
  362. ccxt/pro/lbank.py +102 -21
  363. ccxt/pro/luno.py +12 -8
  364. ccxt/pro/mexc.py +877 -111
  365. ccxt/pro/modetrade.py +1271 -0
  366. ccxt/pro/myokx.py +38 -0
  367. ccxt/pro/ndax.py +15 -2
  368. ccxt/pro/okcoin.py +23 -4
  369. ccxt/pro/okx.py +573 -98
  370. ccxt/pro/okxus.py +38 -0
  371. ccxt/pro/onetrading.py +30 -13
  372. ccxt/pro/oxfun.py +131 -27
  373. ccxt/pro/p2b.py +88 -22
  374. ccxt/pro/paradex.py +3 -3
  375. ccxt/pro/phemex.py +75 -21
  376. ccxt/pro/poloniex.py +124 -41
  377. ccxt/pro/probit.py +87 -80
  378. ccxt/pro/tradeogre.py +272 -0
  379. ccxt/pro/upbit.py +152 -12
  380. ccxt/pro/vertex.py +8 -3
  381. ccxt/pro/whitebit.py +58 -5
  382. ccxt/pro/woo.py +228 -37
  383. ccxt/pro/woofipro.py +106 -18
  384. ccxt/pro/xt.py +111 -5
  385. ccxt/probit.py +224 -95
  386. ccxt/protobuf/__init__.py +0 -0
  387. ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
  388. ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
  389. ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
  390. ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
  391. ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
  392. ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
  393. ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
  394. ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
  395. ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
  396. ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
  397. ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
  398. ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
  399. ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
  400. ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
  401. ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
  402. ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
  403. ccxt/protobuf/mexc/__init__.py +0 -0
  404. ccxt/ramzinex.py +28 -25
  405. ccxt/sarmayex.py +7 -7
  406. ccxt/sarrafex.py +10 -10
  407. ccxt/static_dependencies/__init__.py +1 -1
  408. ccxt/static_dependencies/lark/py.typed +0 -0
  409. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  410. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  411. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  412. ccxt/tabdeal.py +12 -11
  413. ccxt/test/tests_async.py +261 -57
  414. ccxt/test/tests_helpers.py +1 -3
  415. ccxt/test/tests_init.py +4 -3
  416. ccxt/test/tests_sync.py +261 -57
  417. ccxt/tetherland.py +7 -7
  418. ccxt/timex.py +210 -51
  419. ccxt/tokocrypto.py +167 -47
  420. ccxt/tradeogre.py +266 -31
  421. ccxt/twox.py +7 -7
  422. ccxt/ubitex.py +9 -9
  423. ccxt/upbit.py +568 -165
  424. ccxt/vertex.py +160 -32
  425. ccxt/wallex.py +9 -9
  426. ccxt/wavesexchange.py +165 -30
  427. ccxt/whitebit.py +975 -127
  428. ccxt/woo.py +1917 -1016
  429. ccxt/woofipro.py +432 -141
  430. ccxt/xt.py +649 -193
  431. ccxt/yobit.py +194 -70
  432. ccxt/zaif.py +91 -15
  433. ccxt/zonda.py +151 -36
  434. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.0.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info}/WHEEL +1 -1
  437. ccxt/__test__.py +0 -7
  438. ccxt/abstract/ace.py +0 -15
  439. ccxt/abstract/bitbay.py +0 -53
  440. ccxt/abstract/bitcoincom.py +0 -115
  441. ccxt/abstract/bitfinex2.py +0 -139
  442. ccxt/abstract/bitpanda.py +0 -35
  443. ccxt/abstract/bl3p.py +0 -19
  444. ccxt/abstract/coinlist.py +0 -54
  445. ccxt/abstract/currencycom.py +0 -68
  446. ccxt/abstract/hitbtc3.py +0 -115
  447. ccxt/abstract/idex.py +0 -26
  448. ccxt/abstract/kuna.py +0 -182
  449. ccxt/abstract/lykke.py +0 -29
  450. ccxt/abstract/poloniexfutures.py +0 -48
  451. ccxt/abstract/wazirx.py +0 -30
  452. ccxt/ace.py +0 -1012
  453. ccxt/async_support/ace.py +0 -1012
  454. ccxt/async_support/base/ws/aiohttp_client.py +0 -125
  455. ccxt/async_support/base/ws/fast_client.py +0 -96
  456. ccxt/async_support/bitbay.py +0 -17
  457. ccxt/async_support/bitcoincom.py +0 -17
  458. ccxt/async_support/bitfinex2.py +0 -3552
  459. ccxt/async_support/bitpanda.py +0 -16
  460. ccxt/async_support/bl3p.py +0 -485
  461. ccxt/async_support/coinlist.py +0 -2243
  462. ccxt/async_support/currencycom.py +0 -1950
  463. ccxt/async_support/hitbtc3.py +0 -16
  464. ccxt/async_support/idex.py +0 -1766
  465. ccxt/async_support/kuna.py +0 -1841
  466. ccxt/async_support/lykke.py +0 -1270
  467. ccxt/async_support/poloniexfutures.py +0 -1717
  468. ccxt/async_support/wazirx.py +0 -1224
  469. ccxt/bitbay.py +0 -17
  470. ccxt/bitcoincom.py +0 -17
  471. ccxt/bitfinex2.py +0 -3552
  472. ccxt/bitpanda.py +0 -16
  473. ccxt/bl3p.py +0 -485
  474. ccxt/coinlist.py +0 -2243
  475. ccxt/currencycom.py +0 -1950
  476. ccxt/hitbtc3.py +0 -16
  477. ccxt/idex.py +0 -1766
  478. ccxt/kuna.py +0 -1841
  479. ccxt/lykke.py +0 -1270
  480. ccxt/poloniexfutures.py +0 -1717
  481. ccxt/pro/bitcoincom.py +0 -34
  482. ccxt/pro/bitfinex2.py +0 -1083
  483. ccxt/pro/bitpanda.py +0 -15
  484. ccxt/pro/currencycom.py +0 -536
  485. ccxt/pro/idex.py +0 -672
  486. ccxt/pro/poloniexfutures.py +0 -990
  487. ccxt/pro/wazirx.py +0 -749
  488. ccxt/test/base/__init__.py +0 -29
  489. ccxt/test/base/test_account.py +0 -26
  490. ccxt/test/base/test_balance.py +0 -56
  491. ccxt/test/base/test_borrow_interest.py +0 -35
  492. ccxt/test/base/test_borrow_rate.py +0 -32
  493. ccxt/test/base/test_calculate_fee.py +0 -51
  494. ccxt/test/base/test_crypto.py +0 -127
  495. ccxt/test/base/test_currency.py +0 -76
  496. ccxt/test/base/test_datetime.py +0 -109
  497. ccxt/test/base/test_decimal_to_precision.py +0 -392
  498. ccxt/test/base/test_deep_extend.py +0 -68
  499. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  500. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  501. ccxt/test/base/test_funding_rate_history.py +0 -29
  502. ccxt/test/base/test_last_price.py +0 -31
  503. ccxt/test/base/test_ledger_entry.py +0 -45
  504. ccxt/test/base/test_ledger_item.py +0 -48
  505. ccxt/test/base/test_leverage_tier.py +0 -33
  506. ccxt/test/base/test_liquidation.py +0 -50
  507. ccxt/test/base/test_margin_mode.py +0 -24
  508. ccxt/test/base/test_margin_modification.py +0 -35
  509. ccxt/test/base/test_market.py +0 -193
  510. ccxt/test/base/test_number.py +0 -411
  511. ccxt/test/base/test_ohlcv.py +0 -33
  512. ccxt/test/base/test_open_interest.py +0 -32
  513. ccxt/test/base/test_order.py +0 -64
  514. ccxt/test/base/test_order_book.py +0 -69
  515. ccxt/test/base/test_position.py +0 -60
  516. ccxt/test/base/test_shared_methods.py +0 -353
  517. ccxt/test/base/test_status.py +0 -24
  518. ccxt/test/base/test_throttle.py +0 -126
  519. ccxt/test/base/test_ticker.py +0 -92
  520. ccxt/test/base/test_trade.py +0 -47
  521. ccxt/test/base/test_trading_fee.py +0 -26
  522. ccxt/test/base/test_transaction.py +0 -39
  523. ccxt/test/test_async.py +0 -1649
  524. ccxt/test/test_sync.py +0 -1648
  525. ccxt/wazirx.py +0 -1224
  526. ccxt_ir-4.3.46.0.3.dist-info/RECORD +0 -773
  527. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  528. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info/licenses}/LICENSE.txt +0 -0
  529. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info}/top_level.txt +0 -0
ccxt/pro/bingx.py CHANGED
@@ -5,23 +5,23 @@
5
5
 
6
6
  import ccxt.async_support
7
7
  from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
8
- from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Strings, Ticker, Tickers, Trade
8
+ from ccxt.base.types import Any, Balances, Int, Order, OrderBook, Str, Strings, Ticker, Tickers, Trade
9
9
  from ccxt.async_support.base.ws.client import Client
10
10
  from typing import List
11
11
  from ccxt.base.errors import ArgumentsRequired
12
12
  from ccxt.base.errors import BadRequest
13
13
  from ccxt.base.errors import NotSupported
14
14
  from ccxt.base.errors import NetworkError
15
- from ccxt.base.precise import Precise
16
15
 
17
16
 
18
17
  class bingx(ccxt.async_support.bingx):
19
18
 
20
- def describe(self):
19
+ def describe(self) -> Any:
21
20
  return self.deep_extend(super(bingx, self).describe(), {
22
21
  'has': {
23
22
  'ws': True,
24
23
  'watchTrades': True,
24
+ 'watchTradesForSymbols': False,
25
25
  'watchOrderBook': True,
26
26
  'watchOrderBookForSymbols': True,
27
27
  'watchOHLCV': True,
@@ -36,12 +36,13 @@ class bingx(ccxt.async_support.bingx):
36
36
  'api': {
37
37
  'ws': {
38
38
  'spot': 'wss://open-api-ws.bingx.com/market',
39
- 'swap': 'wss://open-api-swap.bingx.com/swap-market',
39
+ 'linear': 'wss://open-api-swap.bingx.com/swap-market',
40
+ 'inverse': 'wss://open-api-cswap-ws.bingx.com/market',
40
41
  },
41
42
  },
42
43
  },
43
44
  'options': {
44
- 'listenKeyRefreshRate': 3540000, # 1 hour(59 mins so we have 1min to renew the token)
45
+ 'listenKeyRefreshRate': 3540000, # 1 hour(59 mins so we have 1 min to renew the token)
45
46
  'ws': {
46
47
  'gunzip': True,
47
48
  },
@@ -85,6 +86,9 @@ class bingx(ccxt.async_support.bingx):
85
86
  'depth': 100, # 5, 10, 20, 50, 100
86
87
  'interval': 500, # 100, 200, 500, 1000
87
88
  },
89
+ 'watchTrades': {
90
+ 'ignoreDuplicates': True,
91
+ },
88
92
  },
89
93
  'streaming': {
90
94
  'keepAlive': 1800000, # 30 minutes
@@ -94,17 +98,26 @@ class bingx(ccxt.async_support.bingx):
94
98
  async def watch_ticker(self, symbol: str, params={}) -> Ticker:
95
99
  """
96
100
  watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
97
- :see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20to%2024-hour%20price%20changes
101
+
102
+ https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#Subscribe%20to%2024-hour%20Price%20Change
103
+ https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20to%2024-hour%20price%20changes
104
+ https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%2024-Hour%20Price%20Change
105
+
98
106
  :param str symbol: unified symbol of the market to fetch the ticker for
99
107
  :param dict [params]: extra parameters specific to the exchange API endpoint
100
108
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
101
109
  """
102
110
  await self.load_markets()
103
111
  market = self.market(symbol)
104
- marketType, query = self.handle_market_type_and_params('watchTrades', market, params)
105
- url = self.safe_value(self.urls['api']['ws'], marketType)
106
- if url is None:
107
- raise BadRequest(self.id + ' watchTrades is not supported for ' + marketType + ' markets.')
112
+ marketType = None
113
+ subType = None
114
+ url = None
115
+ marketType, params = self.handle_market_type_and_params('watchTicker', market, params)
116
+ subType, params = self.handle_sub_type_and_params('watchTicker', market, params, 'linear')
117
+ if marketType == 'swap':
118
+ url = self.safe_string(self.urls['api']['ws'], subType)
119
+ else:
120
+ url = self.safe_string(self.urls['api']['ws'], marketType)
108
121
  subscriptionHash = market['id'] + '@ticker'
109
122
  messageHash = self.get_message_hash('ticker', market['symbol'])
110
123
  uuid = self.uuid()
@@ -114,7 +127,7 @@ class bingx(ccxt.async_support.bingx):
114
127
  }
115
128
  if marketType == 'swap':
116
129
  request['reqType'] = 'sub'
117
- return await self.watch(url, messageHash, self.extend(request, query), subscriptionHash)
130
+ return await self.watch(url, messageHash, self.extend(request, params), subscriptionHash)
118
131
 
119
132
  def handle_ticker(self, client: Client, message):
120
133
  #
@@ -237,7 +250,9 @@ class bingx(ccxt.async_support.bingx):
237
250
  async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
238
251
  """
239
252
  watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
240
- :see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20to%2024-hour%20price%20changes%20of%20all%20trading%20pairs
253
+
254
+ https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20to%2024-hour%20price%20changes%20of%20all%20trading%20pairs
255
+
241
256
  :param str[] symbols: unified symbol of the market to watch the tickers for
242
257
  :param dict [params]: extra parameters specific to the exchange API endpoint
243
258
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -246,12 +261,16 @@ class bingx(ccxt.async_support.bingx):
246
261
  symbols = self.market_symbols(symbols, None, True, True, False)
247
262
  firstMarket = None
248
263
  marketType = None
264
+ subType = None
249
265
  symbolsDefined = (symbols is not None)
250
266
  if symbolsDefined:
251
267
  firstMarket = self.market(symbols[0])
252
268
  marketType, params = self.handle_market_type_and_params('watchTickers', firstMarket, params)
269
+ subType, params = self.handle_sub_type_and_params('watchTickers', firstMarket, params, 'linear')
253
270
  if marketType == 'spot':
254
271
  raise NotSupported(self.id + ' watchTickers is not supported for spot markets yet')
272
+ if subType == 'inverse':
273
+ raise NotSupported(self.id + ' watchTickers is not supported for inverse markets yet')
255
274
  messageHashes = []
256
275
  subscriptionHashes = ['all@ticker']
257
276
  if symbolsDefined:
@@ -261,7 +280,7 @@ class bingx(ccxt.async_support.bingx):
261
280
  messageHashes.append(self.get_message_hash('ticker', market['symbol']))
262
281
  else:
263
282
  messageHashes.append(self.get_message_hash('ticker'))
264
- url = self.safe_string(self.urls['api']['ws'], marketType)
283
+ url = self.safe_string(self.urls['api']['ws'], subType)
265
284
  uuid = self.uuid()
266
285
  request: dict = {
267
286
  'id': uuid,
@@ -279,7 +298,9 @@ class bingx(ccxt.async_support.bingx):
279
298
  async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
280
299
  """
281
300
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
282
- :see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20Market%20Depth%20Data%20of%20all%20trading%20pairs
301
+
302
+ https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20Market%20Depth%20Data%20of%20all%20trading%20pairs
303
+
283
304
  :param str[] symbols: unified array of symbols
284
305
  :param int [limit]: the maximum amount of order book entries to return
285
306
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -288,12 +309,16 @@ class bingx(ccxt.async_support.bingx):
288
309
  symbols = self.market_symbols(symbols, None, True, True, False)
289
310
  firstMarket = None
290
311
  marketType = None
312
+ subType = None
291
313
  symbolsDefined = (symbols is not None)
292
314
  if symbolsDefined:
293
315
  firstMarket = self.market(symbols[0])
294
316
  marketType, params = self.handle_market_type_and_params('watchOrderBookForSymbols', firstMarket, params)
317
+ subType, params = self.handle_sub_type_and_params('watchOrderBookForSymbols', firstMarket, params, 'linear')
295
318
  if marketType == 'spot':
296
319
  raise NotSupported(self.id + ' watchOrderBookForSymbols is not supported for spot markets yet')
320
+ if subType == 'inverse':
321
+ raise NotSupported(self.id + ' watchOrderBookForSymbols is not supported for inverse markets yet')
297
322
  limit = self.get_order_book_limit_by_market_type(marketType, limit)
298
323
  interval = None
299
324
  interval, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'interval', 500)
@@ -308,7 +333,7 @@ class bingx(ccxt.async_support.bingx):
308
333
  messageHashes.append(self.get_message_hash('orderbook', market['symbol']))
309
334
  else:
310
335
  messageHashes.append(self.get_message_hash('orderbook'))
311
- url = self.safe_string(self.urls['api']['ws'], marketType)
336
+ url = self.safe_string(self.urls['api']['ws'], subType)
312
337
  uuid = self.uuid()
313
338
  request: dict = {
314
339
  'id': uuid,
@@ -328,6 +353,9 @@ class bingx(ccxt.async_support.bingx):
328
353
  async def watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], since: Int = None, limit: Int = None, params={}):
329
354
  """
330
355
  watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
356
+
357
+ https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20K-Line%20Data%20of%20all%20trading%20pairs
358
+
331
359
  :param str[][] symbolsAndTimeframes: array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
332
360
  :param int [since]: timestamp in ms of the earliest candle to fetch
333
361
  :param int [limit]: the maximum amount of candles to fetch
@@ -340,14 +368,19 @@ class bingx(ccxt.async_support.bingx):
340
368
  await self.load_markets()
341
369
  messageHashes = []
342
370
  marketType = None
371
+ subType = None
343
372
  chosenTimeframe = None
373
+ firstMarket = None
344
374
  if symbolsLength != 0:
345
375
  symbols = self.get_list_from_object_values(symbolsAndTimeframes, 0)
346
376
  symbols = self.market_symbols(symbols, None, True, True, False)
347
377
  firstMarket = self.market(symbols[0])
348
- marketType, params = self.handle_market_type_and_params('watchOrderBookForSymbols', firstMarket, params)
349
- if marketType == 'spot':
350
- raise NotSupported(self.id + ' watchOrderBookForSymbols is not supported for spot markets yet')
378
+ marketType, params = self.handle_market_type_and_params('watchOHLCVForSymbols', firstMarket, params)
379
+ subType, params = self.handle_sub_type_and_params('watchOHLCVForSymbols', firstMarket, params, 'linear')
380
+ if marketType == 'spot':
381
+ raise NotSupported(self.id + ' watchOHLCVForSymbols is not supported for spot markets yet')
382
+ if subType == 'inverse':
383
+ raise NotSupported(self.id + ' watchOHLCVForSymbols is not supported for inverse markets yet')
351
384
  marketOptions = self.safe_dict(self.options, marketType)
352
385
  timeframes = self.safe_dict(marketOptions, 'timeframes', {})
353
386
  for i in range(0, len(symbolsAndTimeframes)):
@@ -362,7 +395,7 @@ class bingx(ccxt.async_support.bingx):
362
395
  raise BadRequest(self.id + ' watchOHLCVForSymbols requires all timeframes to be the same')
363
396
  messageHashes.append(self.get_message_hash('ohlcv', market['symbol'], chosenTimeframe))
364
397
  subscriptionHash = 'all@kline_' + chosenTimeframe
365
- url = self.safe_string(self.urls['api']['ws'], marketType)
398
+ url = self.safe_string(self.urls['api']['ws'], subType)
366
399
  uuid = self.uuid()
367
400
  request: dict = {
368
401
  'id': uuid,
@@ -403,37 +436,51 @@ class bingx(ccxt.async_support.bingx):
403
436
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
404
437
  """
405
438
  watches information on multiple trades made in a market
406
- :see: https://bingx-api.github.io/docs/#/spot/socket/market.html#Subscribe%20to%20tick-by-tick
407
- :see: https://bingx-api.github.io/docs/#/swapV2/socket/market.html#Subscribe%20the%20Latest%20Trade%20Detail
439
+
440
+ https://bingx-api.github.io/docs/#/spot/socket/market.html#Subscribe%20to%20tick-by-tick
441
+ https://bingx-api.github.io/docs/#/swapV2/socket/market.html#Subscribe%20the%20Latest%20Trade%20Detail
442
+ https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscription%20transaction%20by%20transaction
443
+
408
444
  :param str symbol: unified market symbol of the market orders were made in
409
445
  :param int [since]: the earliest time in ms to fetch orders for
410
446
  :param int [limit]: the maximum number of order structures to retrieve
411
447
  :param dict [params]: extra parameters specific to the exchange API endpoint
412
- :returns dict[]: a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
448
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
413
449
  """
414
450
  await self.load_markets()
415
451
  market = self.market(symbol)
416
- marketType, query = self.handle_market_type_and_params('watchTrades', market, params)
417
- url = self.safe_value(self.urls['api']['ws'], marketType)
418
- if url is None:
419
- raise BadRequest(self.id + ' watchTrades is not supported for ' + marketType + ' markets.')
420
- messageHash = market['id'] + '@trade'
452
+ symbol = market['symbol']
453
+ marketType = None
454
+ subType = None
455
+ url = None
456
+ marketType, params = self.handle_market_type_and_params('watchTrades', market, params)
457
+ subType, params = self.handle_sub_type_and_params('watchTrades', market, params, 'linear')
458
+ if marketType == 'swap':
459
+ url = self.safe_string(self.urls['api']['ws'], subType)
460
+ else:
461
+ url = self.safe_string(self.urls['api']['ws'], marketType)
462
+ rawHash = market['id'] + '@trade'
463
+ messageHash = 'trade::' + symbol
421
464
  uuid = self.uuid()
422
465
  request: dict = {
423
466
  'id': uuid,
424
- 'dataType': messageHash,
467
+ 'dataType': rawHash,
425
468
  }
426
469
  if marketType == 'swap':
427
470
  request['reqType'] = 'sub'
428
- trades = await self.watch(url, messageHash, self.extend(request, query), messageHash)
471
+ trades = await self.watch(url, messageHash, self.extend(request, params), messageHash)
429
472
  if self.newUpdates:
430
473
  limit = trades.getLimit(symbol, limit)
431
- return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
474
+ result = self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
475
+ if self.handle_option('watchTrades', 'ignoreDuplicates', True):
476
+ filtered = self.remove_repeated_trades_from_array(result)
477
+ filtered = self.sort_by(filtered, 'timestamp')
478
+ return filtered
479
+ return result
432
480
 
433
481
  def handle_trades(self, client: Client, message):
434
482
  #
435
- # spot
436
- # first snapshot
483
+ # spot: first snapshot
437
484
  #
438
485
  # {
439
486
  # "id": "d83b78ce-98be-4dc2-b847-12fe471b5bc5",
@@ -442,7 +489,7 @@ class bingx(ccxt.async_support.bingx):
442
489
  # "timestamp": 1690214699854
443
490
  # }
444
491
  #
445
- # subsequent updates
492
+ # spot: subsequent updates
446
493
  #
447
494
  # {
448
495
  # "code": 0,
@@ -460,9 +507,7 @@ class bingx(ccxt.async_support.bingx):
460
507
  # "success": True
461
508
  # }
462
509
  #
463
- #
464
- # swap
465
- # first snapshot
510
+ # linear swap: first snapshot
466
511
  #
467
512
  # {
468
513
  # "id": "2aed93b1-6e1e-4038-aeba-f5eeaec2ca48",
@@ -472,8 +517,7 @@ class bingx(ccxt.async_support.bingx):
472
517
  # "data": null
473
518
  # }
474
519
  #
475
- # subsequent updates
476
- #
520
+ # linear swap: subsequent updates
477
521
  #
478
522
  # {
479
523
  # "code": 0,
@@ -490,13 +534,40 @@ class bingx(ccxt.async_support.bingx):
490
534
  # ]
491
535
  # }
492
536
  #
537
+ # inverse swap: first snapshot
538
+ #
539
+ # {
540
+ # "code": 0,
541
+ # "id": "a2e482ca-f71b-42f8-a83a-8ff85a713e64",
542
+ # "msg": "SUCCESS",
543
+ # "timestamp": 1722920589426
544
+ # }
545
+ #
546
+ # inverse swap: subsequent updates
547
+ #
548
+ # {
549
+ # "code": 0,
550
+ # "dataType": "BTC-USD@trade",
551
+ # "data": {
552
+ # "e": "trade",
553
+ # "E": 1722920589665,
554
+ # "s": "BTC-USD",
555
+ # "t": "39125001",
556
+ # "p": "55360.0",
557
+ # "q": "1",
558
+ # "T": 1722920589582,
559
+ # "m": False
560
+ # }
561
+ # }
562
+ #
493
563
  data = self.safe_value(message, 'data', [])
494
- messageHash = self.safe_string(message, 'dataType')
495
- marketId = messageHash.split('@')[0]
564
+ rawHash = self.safe_string(message, 'dataType')
565
+ marketId = rawHash.split('@')[0]
496
566
  isSwap = client.url.find('swap') >= 0
497
567
  marketType = 'swap' if isSwap else 'spot'
498
568
  market = self.safe_market(marketId, None, None, marketType)
499
569
  symbol = market['symbol']
570
+ messageHash = 'trade::' + symbol
500
571
  trades = None
501
572
  if isinstance(data, list):
502
573
  trades = self.parse_trades(data, market)
@@ -514,8 +585,11 @@ class bingx(ccxt.async_support.bingx):
514
585
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
515
586
  """
516
587
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
517
- :see: https://bingx-api.github.io/docs/#/spot/socket/market.html#Subscribe%20Market%20Depth%20Data
518
- :see: https://bingx-api.github.io/docs/#/swapV2/socket/market.html#Subscribe%20Market%20Depth%20Data
588
+
589
+ https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#Subscribe%20Market%20Depth%20Data
590
+ https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20Market%20Depth%20Data
591
+ https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%20Limited%20Depth
592
+
519
593
  :param str symbol: unified symbol of the market to fetch the order book for
520
594
  :param int [limit]: the maximum amount of order book entries to return
521
595
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -523,17 +597,23 @@ class bingx(ccxt.async_support.bingx):
523
597
  """
524
598
  await self.load_markets()
525
599
  market = self.market(symbol)
526
- marketType, query = self.handle_market_type_and_params('watchOrderBook', market, params)
600
+ marketType = None
601
+ subType = None
602
+ url = None
603
+ marketType, params = self.handle_market_type_and_params('watchOrderBook', market, params)
604
+ subType, params = self.handle_sub_type_and_params('watchOrderBook', market, params, 'linear')
605
+ if marketType == 'swap':
606
+ url = self.safe_string(self.urls['api']['ws'], subType)
607
+ else:
608
+ url = self.safe_string(self.urls['api']['ws'], marketType)
527
609
  limit = self.get_order_book_limit_by_market_type(marketType, limit)
528
610
  channelName = 'depth' + str(limit)
529
- url = self.safe_value(self.urls['api']['ws'], marketType)
530
- if url is None:
531
- raise BadRequest(self.id + ' watchOrderBook is not supported for ' + marketType + ' markets.')
532
611
  interval = None
533
612
  if marketType != 'spot':
534
- interval, params = self.handle_option_and_params(params, 'watchOrderBook', 'interval', 500)
535
- self.check_required_argument('watchOrderBook', interval, 'interval', [100, 200, 500, 1000])
536
- channelName = channelName + '@' + str(interval) + 'ms'
613
+ if not market['inverse']:
614
+ interval, params = self.handle_option_and_params(params, 'watchOrderBook', 'interval', 500)
615
+ self.check_required_argument('watchOrderBook', interval, 'interval', [100, 200, 500, 1000])
616
+ channelName = channelName + '@' + str(interval) + 'ms'
537
617
  subscriptionHash = market['id'] + '@' + channelName
538
618
  messageHash = self.get_message_hash('orderbook', market['symbol'])
539
619
  uuid = self.uuid()
@@ -543,59 +623,93 @@ class bingx(ccxt.async_support.bingx):
543
623
  }
544
624
  if marketType == 'swap':
545
625
  request['reqType'] = 'sub'
546
- subscriptionArgs: dict = {
547
- 'limit': limit,
548
- 'interval': interval,
549
- 'params': params,
550
- }
551
- orderbook = await self.watch(url, messageHash, self.deep_extend(request, query), subscriptionHash, subscriptionArgs)
626
+ subscriptionArgs: dict = {}
627
+ if market['inverse']:
628
+ subscriptionArgs = {
629
+ 'count': limit,
630
+ 'params': params,
631
+ }
632
+ else:
633
+ subscriptionArgs = {
634
+ 'level': limit,
635
+ 'interval': interval,
636
+ 'params': params,
637
+ }
638
+ orderbook = await self.watch(url, messageHash, self.deep_extend(request, params), subscriptionHash, subscriptionArgs)
552
639
  return orderbook.limit()
553
640
 
554
641
  def handle_delta(self, bookside, delta):
555
- price = self.safe_float(delta, 0)
556
- amount = self.safe_float(delta, 1)
642
+ price = self.safe_float_2(delta, 0, 'p')
643
+ amount = self.safe_float_2(delta, 1, 'a')
557
644
  bookside.store(price, amount)
558
645
 
559
646
  def handle_order_book(self, client: Client, message):
560
647
  #
561
648
  # spot
562
649
  #
650
+ # {
651
+ # "code":0,
652
+ # "data":
653
+ # {
654
+ # "asks":[
655
+ # ["84119.73","0.000011"],
656
+ # ["84116.52","0.000014"],
657
+ # ["84116.40","0.000039"]
658
+ # ],
659
+ # "bids":[
660
+ # ["83656.98","2.570805"],
661
+ # ["83655.51","0.000347"],
662
+ # ["83654.59","0.000082"]
663
+ # ],
664
+ # "lastUpdateId":13565694850
665
+ # },
666
+ # "dataType":"BTC-USDT@depth100",
667
+ # "success":true,
668
+ # "timestamp":1743241379958
669
+ # }
563
670
  #
564
- # {
565
- # "code": 0,
566
- # "dataType": "BTC-USDT@depth20",
567
- # "data": {
568
- # "bids": [
569
- # ['28852.9', "34.2621"],
570
- # ...
571
- # ],
572
- # "asks": [
573
- # ['28864.9', "23.4079"],
574
- # ...
575
- # ]
576
- # },
577
- # "dataType": "BTC-USDT@depth20",
578
- # "success": True
579
- # }
671
+ # linear swap
580
672
  #
581
- # swap
673
+ # {
674
+ # "code":0,
675
+ # "dataType":"BTC-USDT@depth100@500ms",
676
+ # "ts":1743241563651,
677
+ # "data":
678
+ # {
679
+ # "bids":[
680
+ # ["83363.2","0.1908"],
681
+ # ["83360.0","0.0003"],
682
+ # ["83356.5","0.0245"],
683
+ # ],
684
+ # "asks":[
685
+ # ["83495.0","0.0024"],
686
+ # ["83490.0","0.0001"],
687
+ # ["83488.0","0.0004"],
688
+ # ]
689
+ # }
690
+ # }
582
691
  #
692
+ # inverse swap
583
693
  #
584
- # {
585
- # "code": 0,
586
- # "dataType": "BTC-USDT@depth20@100ms", #or "all@depth20@100ms"
587
- # "data": {
588
- # "bids": [
589
- # ['28852.9', "34.2621"],
590
- # ...
591
- # ],
592
- # "asks": [
593
- # ['28864.9', "23.4079"],
594
- # ...
595
- # ],
596
- # "symbol": "BTC-USDT", # self key exists only in "all" subscription
597
- # }
598
- # }
694
+ # {
695
+ # "code":0,
696
+ # "dataType":"BTC-USD@depth100",
697
+ # "data":{
698
+ # "symbol":"BTC-USD",
699
+ # "bids":[
700
+ # {"p":"83411.2","a":"2.979216","v":"2485.0"},
701
+ # {"p":"83411.1","a":"1.592114","v":"1328.0"},
702
+ # {"p":"83410.8","a":"2.656730","v":"2216.0"},
703
+ # ],
704
+ # "asks":[
705
+ # {"p":"88200.0","a":"0.344671","v":"304.0"},
706
+ # {"p":"88023.8","a":"0.045442","v":"40.0"},
707
+ # {"p":"88001.0","a":"0.003409","v":"3.0"},
708
+ # ],
709
+ # "aggPrecision":"0.1",
710
+ # "timestamp":1743242290710
711
+ # }
712
+ # }
599
713
  #
600
714
  data = self.safe_dict(message, 'data', {})
601
715
  dataType = self.safe_string(message, 'dataType')
@@ -607,16 +721,24 @@ class bingx(ccxt.async_support.bingx):
607
721
  marketType = 'swap' if isSwap else 'spot'
608
722
  market = self.safe_market(marketId, None, None, marketType)
609
723
  symbol = market['symbol']
610
- if self.safe_value(self.orderbooks, symbol) is None:
724
+ orderbook = self.safe_value(self.orderbooks, symbol)
725
+ if orderbook is None:
611
726
  # limit = [5, 10, 20, 50, 100]
612
727
  subscriptionHash = dataType
613
728
  subscription = client.subscriptions[subscriptionHash]
614
729
  limit = self.safe_integer(subscription, 'limit')
615
730
  self.orderbooks[symbol] = self.order_book({}, limit)
616
731
  orderbook = self.orderbooks[symbol]
617
- snapshot = self.parse_order_book(data, symbol, None, 'bids', 'asks', 0, 1)
732
+ snapshot = None
733
+ timestamp = self.safe_integer_2(message, 'timestamp', 'ts')
734
+ timestamp = self.safe_integer_2(data, 'timestamp', 'ts', timestamp)
735
+ if market['inverse']:
736
+ snapshot = self.parse_order_book(data, symbol, timestamp, 'bids', 'asks', 'p', 'a')
737
+ else:
738
+ snapshot = self.parse_order_book(data, symbol, timestamp, 'bids', 'asks', 0, 1)
739
+ nonce = self.safe_integer(data, 'lastUpdateId')
740
+ snapshot['nonce'] = nonce
618
741
  orderbook.reset(snapshot)
619
- self.orderbooks[symbol] = orderbook
620
742
  messageHash = self.get_message_hash('orderbook', symbol)
621
743
  client.resolve(orderbook, messageHash)
622
744
  # resolve for "all"
@@ -637,8 +759,10 @@ class bingx(ccxt.async_support.bingx):
637
759
  # }
638
760
  #
639
761
  # for spot, opening-time(t) is used instead of closing-time(T), to be compatible with fetchOHLCV
640
- # for swap,(T) is the opening time
762
+ # for linear swap,(T) is the opening time
641
763
  timestamp = 't' if (market['spot']) else 'T'
764
+ if market['swap']:
765
+ timestamp = 't' if (market['inverse']) else 'T'
642
766
  return [
643
767
  self.safe_integer(ohlcv, timestamp),
644
768
  self.safe_number(ohlcv, 'o'),
@@ -650,7 +774,7 @@ class bingx(ccxt.async_support.bingx):
650
774
 
651
775
  def handle_ohlcv(self, client: Client, message):
652
776
  #
653
- # spot
777
+ # spot:
654
778
  #
655
779
  # {
656
780
  # "code": 0,
@@ -676,7 +800,8 @@ class bingx(ccxt.async_support.bingx):
676
800
  # "success": True
677
801
  # }
678
802
  #
679
- # swap
803
+ # linear swap:
804
+ #
680
805
  # {
681
806
  # "code": 0,
682
807
  # "dataType": "BTC-USDT@kline_1m",
@@ -693,20 +818,42 @@ class bingx(ccxt.async_support.bingx):
693
818
  # ]
694
819
  # }
695
820
  #
696
- data = self.safe_list(message, 'data', [])
697
- candles = None
698
- if isinstance(data, list):
699
- candles = data
700
- else:
701
- candles = [self.safe_list(data, 'K', [])]
702
- dataType = self.safe_string(message, 'dataType')
821
+ # inverse swap:
822
+ #
823
+ # {
824
+ # "code": 0,
825
+ # "timestamp": 1723769354547,
826
+ # "dataType": "BTC-USD@kline_1m",
827
+ # "data": {
828
+ # "t": 1723769340000,
829
+ # "o": 57485.1,
830
+ # "c": 57468,
831
+ # "l": 57464.9,
832
+ # "h": 57485.1,
833
+ # "a": 0.189663,
834
+ # "v": 109,
835
+ # "u": 92,
836
+ # "s": "BTC-USD"
837
+ # }
838
+ # }
839
+ #
703
840
  isSwap = client.url.find('swap') >= 0
841
+ dataType = self.safe_string(message, 'dataType')
704
842
  parts = dataType.split('@')
705
843
  firstPart = parts[0]
706
844
  isAllEndpoint = (firstPart == 'all')
707
845
  marketId = self.safe_string(message, 's', firstPart)
708
846
  marketType = 'swap' if isSwap else 'spot'
709
847
  market = self.safe_market(marketId, None, None, marketType)
848
+ candles = None
849
+ if isSwap:
850
+ if market['inverse']:
851
+ candles = [self.safe_dict(message, 'data', {})]
852
+ else:
853
+ candles = self.safe_list(message, 'data', [])
854
+ else:
855
+ data = self.safe_dict(message, 'data', {})
856
+ candles = [self.safe_dict(data, 'K', {})]
710
857
  symbol = market['symbol']
711
858
  self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
712
859
  rawTimeframe = dataType.split('_')[1]
@@ -734,8 +881,11 @@ class bingx(ccxt.async_support.bingx):
734
881
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
735
882
  """
736
883
  watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
737
- :see: https://bingx-api.github.io/docs/#/spot/socket/market.html#K%E7%BA%BF%20Streams
738
- :see: https://bingx-api.github.io/docs/#/swapV2/socket/market.html#Subscribe%20K-Line%20Data
884
+
885
+ https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#K-line%20Streams
886
+ https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20K-Line%20Data
887
+ https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%20Latest%20Trading%20Pair%20K-Line
888
+
739
889
  :param str symbol: unified symbol of the market to fetch OHLCV data for
740
890
  :param str timeframe: the length of time each candle represents
741
891
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -745,8 +895,15 @@ class bingx(ccxt.async_support.bingx):
745
895
  """
746
896
  await self.load_markets()
747
897
  market = self.market(symbol)
748
- marketType, query = self.handle_market_type_and_params('watchOHLCV', market, params)
749
- url = self.safe_value(self.urls['api']['ws'], marketType)
898
+ marketType = None
899
+ subType = None
900
+ url = None
901
+ marketType, params = self.handle_market_type_and_params('watchOHLCV', market, params)
902
+ subType, params = self.handle_sub_type_and_params('watchOHLCV', market, params, 'linear')
903
+ if marketType == 'swap':
904
+ url = self.safe_string(self.urls['api']['ws'], subType)
905
+ else:
906
+ url = self.safe_string(self.urls['api']['ws'], marketType)
750
907
  if url is None:
751
908
  raise BadRequest(self.id + ' watchOHLCV is not supported for ' + marketType + ' markets.')
752
909
  options = self.safe_value(self.options, marketType, {})
@@ -762,10 +919,10 @@ class bingx(ccxt.async_support.bingx):
762
919
  if marketType == 'swap':
763
920
  request['reqType'] = 'sub'
764
921
  subscriptionArgs: dict = {
765
- 'limit': limit,
922
+ 'interval': rawTimeframe,
766
923
  'params': params,
767
924
  }
768
- result = await self.watch(url, messageHash, self.extend(request, query), subscriptionHash, subscriptionArgs)
925
+ result = await self.watch(url, messageHash, self.extend(request, params), subscriptionHash, subscriptionArgs)
769
926
  ohlcv = result[2]
770
927
  if self.newUpdates:
771
928
  limit = ohlcv.getLimit(symbol, limit)
@@ -773,11 +930,14 @@ class bingx(ccxt.async_support.bingx):
773
930
 
774
931
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
775
932
  """
776
- :see: https://bingx-api.github.io/docs/#/spot/socket/account.html#Subscription%20order%20update%20data
777
- :see: https://bingx-api.github.io/docs/#/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
778
933
  watches information on multiple orders made by the user
779
- :param str symbol: unified market symbol of the market orders were made in
780
- :param int [since]: the earliest time in ms to fetch orders for
934
+
935
+ https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20order%20update%20data
936
+ https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Order%20update%20push
937
+ https://bingx-api.github.io/docs/#/en-us/cswap/socket/account.html#Order%20update%20push
938
+
939
+ :param str [symbol]: unified market symbol of the market orders are made in
940
+ :param int [since]: the earliest time in ms to watch orders for
781
941
  :param int [limit]: the maximum number of order structures to retrieve
782
942
  :param dict [params]: extra parameters specific to the exchange API endpoint
783
943
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
@@ -785,11 +945,13 @@ class bingx(ccxt.async_support.bingx):
785
945
  await self.load_markets()
786
946
  await self.authenticate()
787
947
  type = None
948
+ subType = None
788
949
  market = None
789
950
  if symbol is not None:
790
951
  market = self.market(symbol)
791
952
  symbol = market['symbol']
792
953
  type, params = self.handle_market_type_and_params('watchOrders', market, params)
954
+ subType, params = self.handle_sub_type_and_params('watchOrders', market, params, 'linear')
793
955
  isSpot = (type == 'spot')
794
956
  spotHash = 'spot:private'
795
957
  swapHash = 'swap:private'
@@ -799,14 +961,21 @@ class bingx(ccxt.async_support.bingx):
799
961
  messageHash = spotMessageHash if isSpot else swapMessageHash
800
962
  if market is not None:
801
963
  messageHash += ':' + symbol
802
- url = self.urls['api']['ws'][type] + '?listenKey=' + self.options['listenKey']
803
- request = None
804
964
  uuid = self.uuid()
805
- if isSpot:
965
+ baseUrl = None
966
+ request = None
967
+ if type == 'swap':
968
+ if subType == 'inverse':
969
+ raise NotSupported(self.id + ' watchOrders is not supported for inverse swap markets yet')
970
+ baseUrl = self.safe_string(self.urls['api']['ws'], subType)
971
+ else:
972
+ baseUrl = self.safe_string(self.urls['api']['ws'], type)
806
973
  request = {
807
974
  'id': uuid,
975
+ 'reqType': 'sub',
808
976
  'dataType': 'spot.executionReport',
809
977
  }
978
+ url = baseUrl + '?listenKey=' + self.options['listenKey']
810
979
  orders = await self.watch(url, messageHash, request, subscriptionHash)
811
980
  if self.newUpdates:
812
981
  limit = orders.getLimit(symbol, limit)
@@ -814,40 +983,52 @@ class bingx(ccxt.async_support.bingx):
814
983
 
815
984
  async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
816
985
  """
817
- :see: https://bingx-api.github.io/docs/#/spot/socket/account.html#Subscription%20order%20update%20data
818
- :see: https://bingx-api.github.io/docs/#/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
819
986
  watches information on multiple trades made by the user
820
- :param str symbol: unified market symbol of the market trades were made in
821
- :param int [since]: the earliest time in ms to trades orders for
822
- :param int [limit]: the maximum number of trades structures to retrieve
987
+
988
+ https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20order%20update%20data
989
+ https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Order%20update%20push
990
+ https://bingx-api.github.io/docs/#/en-us/cswap/socket/account.html#Order%20update%20push
991
+
992
+ :param str [symbol]: unified market symbol of the market the trades are made in
993
+ :param int [since]: the earliest time in ms to watch trades for
994
+ :param int [limit]: the maximum number of trade structures to retrieve
823
995
  :param dict [params]: extra parameters specific to the exchange API endpoint
824
- :returns dict[]: a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
996
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
825
997
  """
826
998
  await self.load_markets()
827
999
  await self.authenticate()
828
1000
  type = None
1001
+ subType = None
829
1002
  market = None
830
1003
  if symbol is not None:
831
1004
  market = self.market(symbol)
832
1005
  symbol = market['symbol']
833
- type, params = self.handle_market_type_and_params('watchOrders', market, params)
1006
+ type, params = self.handle_market_type_and_params('watchMyTrades', market, params)
1007
+ subType, params = self.handle_sub_type_and_params('watchMyTrades', market, params, 'linear')
834
1008
  isSpot = (type == 'spot')
835
- spotSubHash = 'spot:private'
836
- swapSubHash = 'swap:private'
837
- subscriptionHash = spotSubHash if isSpot else swapSubHash
1009
+ spotHash = 'spot:private'
1010
+ swapHash = 'swap:private'
1011
+ subscriptionHash = spotHash if isSpot else swapHash
838
1012
  spotMessageHash = 'spot:mytrades'
839
1013
  swapMessageHash = 'swap:mytrades'
840
1014
  messageHash = spotMessageHash if isSpot else swapMessageHash
841
1015
  if market is not None:
842
1016
  messageHash += ':' + symbol
843
- url = self.urls['api']['ws'][type] + '?listenKey=' + self.options['listenKey']
844
- request = None
845
1017
  uuid = self.uuid()
846
- if isSpot:
1018
+ baseUrl = None
1019
+ request = None
1020
+ if type == 'swap':
1021
+ if subType == 'inverse':
1022
+ raise NotSupported(self.id + ' watchMyTrades is not supported for inverse swap markets yet')
1023
+ baseUrl = self.safe_string(self.urls['api']['ws'], subType)
1024
+ else:
1025
+ baseUrl = self.safe_string(self.urls['api']['ws'], type)
847
1026
  request = {
848
1027
  'id': uuid,
1028
+ 'reqType': 'sub',
849
1029
  'dataType': 'spot.executionReport',
850
1030
  }
1031
+ url = baseUrl + '?listenKey=' + self.options['listenKey']
851
1032
  trades = await self.watch(url, messageHash, request, subscriptionHash)
852
1033
  if self.newUpdates:
853
1034
  limit = trades.getLimit(symbol, limit)
@@ -855,16 +1036,21 @@ class bingx(ccxt.async_support.bingx):
855
1036
 
856
1037
  async def watch_balance(self, params={}) -> Balances:
857
1038
  """
858
- :see: https://bingx-api.github.io/docs/#/spot/socket/account.html#Subscription%20order%20update%20data
859
- :see: https://bingx-api.github.io/docs/#/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
860
1039
  query for balance and get the amount of funds available for trading or funds locked in orders
1040
+
1041
+ https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20account%20balance%20push
1042
+ https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
1043
+ https://bingx-api.github.io/docs/#/en-us/cswap/socket/account.html#Account%20balance%20and%20position%20update%20push
1044
+
861
1045
  :param dict [params]: extra parameters specific to the exchange API endpoint
862
1046
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
863
1047
  """
864
1048
  await self.load_markets()
865
1049
  await self.authenticate()
866
1050
  type = None
1051
+ subType = None
867
1052
  type, params = self.handle_market_type_and_params('watchBalance', None, params)
1053
+ subType, params = self.handle_sub_type_and_params('watchBalance', None, params, 'linear')
868
1054
  isSpot = (type == 'spot')
869
1055
  spotSubHash = 'spot:balance'
870
1056
  swapSubHash = 'swap:private'
@@ -872,16 +1058,22 @@ class bingx(ccxt.async_support.bingx):
872
1058
  swapMessageHash = 'swap:balance'
873
1059
  messageHash = spotMessageHash if isSpot else swapMessageHash
874
1060
  subscriptionHash = spotSubHash if isSpot else swapSubHash
875
- url = self.urls['api']['ws'][type] + '?listenKey=' + self.options['listenKey']
876
1061
  request = None
1062
+ baseUrl = None
877
1063
  uuid = self.uuid()
878
- if type == 'spot':
1064
+ if type == 'swap':
1065
+ if subType == 'inverse':
1066
+ raise NotSupported(self.id + ' watchBalance is not supported for inverse swap markets yet')
1067
+ baseUrl = self.safe_string(self.urls['api']['ws'], subType)
1068
+ else:
1069
+ baseUrl = self.safe_string(self.urls['api']['ws'], type)
879
1070
  request = {
880
1071
  'id': uuid,
881
1072
  'dataType': 'ACCOUNT_UPDATE',
882
1073
  }
1074
+ url = baseUrl + '?listenKey=' + self.options['listenKey']
883
1075
  client = self.client(url)
884
- self.set_balance_cache(client, type, subscriptionHash, params)
1076
+ self.set_balance_cache(client, type, subType, subscriptionHash, params)
885
1077
  fetchBalanceSnapshot = None
886
1078
  awaitBalanceSnapshot = None
887
1079
  fetchBalanceSnapshot, params = self.handle_option_and_params(params, 'watchBalance', 'fetchBalanceSnapshot', True)
@@ -890,7 +1082,7 @@ class bingx(ccxt.async_support.bingx):
890
1082
  await client.future(type + ':fetchBalanceSnapshot')
891
1083
  return await self.watch(url, messageHash, request, subscriptionHash)
892
1084
 
893
- def set_balance_cache(self, client: Client, type, subscriptionHash, params):
1085
+ def set_balance_cache(self, client: Client, type, subType, subscriptionHash, params):
894
1086
  if subscriptionHash in client.subscriptions:
895
1087
  return
896
1088
  fetchBalanceSnapshot = self.handle_option_and_params(params, 'watchBalance', 'fetchBalanceSnapshot', True)
@@ -898,12 +1090,12 @@ class bingx(ccxt.async_support.bingx):
898
1090
  messageHash = type + ':fetchBalanceSnapshot'
899
1091
  if not (messageHash in client.futures):
900
1092
  client.future(messageHash)
901
- self.spawn(self.load_balance_snapshot, client, messageHash, type)
1093
+ self.spawn(self.load_balance_snapshot, client, messageHash, type, subType)
902
1094
  else:
903
1095
  self.balance[type] = {}
904
1096
 
905
- async def load_balance_snapshot(self, client, messageHash, type):
906
- response = await self.fetch_balance({'type': type})
1097
+ async def load_balance_snapshot(self, client, messageHash, type, subType):
1098
+ response = await self.fetch_balance({'type': type, 'subType': subType})
907
1099
  self.balance[type] = self.extend(response, self.safe_value(self.balance, type, {}))
908
1100
  # don't remove the future from the .futures cache
909
1101
  future = client.futures[messageHash]
@@ -937,7 +1129,7 @@ class bingx(ccxt.async_support.bingx):
937
1129
  try:
938
1130
  await self.userAuthPrivatePutUserDataStream({'listenKey': listenKey}) # self.extend the expiry
939
1131
  except Exception as error:
940
- types = ['spot', 'swap']
1132
+ types = ['spot', 'linear', 'inverse']
941
1133
  for i in range(0, len(types)):
942
1134
  type = types[i]
943
1135
  url = self.urls['api']['ws'][type] + '?listenKey=' + listenKey
@@ -1212,11 +1404,10 @@ class bingx(ccxt.async_support.bingx):
1212
1404
  balance = data[i]
1213
1405
  currencyId = self.safe_string(balance, 'a')
1214
1406
  code = self.safe_currency_code(currencyId)
1215
- account = self.balance[type][code] if (code in self.balance[type]) else self.account()
1407
+ account = self.account()
1408
+ account['info'] = balance
1409
+ account['used'] = self.safe_string(balance, 'lk')
1216
1410
  account['free'] = self.safe_string(balance, 'wb')
1217
- balanceChange = self.safe_string(balance, 'bc')
1218
- if account['used'] is not None:
1219
- account['used'] = Precise.string_sub(self.safe_string(account, 'used'), balanceChange)
1220
1411
  self.balance[type][code] = account
1221
1412
  self.balance[type] = self.safe_balance(self.balance[type])
1222
1413
  client.resolve(self.balance[type], type + ':balance')