ccxt-ir 4.3.46.0.3__py2.py3-none-any.whl → 4.5.1__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 +8 -8
  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 +10 -10
  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 +32 -38
  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 +32 -27
  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 +34 -30
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +15 -14
  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 +30 -36
  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 +29 -24
  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 +32 -28
  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 +13 -12
  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.1.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.1.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.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.1.dist-info/licenses}/LICENSE.txt +0 -0
  529. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/top_level.txt +0 -0
ccxt/pro/bitget.py CHANGED
@@ -6,7 +6,7 @@
6
6
  import ccxt.async_support
7
7
  from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Int, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
9
+ from ccxt.base.types import Any, Balances, Bool, Int, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
10
10
  from ccxt.async_support.base.ws.client import Client
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
@@ -14,13 +14,14 @@ from ccxt.base.errors import AuthenticationError
14
14
  from ccxt.base.errors import ArgumentsRequired
15
15
  from ccxt.base.errors import BadRequest
16
16
  from ccxt.base.errors import RateLimitExceeded
17
- from ccxt.base.errors import InvalidNonce
17
+ from ccxt.base.errors import ChecksumError
18
+ from ccxt.base.errors import UnsubscribeError
18
19
  from ccxt.base.precise import Precise
19
20
 
20
21
 
21
22
  class bitget(ccxt.async_support.bitget):
22
23
 
23
- def describe(self):
24
+ def describe(self) -> Any:
24
25
  return self.deep_extend(super(bitget, self).describe(), {
25
26
  'has': {
26
27
  'ws': True,
@@ -40,6 +41,7 @@ class bitget(ccxt.async_support.bitget):
40
41
  'watchOrders': True,
41
42
  'watchTicker': True,
42
43
  'watchTickers': True,
44
+ 'watchBidsAsks': True,
43
45
  'watchTrades': True,
44
46
  'watchTradesForSymbols': True,
45
47
  'watchPositions': True,
@@ -49,6 +51,14 @@ class bitget(ccxt.async_support.bitget):
49
51
  'ws': {
50
52
  'public': 'wss://ws.bitget.com/v2/ws/public',
51
53
  'private': 'wss://ws.bitget.com/v2/ws/private',
54
+ 'utaPublic': 'wss://ws.bitget.com/v3/ws/public',
55
+ 'utaPrivate': 'wss://ws.bitget.com/v3/ws/private',
56
+ },
57
+ 'demo': {
58
+ 'public': 'wss://wspap.bitget.com/v2/ws/public',
59
+ 'private': 'wss://wspap.bitget.com/v2/ws/private',
60
+ 'utaPublic': 'wss://wspap.bitget.com/v3/ws/public',
61
+ 'utaPrivate': 'wss://wspap.bitget.com/v3/ws/private',
52
62
  },
53
63
  },
54
64
  },
@@ -68,6 +78,12 @@ class bitget(ccxt.async_support.bitget):
68
78
  '1d': '1D',
69
79
  '1w': '1W',
70
80
  },
81
+ 'watchOrderBook': {
82
+ 'checksum': True,
83
+ },
84
+ 'watchTrades': {
85
+ 'ignoreDuplicates': True,
86
+ },
71
87
  },
72
88
  'streaming': {
73
89
  'ping': self.ping,
@@ -94,7 +110,9 @@ class bitget(ccxt.async_support.bitget):
94
110
  },
95
111
  })
96
112
 
97
- def get_inst_type(self, market, params={}):
113
+ def get_inst_type(self, market, uta: bool = False, params={}):
114
+ if (uta is None) or not uta:
115
+ uta, params = self.handle_option_and_params(params, 'getInstType', 'uta', False)
98
116
  instType = None
99
117
  if market is None:
100
118
  instType, params = self.handleProductTypeAndParams(None, params)
@@ -105,15 +123,21 @@ class bitget(ccxt.async_support.bitget):
105
123
  instypeAux = None
106
124
  instypeAux, params = self.handle_option_and_params(params, 'getInstType', 'instType', instType)
107
125
  instType = instypeAux
126
+ if uta:
127
+ instType = instType.lower()
108
128
  return [instType, params]
109
129
 
110
130
  async def watch_ticker(self, symbol: str, params={}) -> Ticker:
111
131
  """
112
132
  watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
113
- :see: https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
114
- :see: https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
133
+
134
+ https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
135
+ https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
136
+ https://www.bitget.com/api-doc/uta/websocket/public/Tickers-Channel
137
+
115
138
  :param str symbol: unified symbol of the market to watch the ticker for
116
139
  :param dict [params]: extra parameters specific to the exchange API endpoint
140
+ :param boolean [params.uta]: set to True for the unified trading account(uta), defaults to False
117
141
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
118
142
  """
119
143
  await self.load_markets()
@@ -121,28 +145,52 @@ class bitget(ccxt.async_support.bitget):
121
145
  symbol = market['symbol']
122
146
  messageHash = 'ticker:' + symbol
123
147
  instType = None
124
- instType, params = self.get_inst_type(market, params)
148
+ uta = None
149
+ uta, params = self.handle_option_and_params(params, 'watchTicker', 'uta', False)
150
+ instType, params = self.get_inst_type(market, uta, params)
125
151
  args: dict = {
126
152
  'instType': instType,
127
- 'channel': 'ticker',
128
- 'instId': market['id'],
129
153
  }
154
+ topicOrChannel = 'topic' if uta else 'channel'
155
+ symbolOrInstId = 'symbol' if uta else 'instId'
156
+ args[topicOrChannel] = 'ticker'
157
+ args[symbolOrInstId] = market['id']
130
158
  return await self.watch_public(messageHash, args, params)
131
159
 
160
+ async def un_watch_ticker(self, symbol: str, params={}) -> Any:
161
+ """
162
+ unsubscribe from the ticker channel
163
+
164
+ https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
165
+ https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
166
+
167
+ :param str symbol: unified symbol of the market to unwatch the ticker for
168
+ :param dict [params]: extra parameters specific to the exchange API endpoint
169
+ :returns any: status of the unwatch request
170
+ """
171
+ await self.load_markets()
172
+ return await self.un_watch_channel(symbol, 'ticker', 'ticker', params)
173
+
132
174
  async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
133
175
  """
134
176
  watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
135
- :see: https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
136
- :see: https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
177
+
178
+ https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
179
+ https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
180
+ https://www.bitget.com/api-doc/uta/websocket/public/Tickers-Channel
181
+
137
182
  :param str[] symbols: unified symbol of the market to watch the tickers for
138
183
  :param dict [params]: extra parameters specific to the exchange API endpoint
184
+ :param boolean [params.uta]: set to True for the unified trading account(uta), defaults to False
139
185
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
140
186
  """
141
187
  await self.load_markets()
142
188
  symbols = self.market_symbols(symbols, None, False)
143
189
  market = self.market(symbols[0])
144
190
  instType = None
145
- instType, params = self.get_inst_type(market, params)
191
+ uta = None
192
+ uta, params = self.handle_option_and_params(params, 'watchTickers', 'uta', False)
193
+ instType, params = self.get_inst_type(market, uta, params)
146
194
  topics = []
147
195
  messageHashes = []
148
196
  for i in range(0, len(symbols)):
@@ -150,9 +198,11 @@ class bitget(ccxt.async_support.bitget):
150
198
  marketInner = self.market(symbol)
151
199
  args: dict = {
152
200
  'instType': instType,
153
- 'channel': 'ticker',
154
- 'instId': marketInner['id'],
155
201
  }
202
+ topicOrChannel = 'topic' if uta else 'channel'
203
+ symbolOrInstId = 'symbol' if uta else 'instId'
204
+ args[topicOrChannel] = 'ticker'
205
+ args[symbolOrInstId] = marketInner['id']
156
206
  topics.append(args)
157
207
  messageHashes.append('ticker:' + symbol)
158
208
  tickers = await self.watch_public_multiple(messageHashes, topics, params)
@@ -163,6 +213,8 @@ class bitget(ccxt.async_support.bitget):
163
213
  return self.filter_by_array(self.tickers, 'symbol', symbols)
164
214
 
165
215
  def handle_ticker(self, client: Client, message):
216
+ #
217
+ # default
166
218
  #
167
219
  # {
168
220
  # "action": "snapshot",
@@ -193,6 +245,30 @@ class bitget(ccxt.async_support.bitget):
193
245
  # "ts": 1701842994341
194
246
  # }
195
247
  #
248
+ # uta
249
+ #
250
+ # {
251
+ # "action": "snapshot",
252
+ # "arg": {"instType": "spot", topic: "ticker", symbol: "BTCUSDT"},
253
+ # "data": [
254
+ # {
255
+ # "highPrice24h": "120255.61",
256
+ # "lowPrice24h": "116145.88",
257
+ # "openPrice24h": "118919.38",
258
+ # "lastPrice": "119818.83",
259
+ # "turnover24h": "215859996.272276",
260
+ # "volume24h": "1819.756798",
261
+ # "bid1Price": "119811.26",
262
+ # "ask1Price": "119831.18",
263
+ # "bid1Size": "0.008732",
264
+ # "ask1Size": "0.004297",
265
+ # "price24hPcnt": "0.02002"
266
+ # }
267
+ # ],
268
+ # "ts": 1753230479687
269
+ # }
270
+ #
271
+ self.handle_bid_ask(client, message)
196
272
  ticker = self.parse_ws_ticker(message)
197
273
  symbol = ticker['symbol']
198
274
  self.tickers[symbol] = ticker
@@ -270,45 +346,142 @@ class bitget(ccxt.async_support.bitget):
270
346
  # "ts": 1701843962812
271
347
  # }
272
348
  #
349
+ # uta
350
+ #
351
+ # {
352
+ # "action": "snapshot",
353
+ # "arg": {"instType": "spot", topic: "ticker", symbol: "BTCUSDT"},
354
+ # "data": [
355
+ # {
356
+ # "highPrice24h": "120255.61",
357
+ # "lowPrice24h": "116145.88",
358
+ # "openPrice24h": "118919.38",
359
+ # "lastPrice": "119818.83",
360
+ # "turnover24h": "215859996.272276",
361
+ # "volume24h": "1819.756798",
362
+ # "bid1Price": "119811.26",
363
+ # "ask1Price": "119831.18",
364
+ # "bid1Size": "0.008732",
365
+ # "ask1Size": "0.004297",
366
+ # "price24hPcnt": "0.02002"
367
+ # }
368
+ # ],
369
+ # "ts": 1753230479687
370
+ # }
371
+ #
273
372
  arg = self.safe_value(message, 'arg', {})
274
373
  data = self.safe_value(message, 'data', [])
275
374
  ticker = self.safe_value(data, 0, {})
276
- timestamp = self.safe_integer(ticker, 'ts')
277
- instType = self.safe_string(arg, 'instType')
278
- marketType = 'spot' if (instType == 'SPOT') else 'contract'
279
- marketId = self.safe_string(ticker, 'instId')
375
+ utaTimestamp = self.safe_integer(message, 'ts')
376
+ timestamp = self.safe_integer(ticker, 'ts', utaTimestamp)
377
+ instType = self.safe_string_lower(arg, 'instType')
378
+ marketType = 'spot' if (instType == 'spot') else 'contract'
379
+ utaMarketId = self.safe_string(arg, 'symbol')
380
+ marketId = self.safe_string(ticker, 'instId', utaMarketId)
280
381
  market = self.safe_market(marketId, market, None, marketType)
281
- close = self.safe_string(ticker, 'lastPr')
282
- changeDecimal = self.safe_string(ticker, 'change24h')
283
- change = Precise.string_mul(changeDecimal, '100')
382
+ close = self.safe_string_2(ticker, 'lastPr', 'lastPrice')
383
+ changeDecimal = self.safe_string(ticker, 'change24h', '')
384
+ change = self.safe_string(ticker, 'price24hPcnt', Precise.string_mul(changeDecimal, '100'))
284
385
  return self.safe_ticker({
285
386
  'symbol': market['symbol'],
286
387
  'timestamp': timestamp,
287
388
  'datetime': self.iso8601(timestamp),
288
- 'high': self.safe_string(ticker, 'high24h'),
289
- 'low': self.safe_string(ticker, 'low24h'),
290
- 'bid': self.safe_string(ticker, 'bidPr'),
291
- 'bidVolume': self.safe_string(ticker, 'bidSz'),
292
- 'ask': self.safe_string(ticker, 'askPr'),
293
- 'askVolume': self.safe_string(ticker, 'askSz'),
389
+ 'high': self.safe_string_2(ticker, 'high24h', 'highPrice24h'),
390
+ 'low': self.safe_string_2(ticker, 'low24h', 'lowPrice24h'),
391
+ 'bid': self.safe_string_2(ticker, 'bidPr', 'bid1Price'),
392
+ 'bidVolume': self.safe_string_2(ticker, 'bidSz', 'bid1Size'),
393
+ 'ask': self.safe_string_2(ticker, 'askPr', 'ask1Price'),
394
+ 'askVolume': self.safe_string_2(ticker, 'askSz', 'ask1Size'),
294
395
  'vwap': None,
295
- 'open': self.safe_string(ticker, 'open24h'),
396
+ 'open': self.safe_string_2(ticker, 'open24h', 'openPrice24h'),
296
397
  'close': close,
297
398
  'last': close,
298
399
  'previousClose': None,
299
400
  'change': None,
300
401
  'percentage': change,
301
402
  'average': None,
302
- 'baseVolume': self.safe_string(ticker, 'baseVolume'),
303
- 'quoteVolume': self.safe_string(ticker, 'quoteVolume'),
403
+ 'baseVolume': self.safe_string_2(ticker, 'baseVolume', 'volume24h'),
404
+ 'quoteVolume': self.safe_string_2(ticker, 'quoteVolume', 'turnover24h'),
405
+ 'info': ticker,
406
+ }, market)
407
+
408
+ async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
409
+ """
410
+ watches best bid & ask for symbols
411
+
412
+ https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
413
+ https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
414
+ https://www.bitget.com/api-doc/uta/websocket/public/Tickers-Channel
415
+
416
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
417
+ :param dict [params]: extra parameters specific to the exchange API endpoint
418
+ :param boolean [params.uta]: set to True for the unified trading account(uta), defaults to False
419
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
420
+ """
421
+ await self.load_markets()
422
+ symbols = self.market_symbols(symbols, None, False)
423
+ market = self.market(symbols[0])
424
+ instType = None
425
+ uta = None
426
+ uta, params = self.handle_option_and_params(params, 'watchBidsAsks', 'uta', False)
427
+ instType, params = self.get_inst_type(market, uta, params)
428
+ topics = []
429
+ messageHashes = []
430
+ for i in range(0, len(symbols)):
431
+ symbol = symbols[i]
432
+ marketInner = self.market(symbol)
433
+ args: dict = {
434
+ 'instType': instType,
435
+ }
436
+ topicOrChannel = 'topic' if uta else 'channel'
437
+ symbolOrInstId = 'symbol' if uta else 'instId'
438
+ args[topicOrChannel] = 'ticker'
439
+ args[symbolOrInstId] = marketInner['id']
440
+ topics.append(args)
441
+ messageHashes.append('bidask:' + symbol)
442
+ tickers = await self.watch_public_multiple(messageHashes, topics, params)
443
+ if self.newUpdates:
444
+ result: dict = {}
445
+ result[tickers['symbol']] = tickers
446
+ return result
447
+ return self.filter_by_array(self.bidsasks, 'symbol', symbols)
448
+
449
+ def handle_bid_ask(self, client: Client, message):
450
+ ticker = self.parse_ws_bid_ask(message)
451
+ symbol = ticker['symbol']
452
+ self.bidsasks[symbol] = ticker
453
+ messageHash = 'bidask:' + symbol
454
+ client.resolve(ticker, messageHash)
455
+
456
+ def parse_ws_bid_ask(self, message, market=None):
457
+ arg = self.safe_value(message, 'arg', {})
458
+ data = self.safe_value(message, 'data', [])
459
+ ticker = self.safe_value(data, 0, {})
460
+ utaTimestamp = self.safe_integer(message, 'ts')
461
+ timestamp = self.safe_integer(ticker, 'ts', utaTimestamp)
462
+ instType = self.safe_string_lower(arg, 'instType')
463
+ marketType = 'spot' if (instType == 'spot') else 'contract'
464
+ utaMarketId = self.safe_string(arg, 'symbol')
465
+ marketId = self.safe_string(ticker, 'instId', utaMarketId)
466
+ market = self.safe_market(marketId, market, None, marketType)
467
+ return self.safe_ticker({
468
+ 'symbol': market['symbol'],
469
+ 'timestamp': timestamp,
470
+ 'datetime': self.iso8601(timestamp),
471
+ 'ask': self.safe_string_2(ticker, 'askPr', 'ask1Price'),
472
+ 'askVolume': self.safe_string_2(ticker, 'askSz', 'ask1Size'),
473
+ 'bid': self.safe_string_2(ticker, 'bidPr', 'bid1Price'),
474
+ 'bidVolume': self.safe_string_2(ticker, 'bidSz', 'bid1Size'),
304
475
  'info': ticker,
305
476
  }, market)
306
477
 
307
478
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
308
479
  """
309
480
  watches historical candlestick data containing the open, high, low, close price, and the volume of a market
310
- :see: https://www.bitget.com/api-doc/spot/websocket/public/Candlesticks-Channel
311
- :see: https://www.bitget.com/api-doc/contract/websocket/public/Candlesticks-Channel
481
+
482
+ https://www.bitget.com/api-doc/spot/websocket/public/Candlesticks-Channel
483
+ https://www.bitget.com/api-doc/contract/websocket/public/Candlesticks-Channel
484
+
312
485
  :param str symbol: unified symbol of the market to fetch OHLCV data for
313
486
  :param str timeframe: the length of time each candle represents
314
487
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -323,7 +496,7 @@ class bitget(ccxt.async_support.bitget):
323
496
  interval = self.safe_string(timeframes, timeframe)
324
497
  messageHash = 'candles:' + timeframe + ':' + symbol
325
498
  instType = None
326
- instType, params = self.get_inst_type(market, params)
499
+ instType, params = self.get_inst_type(market, False, params)
327
500
  args: dict = {
328
501
  'instType': instType,
329
502
  'channel': 'candle' + interval,
@@ -334,6 +507,24 @@ class bitget(ccxt.async_support.bitget):
334
507
  limit = ohlcv.getLimit(symbol, limit)
335
508
  return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
336
509
 
510
+ async def un_watch_ohlcv(self, symbol: str, timeframe='1m', params={}) -> Any:
511
+ """
512
+ unsubscribe from the ohlcv channel
513
+
514
+ https://www.bitget.com/api-doc/spot/websocket/public/Candlesticks-Channel
515
+ https://www.bitget.com/api-doc/contract/websocket/public/Candlesticks-Channel
516
+
517
+ :param str symbol: unified symbol of the market to unwatch the ohlcv for
518
+ :param str [timeframe]: the period for the ratio, default is 1 minute
519
+ :param dict [params]: extra parameters specific to the exchange API endpoint
520
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
521
+ """
522
+ await self.load_markets()
523
+ timeframes = self.safe_dict(self.options, 'timeframes')
524
+ interval = self.safe_string(timeframes, timeframe)
525
+ channel = 'candle' + interval
526
+ return await self.un_watch_channel(symbol, channel, 'candles:' + timeframe, params)
527
+
337
528
  def handle_ohlcv(self, client: Client, message):
338
529
  #
339
530
  # {
@@ -417,8 +608,10 @@ class bitget(ccxt.async_support.bitget):
417
608
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
418
609
  """
419
610
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
420
- :see: https://www.bitget.com/api-doc/spot/websocket/public/Depth-Channel
421
- :see: https://www.bitget.com/api-doc/contract/websocket/public/Order-Book-Channel
611
+
612
+ https://www.bitget.com/api-doc/spot/websocket/public/Depth-Channel
613
+ https://www.bitget.com/api-doc/contract/websocket/public/Order-Book-Channel
614
+
422
615
  :param str symbol: unified symbol of the market to fetch the order book for
423
616
  :param int [limit]: the maximum amount of order book entries to return
424
617
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -426,11 +619,46 @@ class bitget(ccxt.async_support.bitget):
426
619
  """
427
620
  return await self.watch_order_book_for_symbols([symbol], limit, params)
428
621
 
622
+ async def un_watch_order_book(self, symbol: str, params={}) -> Any:
623
+ """
624
+ unsubscribe from the orderbook channel
625
+
626
+ https://www.bitget.com/api-doc/spot/websocket/public/Depth-Channel
627
+ https://www.bitget.com/api-doc/contract/websocket/public/Order-Book-Channel
628
+
629
+ :param str symbol: unified symbol of the market to fetch the order book for
630
+ :param dict [params]: extra parameters specific to the exchange API endpoint
631
+ :param int [params.limit]: orderbook limit, default is None
632
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
633
+ """
634
+ await self.load_markets()
635
+ channel = 'books'
636
+ limit = self.safe_integer(params, 'limit')
637
+ if (limit == 1) or (limit == 5) or (limit == 15):
638
+ params = self.omit(params, 'limit')
639
+ channel += str(limit)
640
+ return await self.un_watch_channel(symbol, channel, 'orderbook', params)
641
+
642
+ async def un_watch_channel(self, symbol: str, channel: str, messageHashTopic: str, params={}) -> Any:
643
+ await self.load_markets()
644
+ market = self.market(symbol)
645
+ messageHash = 'unsubscribe:' + messageHashTopic + ':' + market['symbol']
646
+ instType = None
647
+ instType, params = self.get_inst_type(market, False, params)
648
+ args: dict = {
649
+ 'instType': instType,
650
+ 'channel': channel,
651
+ 'instId': market['id'],
652
+ }
653
+ return await self.un_watch_public(messageHash, args, params)
654
+
429
655
  async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
430
656
  """
431
657
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
432
- :see: https://www.bitget.com/api-doc/spot/websocket/public/Depth-Channel
433
- :see: https://www.bitget.com/api-doc/contract/websocket/public/Order-Book-Channel
658
+
659
+ https://www.bitget.com/api-doc/spot/websocket/public/Depth-Channel
660
+ https://www.bitget.com/api-doc/contract/websocket/public/Order-Book-Channel
661
+
434
662
  :param str[] symbols: unified array of symbols
435
663
  :param int [limit]: the maximum amount of order book entries to return
436
664
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -449,7 +677,7 @@ class bitget(ccxt.async_support.bitget):
449
677
  symbol = symbols[i]
450
678
  market = self.market(symbol)
451
679
  instType = None
452
- instType, params = self.get_inst_type(market, params)
680
+ instType, params = self.get_inst_type(market, False, params)
453
681
  args: dict = {
454
682
  'instType': instType,
455
683
  'channel': channel,
@@ -520,7 +748,7 @@ class bitget(ccxt.async_support.bitget):
520
748
  self.handle_deltas(storedOrderBook['bids'], bids)
521
749
  storedOrderBook['timestamp'] = timestamp
522
750
  storedOrderBook['datetime'] = self.iso8601(timestamp)
523
- checksum = self.safe_bool(self.options, 'checksum', True)
751
+ checksum = self.handle_option('watchOrderBook', 'checksum', True)
524
752
  isSnapshot = self.safe_string(message, 'action') == 'snapshot' # snapshot does not have a checksum
525
753
  if not isSnapshot and checksum:
526
754
  storedAsks = storedOrderBook['asks']
@@ -539,10 +767,11 @@ class bitget(ccxt.async_support.bitget):
539
767
  calculatedChecksum = self.crc32(payload, True)
540
768
  responseChecksum = self.safe_integer(rawOrderBook, 'checksum')
541
769
  if calculatedChecksum != responseChecksum:
542
- error = InvalidNonce(self.id + ' invalid checksum')
543
- del client.subscriptions[messageHash]
544
- del self.orderbooks[symbol]
545
- client.reject(error, messageHash)
770
+ # if messageHash in client.subscriptions:
771
+ # # del client.subscriptions[messageHash]
772
+ # # del self.orderbooks[symbol]
773
+ # }
774
+ self.spawn(self.handle_check_sum_error, client, symbol, messageHash)
546
775
  return
547
776
  else:
548
777
  orderbook = self.order_book({})
@@ -551,6 +780,11 @@ class bitget(ccxt.async_support.bitget):
551
780
  self.orderbooks[symbol] = orderbook
552
781
  client.resolve(self.orderbooks[symbol], messageHash)
553
782
 
783
+ async def handle_check_sum_error(self, client: Client, symbol: str, messageHash: str):
784
+ await self.un_watch_order_book(symbol)
785
+ error = ChecksumError(self.id + ' ' + self.orderbook_checksum_message(symbol))
786
+ client.reject(error, messageHash)
787
+
554
788
  def handle_delta(self, bookside, delta):
555
789
  bidAsk = self.parse_bid_ask(delta, 0, 1)
556
790
  # we store the string representations in the orderbook for checksum calculation
@@ -565,8 +799,10 @@ class bitget(ccxt.async_support.bitget):
565
799
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
566
800
  """
567
801
  get the list of most recent trades for a particular symbol
568
- :see: https://www.bitget.com/api-doc/spot/websocket/public/Trades-Channel
569
- :see: https://www.bitget.com/api-doc/contract/websocket/public/New-Trades-Channel
802
+
803
+ https://www.bitget.com/api-doc/spot/websocket/public/Trades-Channel
804
+ https://www.bitget.com/api-doc/contract/websocket/public/New-Trades-Channel
805
+
570
806
  :param str symbol: unified symbol of the market to fetch trades for
571
807
  :param int [since]: timestamp in ms of the earliest trade to fetch
572
808
  :param int [limit]: the maximum amount of trades to fetch
@@ -578,9 +814,11 @@ class bitget(ccxt.async_support.bitget):
578
814
  async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
579
815
  """
580
816
  get the list of most recent trades for a particular symbol
581
- :see: https://www.bitget.com/api-doc/spot/websocket/public/Trades-Channel
582
- :see: https://www.bitget.com/api-doc/contract/websocket/public/New-Trades-Channel
583
- :param str symbol: unified symbol of the market to fetch trades for
817
+
818
+ https://www.bitget.com/api-doc/spot/websocket/public/Trades-Channel
819
+ https://www.bitget.com/api-doc/contract/websocket/public/New-Trades-Channel
820
+
821
+ :param str[] symbols: unified symbol of the market to fetch trades for
584
822
  :param int [since]: timestamp in ms of the earliest trade to fetch
585
823
  :param int [limit]: the maximum amount of trades to fetch
586
824
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -597,7 +835,7 @@ class bitget(ccxt.async_support.bitget):
597
835
  symbol = symbols[i]
598
836
  market = self.market(symbol)
599
837
  instType = None
600
- instType, params = self.get_inst_type(market, params)
838
+ instType, params = self.get_inst_type(market, False, params)
601
839
  args: dict = {
602
840
  'instType': instType,
603
841
  'channel': 'trade',
@@ -610,7 +848,26 @@ class bitget(ccxt.async_support.bitget):
610
848
  first = self.safe_value(trades, 0)
611
849
  tradeSymbol = self.safe_string(first, 'symbol')
612
850
  limit = trades.getLimit(tradeSymbol, limit)
613
- return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
851
+ result = self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
852
+ if self.handle_option('watchTrades', 'ignoreDuplicates', True):
853
+ filtered = self.remove_repeated_trades_from_array(result)
854
+ filtered = self.sort_by(filtered, 'timestamp')
855
+ return filtered
856
+ return result
857
+
858
+ async def un_watch_trades(self, symbol: str, params={}) -> Any:
859
+ """
860
+ unsubscribe from the trades channel
861
+
862
+ https://www.bitget.com/api-doc/spot/websocket/public/Trades-Channel
863
+ https://www.bitget.com/api-doc/contract/websocket/public/New-Trades-Channel
864
+
865
+ :param str symbol: unified symbol of the market to unwatch the trades for
866
+ :param dict [params]: extra parameters specific to the exchange API endpoint
867
+ :returns any: status of the unwatch request
868
+ """
869
+ await self.load_markets()
870
+ return await self.un_watch_channel(symbol, 'trade', 'trade', params)
614
871
 
615
872
  def handle_trades(self, client: Client, message):
616
873
  #
@@ -744,8 +1001,12 @@ class bitget(ccxt.async_support.bitget):
744
1001
  async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
745
1002
  """
746
1003
  watch all open positions
747
- :see: https://www.bitget.com/api-doc/contract/websocket/private/Positions-Channel
1004
+
1005
+ https://www.bitget.com/api-doc/contract/websocket/private/Positions-Channel
1006
+
748
1007
  :param str[]|None symbols: list of unified market symbols
1008
+ :param int [since]: the earliest time in ms to fetch positions for
1009
+ :param int [limit]: the maximum number of positions to retrieve
749
1010
  :param dict params: extra parameters specific to the exchange API endpoint
750
1011
  :param str [params.instType]: one of 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES', default is 'USDT-FUTURES'
751
1012
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
@@ -758,7 +1019,7 @@ class bitget(ccxt.async_support.bitget):
758
1019
  symbols = self.market_symbols(symbols)
759
1020
  if not self.is_empty(symbols):
760
1021
  market = self.get_market_from_symbols(symbols)
761
- instType, params = self.get_inst_type(market, params)
1022
+ instType, params = self.get_inst_type(market, False, params)
762
1023
  messageHash = instType + ':positions' + messageHash
763
1024
  args: dict = {
764
1025
  'instType': instType,
@@ -812,13 +1073,11 @@ class bitget(ccxt.async_support.bitget):
812
1073
  instType = self.safe_string(arg, 'instType', '')
813
1074
  if self.positions is None:
814
1075
  self.positions = {}
815
- if not (instType in self.positions):
1076
+ action = self.safe_string(message, 'action')
1077
+ if not (instType in self.positions) or (action == 'snapshot'):
816
1078
  self.positions[instType] = ArrayCacheBySymbolBySide()
817
1079
  cache = self.positions[instType]
818
1080
  rawPositions = self.safe_value(message, 'data', [])
819
- dataLength = len(rawPositions)
820
- if dataLength == 0:
821
- return
822
1081
  newPositions = []
823
1082
  for i in range(0, len(rawPositions)):
824
1083
  rawPosition = rawPositions[i]
@@ -907,20 +1166,22 @@ class bitget(ccxt.async_support.bitget):
907
1166
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
908
1167
  """
909
1168
  watches information on multiple orders made by the user
910
- :see: https://www.bitget.com/api-doc/spot/websocket/private/Order-Channel
911
- :see: https://www.bitget.com/api-doc/contract/websocket/private/Order-Channel
912
- :see: https://www.bitget.com/api-doc/contract/websocket/private/Plan-Order-Channel
913
- :see: https://www.bitget.com/api-doc/margin/cross/websocket/private/Cross-Orders
914
- :see: https://www.bitget.com/api-doc/margin/isolated/websocket/private/Isolate-Orders
1169
+
1170
+ https://www.bitget.com/api-doc/spot/websocket/private/Order-Channel
1171
+ https://www.bitget.com/api-doc/contract/websocket/private/Order-Channel
1172
+ https://www.bitget.com/api-doc/contract/websocket/private/Plan-Order-Channel
1173
+ https://www.bitget.com/api-doc/margin/cross/websocket/private/Cross-Orders
1174
+ https://www.bitget.com/api-doc/margin/isolated/websocket/private/Isolate-Orders
1175
+
915
1176
  :param str symbol: unified market symbol of the market orders were made in
916
1177
  :param int [since]: the earliest time in ms to fetch orders for
917
1178
  :param int [limit]: the maximum number of order structures to retrieve
918
1179
  :param dict [params]: extra parameters specific to the exchange API endpoint
919
- :param boolean [params.stop]: *contract only* set to True for watching trigger orders
1180
+ :param boolean [params.trigger]: *contract only* set to True for watching trigger orders
920
1181
  :param str [params.marginMode]: 'isolated' or 'cross' for watching spot margin orders]
921
1182
  :param str [params.type]: 'spot', 'swap'
922
1183
  :param str [params.subType]: 'linear', 'inverse'
923
- :returns dict[]: a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
1184
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
924
1185
  """
925
1186
  await self.load_markets()
926
1187
  market = None
@@ -940,7 +1201,7 @@ class bitget(ccxt.async_support.bitget):
940
1201
  subType = None
941
1202
  subType, params = self.handle_sub_type_and_params('watchOrders', market, params, 'linear')
942
1203
  if (type == 'spot' or type == 'margin') and (symbol is None):
943
- raise ArgumentsRequired(self.id + ' watchOrders requires a symbol argument for ' + type + ' markets.')
1204
+ marketId = 'default'
944
1205
  if (productType is None) and (type != 'spot') and (symbol is None):
945
1206
  messageHash = messageHash + ':' + subType
946
1207
  elif productType == 'USDT-FUTURES':
@@ -950,8 +1211,11 @@ class bitget(ccxt.async_support.bitget):
950
1211
  elif productType == 'USDC-FUTURES':
951
1212
  messageHash = messageHash + ':usdcfutures' # non unified channel
952
1213
  instType = None
953
- instType, params = self.get_inst_type(market, params)
954
- if type == 'spot':
1214
+ if market is None and type == 'spot':
1215
+ instType = 'SPOT'
1216
+ else:
1217
+ instType, params = self.get_inst_type(market, False, params)
1218
+ if type == 'spot' and (symbol is not None):
955
1219
  subscriptionHash = subscriptionHash + ':' + symbol
956
1220
  if isTrigger:
957
1221
  subscriptionHash = subscriptionHash + ':stop' # we don't want to re-use the same subscription hash for stop orders
@@ -1279,7 +1543,9 @@ class bitget(ccxt.async_support.bitget):
1279
1543
  async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
1280
1544
  """
1281
1545
  watches trades made by the user
1282
- :see: https://www.bitget.com/api-doc/contract/websocket/private/Order-Channel
1546
+
1547
+ https://www.bitget.com/api-doc/contract/websocket/private/Order-Channel
1548
+
1283
1549
  :param str symbol: unified market symbol
1284
1550
  :param int [since]: the earliest time in ms to fetch trades for
1285
1551
  :param int [limit]: the maximum number of trades structures to retrieve
@@ -1293,8 +1559,13 @@ class bitget(ccxt.async_support.bitget):
1293
1559
  market = self.market(symbol)
1294
1560
  symbol = market['symbol']
1295
1561
  messageHash = messageHash + ':' + symbol
1562
+ type = None
1563
+ type, params = self.handle_market_type_and_params('watchMyTrades', market, params)
1296
1564
  instType = None
1297
- instType, params = self.get_inst_type(market, params)
1565
+ if market is None and type == 'spot':
1566
+ instType = 'spot'
1567
+ else:
1568
+ instType, params = self.get_inst_type(market, False, params)
1298
1569
  subscriptionHash = 'fill:' + instType
1299
1570
  args: dict = {
1300
1571
  'instType': instType,
@@ -1397,10 +1668,12 @@ class bitget(ccxt.async_support.bitget):
1397
1668
  async def watch_balance(self, params={}) -> Balances:
1398
1669
  """
1399
1670
  watch balance and get the amount of funds available for trading or funds locked in orders
1400
- :see: https://www.bitget.com/api-doc/spot/websocket/private/Account-Channel
1401
- :see: https://www.bitget.com/api-doc/contract/websocket/private/Account-Channel
1402
- :see: https://www.bitget.com/api-doc/margin/cross/websocket/private/Margin-Cross-Account-Assets
1403
- :see: https://www.bitget.com/api-doc/margin/isolated/websocket/private/Margin-isolated-account-assets
1671
+
1672
+ https://www.bitget.com/api-doc/spot/websocket/private/Account-Channel
1673
+ https://www.bitget.com/api-doc/contract/websocket/private/Account-Channel
1674
+ https://www.bitget.com/api-doc/margin/cross/websocket/private/Margin-Cross-Account-Assets
1675
+ https://www.bitget.com/api-doc/margin/isolated/websocket/private/Margin-isolated-account-assets
1676
+
1404
1677
  :param dict [params]: extra parameters specific to the exchange API endpoint
1405
1678
  :param str [params.type]: spot or contract if not provided self.options['defaultType'] is used
1406
1679
  :param str [params.instType]: one of 'SPOT', 'MARGIN', 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES'
@@ -1513,7 +1786,21 @@ class bitget(ccxt.async_support.bitget):
1513
1786
  client.resolve(self.balance, messageHash)
1514
1787
 
1515
1788
  async def watch_public(self, messageHash, args, params={}):
1516
- url = self.urls['api']['ws']['public']
1789
+ uta = None
1790
+ url = None
1791
+ uta, params = self.handle_option_and_params(params, 'watchPublic', 'uta', False)
1792
+ if uta:
1793
+ url = self.urls['api']['ws']['utaPublic']
1794
+ else:
1795
+ url = self.urls['api']['ws']['public']
1796
+ sandboxMode = self.safe_bool_2(self.options, 'sandboxMode', 'sandbox', False)
1797
+ if sandboxMode:
1798
+ instType = self.safe_string(args, 'instType')
1799
+ if (instType != 'SCOIN-FUTURES') and (instType != 'SUSDT-FUTURES') and (instType != 'SUSDC-FUTURES'):
1800
+ if uta:
1801
+ url = self.urls['api']['demo']['utaPublic']
1802
+ else:
1803
+ url = self.urls['api']['demo']['public']
1517
1804
  request: dict = {
1518
1805
  'op': 'subscribe',
1519
1806
  'args': [args],
@@ -1521,8 +1808,46 @@ class bitget(ccxt.async_support.bitget):
1521
1808
  message = self.extend(request, params)
1522
1809
  return await self.watch(url, messageHash, message, messageHash)
1523
1810
 
1811
+ async def un_watch_public(self, messageHash, args, params={}):
1812
+ uta = None
1813
+ url = None
1814
+ uta, params = self.handle_option_and_params(params, 'unWatchPublic', 'uta', False)
1815
+ if uta:
1816
+ url = self.urls['api']['ws']['utaPublic']
1817
+ else:
1818
+ url = self.urls['api']['ws']['public']
1819
+ sandboxMode = self.safe_bool_2(self.options, 'sandboxMode', 'sandbox', False)
1820
+ if sandboxMode:
1821
+ instType = self.safe_string(args, 'instType')
1822
+ if (instType != 'SCOIN-FUTURES') and (instType != 'SUSDT-FUTURES') and (instType != 'SUSDC-FUTURES'):
1823
+ if uta:
1824
+ url = self.urls['api']['demo']['utaPublic']
1825
+ else:
1826
+ url = self.urls['api']['demo']['public']
1827
+ request: dict = {
1828
+ 'op': 'unsubscribe',
1829
+ 'args': [args],
1830
+ }
1831
+ message = self.extend(request, params)
1832
+ return await self.watch(url, messageHash, message, messageHash)
1833
+
1524
1834
  async def watch_public_multiple(self, messageHashes, argsArray, params={}):
1525
- url = self.urls['api']['ws']['public']
1835
+ uta = None
1836
+ url = None
1837
+ uta, params = self.handle_option_and_params(params, 'watchPublicMultiple', 'uta', False)
1838
+ if uta:
1839
+ url = self.urls['api']['ws']['utaPublic']
1840
+ else:
1841
+ url = self.urls['api']['ws']['public']
1842
+ sandboxMode = self.safe_bool_2(self.options, 'sandboxMode', 'sandbox', False)
1843
+ if sandboxMode:
1844
+ argsArrayFirst = self.safe_dict(argsArray, 0, {})
1845
+ instType = self.safe_string(argsArrayFirst, 'instType')
1846
+ if (instType != 'SCOIN-FUTURES') and (instType != 'SUSDT-FUTURES') and (instType != 'SUSDC-FUTURES'):
1847
+ if uta:
1848
+ url = self.urls['api']['demo']['utaPublic']
1849
+ else:
1850
+ url = self.urls['api']['demo']['public']
1526
1851
  request: dict = {
1527
1852
  'op': 'subscribe',
1528
1853
  'args': argsArray,
@@ -1532,7 +1857,7 @@ class bitget(ccxt.async_support.bitget):
1532
1857
 
1533
1858
  async def authenticate(self, params={}):
1534
1859
  self.check_required_credentials()
1535
- url = self.urls['api']['ws']['private']
1860
+ url = self.safe_string(params, 'url')
1536
1861
  client = self.client(url)
1537
1862
  messageHash = 'authenticated'
1538
1863
  future = client.future(messageHash)
@@ -1558,8 +1883,13 @@ class bitget(ccxt.async_support.bitget):
1558
1883
  return await future
1559
1884
 
1560
1885
  async def watch_private(self, messageHash, subscriptionHash, args, params={}):
1561
- await self.authenticate()
1562
1886
  url = self.urls['api']['ws']['private']
1887
+ sandboxMode = self.safe_bool_2(self.options, 'sandboxMode', 'sandbox', False)
1888
+ if sandboxMode:
1889
+ instType = self.safe_string(args, 'instType')
1890
+ if (instType != 'SCOIN-FUTURES') and (instType != 'SUSDT-FUTURES') and (instType != 'SUSDC-FUTURES'):
1891
+ url = self.urls['api']['demo']['private']
1892
+ await self.authenticate({'url': url})
1563
1893
  request: dict = {
1564
1894
  'op': 'subscribe',
1565
1895
  'args': [args],
@@ -1575,7 +1905,7 @@ class bitget(ccxt.async_support.bitget):
1575
1905
  future = self.safe_value(client.futures, messageHash)
1576
1906
  future.resolve(True)
1577
1907
 
1578
- def handle_error_message(self, client: Client, message):
1908
+ def handle_error_message(self, client: Client, message) -> Bool:
1579
1909
  #
1580
1910
  # {event: "error", code: 30015, msg: "Invalid sign"}
1581
1911
  #
@@ -1634,6 +1964,40 @@ class bitget(ccxt.async_support.bitget):
1634
1964
  # "event": "subscribe",
1635
1965
  # "arg": {instType: 'SPOT', channel: "account", instId: "default"}
1636
1966
  # }
1967
+ # unsubscribe
1968
+ # {
1969
+ # "op":"unsubscribe",
1970
+ # "args":[
1971
+ # {
1972
+ # "instType":"USDT-FUTURES",
1973
+ # "channel":"ticker",
1974
+ # "instId":"BTCUSDT"
1975
+ # }
1976
+ # ]
1977
+ # }
1978
+ #
1979
+ # uta
1980
+ #
1981
+ # {
1982
+ # "action": "snapshot",
1983
+ # "arg": {"instType": "spot", topic: "ticker", symbol: "BTCUSDT"},
1984
+ # "data": [
1985
+ # {
1986
+ # "highPrice24h": "120255.61",
1987
+ # "lowPrice24h": "116145.88",
1988
+ # "openPrice24h": "118919.38",
1989
+ # "lastPrice": "119818.83",
1990
+ # "turnover24h": "215859996.272276",
1991
+ # "volume24h": "1819.756798",
1992
+ # "bid1Price": "119811.26",
1993
+ # "ask1Price": "119831.18",
1994
+ # "bid1Size": "0.008732",
1995
+ # "ask1Size": "0.004297",
1996
+ # "price24hPcnt": "0.02002"
1997
+ # }
1998
+ # ],
1999
+ # "ts": 1753230479687
2000
+ # }
1637
2001
  #
1638
2002
  if self.handle_error_message(client, message):
1639
2003
  return
@@ -1651,6 +2015,9 @@ class bitget(ccxt.async_support.bitget):
1651
2015
  if event == 'subscribe':
1652
2016
  self.handle_subscription_status(client, message)
1653
2017
  return
2018
+ if event == 'unsubscribe':
2019
+ self.handle_un_subscription_status(client, message)
2020
+ return
1654
2021
  methods: dict = {
1655
2022
  'ticker': self.handle_ticker,
1656
2023
  'trade': self.handle_trades,
@@ -1666,7 +2033,7 @@ class bitget(ccxt.async_support.bitget):
1666
2033
  'account-crossed': self.handle_balance,
1667
2034
  }
1668
2035
  arg = self.safe_value(message, 'arg', {})
1669
- topic = self.safe_value(arg, 'channel', '')
2036
+ topic = self.safe_value_2(arg, 'channel', 'topic', '')
1670
2037
  method = self.safe_value(methods, topic)
1671
2038
  if method is not None:
1672
2039
  method(client, message)
@@ -1675,7 +2042,7 @@ class bitget(ccxt.async_support.bitget):
1675
2042
  if topic.find('books') >= 0:
1676
2043
  self.handle_order_book(client, message)
1677
2044
 
1678
- def ping(self, client):
2045
+ def ping(self, client: Client):
1679
2046
  return 'ping'
1680
2047
 
1681
2048
  def handle_pong(self, client: Client, message):
@@ -1690,3 +2057,127 @@ class bitget(ccxt.async_support.bitget):
1690
2057
  # }
1691
2058
  #
1692
2059
  return message
2060
+
2061
+ def handle_order_book_un_subscription(self, client: Client, message):
2062
+ #
2063
+ # {"event":"unsubscribe","arg":{"instType":"SPOT","channel":"books","instId":"BTCUSDT"}}
2064
+ #
2065
+ arg = self.safe_dict(message, 'arg', {})
2066
+ instType = self.safe_string_lower(arg, 'instType')
2067
+ type = 'spot' if (instType == 'spot') else 'contract'
2068
+ instId = self.safe_string(arg, 'instId')
2069
+ market = self.safe_market(instId, None, None, type)
2070
+ symbol = market['symbol']
2071
+ messageHash = 'unsubscribe:orderbook:' + market['symbol']
2072
+ subMessageHash = 'orderbook:' + symbol
2073
+ if symbol in self.orderbooks:
2074
+ del self.orderbooks[symbol]
2075
+ if subMessageHash in client.subscriptions:
2076
+ del client.subscriptions[subMessageHash]
2077
+ if messageHash in client.subscriptions:
2078
+ del client.subscriptions[messageHash]
2079
+ error = UnsubscribeError(self.id + ' orderbook ' + symbol)
2080
+ client.reject(error, subMessageHash)
2081
+ client.resolve(True, messageHash)
2082
+
2083
+ def handle_trades_un_subscription(self, client: Client, message):
2084
+ #
2085
+ # {"event":"unsubscribe","arg":{"instType":"SPOT","channel":"trade","instId":"BTCUSDT"}}
2086
+ #
2087
+ arg = self.safe_dict(message, 'arg', {})
2088
+ instType = self.safe_string_lower(arg, 'instType')
2089
+ type = 'spot' if (instType == 'spot') else 'contract'
2090
+ instId = self.safe_string(arg, 'instId')
2091
+ market = self.safe_market(instId, None, None, type)
2092
+ symbol = market['symbol']
2093
+ messageHash = 'unsubscribe:trade:' + market['symbol']
2094
+ subMessageHash = 'trade:' + symbol
2095
+ if symbol in self.trades:
2096
+ del self.trades[symbol]
2097
+ if subMessageHash in client.subscriptions:
2098
+ del client.subscriptions[subMessageHash]
2099
+ if messageHash in client.subscriptions:
2100
+ del client.subscriptions[messageHash]
2101
+ error = UnsubscribeError(self.id + ' trades ' + symbol)
2102
+ client.reject(error, subMessageHash)
2103
+ client.resolve(True, messageHash)
2104
+
2105
+ def handle_ticker_un_subscription(self, client: Client, message):
2106
+ #
2107
+ # {"event":"unsubscribe","arg":{"instType":"SPOT","channel":"trade","instId":"BTCUSDT"}}
2108
+ #
2109
+ arg = self.safe_dict(message, 'arg', {})
2110
+ instType = self.safe_string_lower(arg, 'instType')
2111
+ type = 'spot' if (instType == 'spot') else 'contract'
2112
+ instId = self.safe_string_2(arg, 'instId', 'symbol')
2113
+ market = self.safe_market(instId, None, None, type)
2114
+ symbol = market['symbol']
2115
+ messageHash = 'unsubscribe:ticker:' + market['symbol']
2116
+ subMessageHash = 'ticker:' + symbol
2117
+ if symbol in self.tickers:
2118
+ del self.tickers[symbol]
2119
+ if subMessageHash in client.subscriptions:
2120
+ del client.subscriptions[subMessageHash]
2121
+ if messageHash in client.subscriptions:
2122
+ del client.subscriptions[messageHash]
2123
+ error = UnsubscribeError(self.id + ' ticker ' + symbol)
2124
+ client.reject(error, subMessageHash)
2125
+ client.resolve(True, messageHash)
2126
+
2127
+ def handle_ohlcv_un_subscription(self, client: Client, message):
2128
+ #
2129
+ # {"event":"unsubscribe","arg":{"instType":"SPOT","channel":"candle1m","instId":"BTCUSDT"}}
2130
+ #
2131
+ arg = self.safe_dict(message, 'arg', {})
2132
+ instType = self.safe_string_lower(arg, 'instType')
2133
+ type = 'spot' if (instType == 'spot') else 'contract'
2134
+ instId = self.safe_string(arg, 'instId')
2135
+ channel = self.safe_string(arg, 'channel')
2136
+ interval = channel.replace('candle', '')
2137
+ timeframes = self.safe_value(self.options, 'timeframes')
2138
+ timeframe = self.find_timeframe(interval, timeframes)
2139
+ market = self.safe_market(instId, None, None, type)
2140
+ symbol = market['symbol']
2141
+ messageHash = 'unsubscribe:candles:' + timeframe + ':' + market['symbol']
2142
+ subMessageHash = 'candles:' + timeframe + ':' + symbol
2143
+ if symbol in self.ohlcvs:
2144
+ if timeframe in self.ohlcvs[symbol]:
2145
+ del self.ohlcvs[symbol][timeframe]
2146
+ self.clean_unsubscription(client, subMessageHash, messageHash)
2147
+
2148
+ def handle_un_subscription_status(self, client: Client, message):
2149
+ #
2150
+ # {
2151
+ # "op":"unsubscribe",
2152
+ # "args":[
2153
+ # {
2154
+ # "instType":"USDT-FUTURES",
2155
+ # "channel":"ticker",
2156
+ # "instId":"BTCUSDT"
2157
+ # },
2158
+ # {
2159
+ # "instType":"USDT-FUTURES",
2160
+ # "channel":"candle1m",
2161
+ # "instId":"BTCUSDT"
2162
+ # }
2163
+ # ]
2164
+ # }
2165
+ # or
2166
+ # {"event":"unsubscribe","arg":{"instType":"SPOT","channel":"books","instId":"BTCUSDT"}}
2167
+ #
2168
+ argsList = self.safe_list(message, 'args')
2169
+ if argsList is None:
2170
+ argsList = [self.safe_dict(message, 'arg', {})]
2171
+ for i in range(0, len(argsList)):
2172
+ arg = argsList[i]
2173
+ channel = self.safe_string_2(arg, 'channel', 'topic')
2174
+ if channel == 'books':
2175
+ # for now only unWatchOrderBook is supporteod
2176
+ self.handle_order_book_un_subscription(client, message)
2177
+ elif channel == 'trade':
2178
+ self.handle_trades_un_subscription(client, message)
2179
+ elif channel == 'ticker':
2180
+ self.handle_ticker_un_subscription(client, message)
2181
+ elif channel.startswith('candle'):
2182
+ self.handle_ohlcv_un_subscription(client, message)
2183
+ return message