ccxt 4.2.77__py2.py3-none-any.whl → 4.4.48__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 (546) hide show
  1. ccxt/__init__.py +36 -14
  2. ccxt/abstract/alpaca.py +4 -0
  3. ccxt/abstract/bigone.py +1 -1
  4. ccxt/abstract/binance.py +112 -48
  5. ccxt/abstract/binancecoinm.py +112 -48
  6. ccxt/abstract/binanceus.py +147 -83
  7. ccxt/abstract/binanceusdm.py +112 -48
  8. ccxt/abstract/bingx.py +133 -78
  9. ccxt/abstract/bitbank.py +5 -0
  10. ccxt/abstract/bitfinex.py +136 -65
  11. ccxt/abstract/bitfinex1.py +69 -0
  12. ccxt/abstract/bitflyer.py +1 -0
  13. ccxt/abstract/bitget.py +8 -1
  14. ccxt/abstract/bitmart.py +13 -1
  15. ccxt/abstract/bitopro.py +1 -0
  16. ccxt/abstract/bitpanda.py +0 -12
  17. ccxt/abstract/bitrue.py +3 -3
  18. ccxt/abstract/bitstamp.py +26 -3
  19. ccxt/abstract/blofin.py +24 -0
  20. ccxt/abstract/btcbox.py +1 -0
  21. ccxt/abstract/bybit.py +29 -14
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbase.py +6 -0
  24. ccxt/abstract/coinbaseadvanced.py +94 -0
  25. ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
  26. ccxt/abstract/coinbaseinternational.py +1 -1
  27. ccxt/abstract/coincatch.py +94 -0
  28. ccxt/abstract/coinex.py +233 -123
  29. ccxt/abstract/coinmetro.py +1 -0
  30. ccxt/abstract/cryptocom.py +14 -0
  31. ccxt/abstract/defx.py +69 -0
  32. ccxt/abstract/deribit.py +1 -0
  33. ccxt/abstract/digifinex.py +1 -0
  34. ccxt/abstract/ellipx.py +25 -0
  35. ccxt/abstract/gate.py +20 -0
  36. ccxt/abstract/gateio.py +20 -0
  37. ccxt/abstract/gemini.py +1 -0
  38. ccxt/abstract/hashkey.py +67 -0
  39. ccxt/abstract/hyperliquid.py +1 -1
  40. ccxt/abstract/independentreserve.py +6 -0
  41. ccxt/abstract/kraken.py +4 -3
  42. ccxt/abstract/krakenfutures.py +4 -0
  43. ccxt/abstract/kucoin.py +24 -0
  44. ccxt/abstract/kucoinfutures.py +34 -0
  45. ccxt/abstract/luno.py +2 -0
  46. ccxt/abstract/mexc.py +4 -0
  47. ccxt/abstract/myokx.py +340 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +30 -0
  50. ccxt/abstract/onetrading.py +0 -12
  51. ccxt/abstract/oxfun.py +34 -0
  52. ccxt/abstract/paradex.py +40 -0
  53. ccxt/abstract/phemex.py +1 -0
  54. ccxt/abstract/upbit.py +4 -0
  55. ccxt/abstract/vertex.py +19 -0
  56. ccxt/abstract/whitebit.py +31 -1
  57. ccxt/abstract/woo.py +6 -2
  58. ccxt/abstract/woofipro.py +119 -0
  59. ccxt/abstract/xt.py +153 -0
  60. ccxt/abstract/zonda.py +6 -0
  61. ccxt/ace.py +164 -60
  62. ccxt/alpaca.py +727 -63
  63. ccxt/ascendex.py +395 -249
  64. ccxt/async_support/__init__.py +36 -14
  65. ccxt/async_support/ace.py +164 -60
  66. ccxt/async_support/alpaca.py +727 -63
  67. ccxt/async_support/ascendex.py +396 -249
  68. ccxt/async_support/base/exchange.py +531 -155
  69. ccxt/async_support/base/ws/aiohttp_client.py +28 -5
  70. ccxt/async_support/base/ws/cache.py +3 -2
  71. ccxt/async_support/base/ws/client.py +26 -5
  72. ccxt/async_support/base/ws/fast_client.py +4 -3
  73. ccxt/async_support/base/ws/functions.py +1 -1
  74. ccxt/async_support/base/ws/future.py +40 -31
  75. ccxt/async_support/base/ws/order_book_side.py +3 -0
  76. ccxt/async_support/bequant.py +1 -1
  77. ccxt/async_support/bigone.py +329 -202
  78. ccxt/async_support/binance.py +3030 -1087
  79. ccxt/async_support/binancecoinm.py +2 -1
  80. ccxt/async_support/binanceus.py +12 -1
  81. ccxt/async_support/binanceusdm.py +3 -1
  82. ccxt/async_support/bingx.py +3104 -880
  83. ccxt/async_support/bit2c.py +119 -38
  84. ccxt/async_support/bitbank.py +215 -76
  85. ccxt/async_support/bitbns.py +124 -53
  86. ccxt/async_support/bitfinex.py +3236 -1078
  87. ccxt/async_support/bitfinex1.py +1711 -0
  88. ccxt/async_support/bitflyer.py +238 -49
  89. ccxt/async_support/bitget.py +1513 -563
  90. ccxt/async_support/bithumb.py +199 -65
  91. ccxt/async_support/bitmart.py +1320 -435
  92. ccxt/async_support/bitmex.py +308 -111
  93. ccxt/async_support/bitopro.py +256 -96
  94. ccxt/async_support/bitrue.py +365 -233
  95. ccxt/async_support/bitso.py +201 -89
  96. ccxt/async_support/bitstamp.py +438 -269
  97. ccxt/async_support/bitteam.py +179 -73
  98. ccxt/async_support/bitvavo.py +180 -70
  99. ccxt/async_support/bl3p.py +92 -25
  100. ccxt/async_support/blockchaincom.py +193 -79
  101. ccxt/async_support/blofin.py +392 -148
  102. ccxt/async_support/btcalpha.py +161 -55
  103. ccxt/async_support/btcbox.py +250 -34
  104. ccxt/async_support/btcmarkets.py +232 -85
  105. ccxt/async_support/btcturk.py +159 -60
  106. ccxt/async_support/bybit.py +2231 -1193
  107. ccxt/async_support/cex.py +1409 -1329
  108. ccxt/async_support/coinbase.py +1454 -287
  109. ccxt/async_support/coinbaseadvanced.py +17 -0
  110. ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
  111. ccxt/async_support/coinbaseinternational.py +428 -88
  112. ccxt/async_support/coincatch.py +5152 -0
  113. ccxt/async_support/coincheck.py +121 -38
  114. ccxt/async_support/coinex.py +4020 -3339
  115. ccxt/async_support/coinlist.py +273 -116
  116. ccxt/async_support/coinmate.py +204 -97
  117. ccxt/async_support/coinmetro.py +203 -110
  118. ccxt/async_support/coinone.py +142 -68
  119. ccxt/async_support/coinsph.py +206 -89
  120. ccxt/async_support/coinspot.py +137 -62
  121. ccxt/async_support/cryptocom.py +515 -185
  122. ccxt/async_support/currencycom.py +203 -85
  123. ccxt/async_support/defx.py +2066 -0
  124. ccxt/async_support/delta.py +404 -109
  125. ccxt/async_support/deribit.py +557 -323
  126. ccxt/async_support/digifinex.py +340 -223
  127. ccxt/async_support/ellipx.py +1826 -0
  128. ccxt/async_support/exmo.py +259 -128
  129. ccxt/async_support/gate.py +1472 -463
  130. ccxt/async_support/gemini.py +206 -84
  131. ccxt/async_support/hashkey.py +4164 -0
  132. ccxt/async_support/hitbtc.py +334 -178
  133. ccxt/async_support/hollaex.py +134 -83
  134. ccxt/async_support/htx.py +1095 -563
  135. ccxt/async_support/huobijp.py +105 -56
  136. ccxt/async_support/hyperliquid.py +1633 -268
  137. ccxt/async_support/idex.py +148 -95
  138. ccxt/async_support/independentreserve.py +236 -31
  139. ccxt/async_support/indodax.py +165 -62
  140. ccxt/async_support/kraken.py +871 -354
  141. ccxt/async_support/krakenfutures.py +324 -100
  142. ccxt/async_support/kucoin.py +917 -357
  143. ccxt/async_support/kucoinfutures.py +1004 -149
  144. ccxt/async_support/kuna.py +138 -106
  145. ccxt/async_support/latoken.py +135 -79
  146. ccxt/async_support/lbank.py +290 -113
  147. ccxt/async_support/luno.py +112 -62
  148. ccxt/async_support/lykke.py +104 -55
  149. ccxt/async_support/mercado.py +36 -29
  150. ccxt/async_support/mexc.py +995 -429
  151. ccxt/async_support/myokx.py +43 -0
  152. ccxt/async_support/ndax.py +163 -82
  153. ccxt/async_support/novadax.py +121 -75
  154. ccxt/async_support/oceanex.py +175 -59
  155. ccxt/async_support/okcoin.py +222 -163
  156. ccxt/async_support/okx.py +1776 -454
  157. ccxt/async_support/onetrading.py +132 -414
  158. ccxt/async_support/oxfun.py +2832 -0
  159. ccxt/async_support/p2b.py +79 -51
  160. ccxt/async_support/paradex.py +2017 -0
  161. ccxt/async_support/paymium.py +56 -32
  162. ccxt/async_support/phemex.py +572 -196
  163. ccxt/async_support/poloniex.py +218 -95
  164. ccxt/async_support/poloniexfutures.py +260 -92
  165. ccxt/async_support/probit.py +143 -110
  166. ccxt/async_support/timex.py +123 -70
  167. ccxt/async_support/tokocrypto.py +129 -93
  168. ccxt/async_support/tradeogre.py +39 -25
  169. ccxt/async_support/upbit.py +322 -113
  170. ccxt/async_support/vertex.py +2983 -0
  171. ccxt/async_support/wavesexchange.py +227 -173
  172. ccxt/async_support/wazirx.py +145 -65
  173. ccxt/async_support/whitebit.py +533 -138
  174. ccxt/async_support/woo.py +1137 -296
  175. ccxt/async_support/woofipro.py +2716 -0
  176. ccxt/async_support/xt.py +4628 -0
  177. ccxt/async_support/yobit.py +160 -92
  178. ccxt/async_support/zaif.py +80 -33
  179. ccxt/async_support/zonda.py +140 -69
  180. ccxt/base/errors.py +51 -20
  181. ccxt/base/exchange.py +1722 -480
  182. ccxt/base/precise.py +10 -0
  183. ccxt/base/types.py +223 -4
  184. ccxt/bequant.py +1 -1
  185. ccxt/bigone.py +329 -202
  186. ccxt/binance.py +3030 -1087
  187. ccxt/binancecoinm.py +2 -1
  188. ccxt/binanceus.py +12 -1
  189. ccxt/binanceusdm.py +3 -1
  190. ccxt/bingx.py +3104 -880
  191. ccxt/bit2c.py +119 -38
  192. ccxt/bitbank.py +215 -76
  193. ccxt/bitbns.py +124 -53
  194. ccxt/bitfinex.py +3235 -1078
  195. ccxt/bitfinex1.py +1710 -0
  196. ccxt/bitflyer.py +238 -49
  197. ccxt/bitget.py +1513 -563
  198. ccxt/bithumb.py +198 -65
  199. ccxt/bitmart.py +1320 -435
  200. ccxt/bitmex.py +308 -111
  201. ccxt/bitopro.py +256 -96
  202. ccxt/bitrue.py +365 -233
  203. ccxt/bitso.py +201 -89
  204. ccxt/bitstamp.py +438 -269
  205. ccxt/bitteam.py +179 -73
  206. ccxt/bitvavo.py +180 -70
  207. ccxt/bl3p.py +92 -25
  208. ccxt/blockchaincom.py +193 -79
  209. ccxt/blofin.py +392 -148
  210. ccxt/btcalpha.py +161 -55
  211. ccxt/btcbox.py +250 -34
  212. ccxt/btcmarkets.py +232 -85
  213. ccxt/btcturk.py +159 -60
  214. ccxt/bybit.py +2231 -1193
  215. ccxt/cex.py +1408 -1329
  216. ccxt/coinbase.py +1454 -287
  217. ccxt/coinbaseadvanced.py +17 -0
  218. ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
  219. ccxt/coinbaseinternational.py +428 -88
  220. ccxt/coincatch.py +5152 -0
  221. ccxt/coincheck.py +121 -38
  222. ccxt/coinex.py +4020 -3339
  223. ccxt/coinlist.py +273 -116
  224. ccxt/coinmate.py +204 -97
  225. ccxt/coinmetro.py +203 -110
  226. ccxt/coinone.py +142 -68
  227. ccxt/coinsph.py +206 -89
  228. ccxt/coinspot.py +137 -62
  229. ccxt/cryptocom.py +515 -185
  230. ccxt/currencycom.py +203 -85
  231. ccxt/defx.py +2065 -0
  232. ccxt/delta.py +404 -109
  233. ccxt/deribit.py +557 -323
  234. ccxt/digifinex.py +340 -223
  235. ccxt/ellipx.py +1826 -0
  236. ccxt/exmo.py +259 -128
  237. ccxt/gate.py +1472 -463
  238. ccxt/gemini.py +206 -84
  239. ccxt/hashkey.py +4164 -0
  240. ccxt/hitbtc.py +334 -178
  241. ccxt/hollaex.py +134 -83
  242. ccxt/htx.py +1095 -563
  243. ccxt/huobijp.py +105 -56
  244. ccxt/hyperliquid.py +1632 -268
  245. ccxt/idex.py +148 -95
  246. ccxt/independentreserve.py +235 -31
  247. ccxt/indodax.py +165 -62
  248. ccxt/kraken.py +871 -354
  249. ccxt/krakenfutures.py +324 -100
  250. ccxt/kucoin.py +917 -357
  251. ccxt/kucoinfutures.py +1004 -149
  252. ccxt/kuna.py +138 -106
  253. ccxt/latoken.py +135 -79
  254. ccxt/lbank.py +290 -113
  255. ccxt/luno.py +112 -62
  256. ccxt/lykke.py +104 -55
  257. ccxt/mercado.py +36 -29
  258. ccxt/mexc.py +994 -429
  259. ccxt/myokx.py +43 -0
  260. ccxt/ndax.py +163 -82
  261. ccxt/novadax.py +121 -75
  262. ccxt/oceanex.py +175 -59
  263. ccxt/okcoin.py +222 -163
  264. ccxt/okx.py +1776 -454
  265. ccxt/onetrading.py +132 -414
  266. ccxt/oxfun.py +2831 -0
  267. ccxt/p2b.py +79 -51
  268. ccxt/paradex.py +2017 -0
  269. ccxt/paymium.py +56 -32
  270. ccxt/phemex.py +572 -196
  271. ccxt/poloniex.py +218 -95
  272. ccxt/poloniexfutures.py +260 -92
  273. ccxt/pro/__init__.py +29 -5
  274. ccxt/pro/alpaca.py +32 -17
  275. ccxt/pro/ascendex.py +62 -14
  276. ccxt/pro/bequant.py +4 -0
  277. ccxt/pro/binance.py +1596 -329
  278. ccxt/pro/binancecoinm.py +1 -0
  279. ccxt/pro/binanceus.py +2 -9
  280. ccxt/pro/binanceusdm.py +2 -0
  281. ccxt/pro/bingx.py +527 -134
  282. ccxt/pro/bitcoincom.py +4 -1
  283. ccxt/pro/bitfinex.py +731 -266
  284. ccxt/pro/bitfinex1.py +635 -0
  285. ccxt/pro/bitget.py +726 -357
  286. ccxt/pro/bithumb.py +380 -0
  287. ccxt/pro/bitmart.py +138 -39
  288. ccxt/pro/bitmex.py +199 -40
  289. ccxt/pro/bitopro.py +25 -13
  290. ccxt/pro/bitrue.py +31 -32
  291. ccxt/pro/bitstamp.py +7 -6
  292. ccxt/pro/bitvavo.py +203 -81
  293. ccxt/pro/blockchaincom.py +30 -17
  294. ccxt/pro/blofin.py +692 -0
  295. ccxt/pro/bybit.py +791 -82
  296. ccxt/pro/cex.py +99 -51
  297. ccxt/pro/coinbase.py +220 -30
  298. ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
  299. ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
  300. ccxt/pro/coinbaseinternational.py +193 -30
  301. ccxt/pro/coincatch.py +1464 -0
  302. ccxt/pro/coincheck.py +11 -6
  303. ccxt/pro/coinex.py +965 -665
  304. ccxt/pro/coinone.py +17 -10
  305. ccxt/pro/cryptocom.py +446 -66
  306. ccxt/pro/currencycom.py +11 -10
  307. ccxt/pro/defx.py +832 -0
  308. ccxt/pro/deribit.py +167 -31
  309. ccxt/pro/exmo.py +252 -20
  310. ccxt/pro/gate.py +729 -64
  311. ccxt/pro/gemini.py +44 -26
  312. ccxt/pro/hashkey.py +802 -0
  313. ccxt/pro/hitbtc.py +208 -103
  314. ccxt/pro/hollaex.py +25 -9
  315. ccxt/pro/htx.py +83 -39
  316. ccxt/pro/huobijp.py +17 -16
  317. ccxt/pro/hyperliquid.py +502 -31
  318. ccxt/pro/idex.py +28 -13
  319. ccxt/pro/independentreserve.py +21 -16
  320. ccxt/pro/kraken.py +298 -51
  321. ccxt/pro/krakenfutures.py +166 -75
  322. ccxt/pro/kucoin.py +395 -77
  323. ccxt/pro/kucoinfutures.py +400 -99
  324. ccxt/pro/lbank.py +52 -31
  325. ccxt/pro/luno.py +12 -10
  326. ccxt/pro/mexc.py +400 -50
  327. ccxt/pro/myokx.py +28 -0
  328. ccxt/pro/ndax.py +25 -12
  329. ccxt/pro/okcoin.py +28 -9
  330. ccxt/pro/okx.py +935 -124
  331. ccxt/pro/onetrading.py +41 -24
  332. ccxt/pro/oxfun.py +1054 -0
  333. ccxt/pro/p2b.py +100 -24
  334. ccxt/pro/paradex.py +352 -0
  335. ccxt/pro/phemex.py +92 -33
  336. ccxt/pro/poloniex.py +128 -49
  337. ccxt/pro/poloniexfutures.py +53 -32
  338. ccxt/pro/probit.py +92 -85
  339. ccxt/pro/upbit.py +401 -8
  340. ccxt/pro/vertex.py +943 -0
  341. ccxt/pro/wazirx.py +46 -28
  342. ccxt/pro/whitebit.py +65 -12
  343. ccxt/pro/woo.py +437 -65
  344. ccxt/pro/woofipro.py +1271 -0
  345. ccxt/pro/xt.py +1067 -0
  346. ccxt/probit.py +143 -110
  347. ccxt/static_dependencies/__init__.py +1 -1
  348. ccxt/static_dependencies/lark/__init__.py +38 -0
  349. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  350. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  351. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  352. ccxt/static_dependencies/lark/common.py +86 -0
  353. ccxt/static_dependencies/lark/exceptions.py +292 -0
  354. ccxt/static_dependencies/lark/grammar.py +130 -0
  355. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  356. ccxt/static_dependencies/lark/indenter.py +143 -0
  357. ccxt/static_dependencies/lark/lark.py +658 -0
  358. ccxt/static_dependencies/lark/lexer.py +678 -0
  359. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  360. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  361. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  362. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  363. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  364. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  365. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  366. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  367. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  368. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  369. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  370. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  371. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  372. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  373. ccxt/static_dependencies/lark/py.typed +0 -0
  374. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  375. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  376. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  377. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  378. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  379. ccxt/static_dependencies/lark/tree.py +267 -0
  380. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  381. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  382. ccxt/static_dependencies/lark/utils.py +343 -0
  383. ccxt/static_dependencies/lark/visitors.py +596 -0
  384. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  385. ccxt/static_dependencies/marshmallow/base.py +65 -0
  386. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  387. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  388. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  389. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  390. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  391. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  392. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  393. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  394. ccxt/static_dependencies/marshmallow/types.py +12 -0
  395. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  396. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  397. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  398. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  399. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  400. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  401. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  402. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  403. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  404. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  405. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  406. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  407. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  408. ccxt/static_dependencies/starknet/__init__.py +0 -0
  409. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  410. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  411. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  412. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  413. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  414. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  415. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  416. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  417. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  418. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  419. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  420. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  421. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  422. ccxt/static_dependencies/starknet/common.py +15 -0
  423. ccxt/static_dependencies/starknet/constants.py +39 -0
  424. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  425. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  426. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  427. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  428. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  429. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  430. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  431. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  432. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  433. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  434. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  435. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  436. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  437. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  438. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  439. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  440. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  441. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  442. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  443. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  444. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  445. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  446. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  447. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  448. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  449. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  450. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  451. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  452. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  453. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  454. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  455. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  456. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  457. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  458. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  459. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  460. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  461. ccxt/static_dependencies/starkware/__init__.py +0 -0
  462. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  463. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  464. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  465. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  466. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  467. ccxt/static_dependencies/sympy/__init__.py +0 -0
  468. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  469. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  470. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  471. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  472. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  473. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  474. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  475. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  476. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  477. ccxt/test/{test_async.py → tests_async.py} +456 -391
  478. ccxt/test/tests_helpers.py +285 -0
  479. ccxt/test/tests_init.py +39 -0
  480. ccxt/test/{test_sync.py → tests_sync.py} +456 -393
  481. ccxt/timex.py +123 -70
  482. ccxt/tokocrypto.py +129 -93
  483. ccxt/tradeogre.py +39 -25
  484. ccxt/upbit.py +322 -113
  485. ccxt/vertex.py +2983 -0
  486. ccxt/wavesexchange.py +227 -173
  487. ccxt/wazirx.py +145 -65
  488. ccxt/whitebit.py +533 -138
  489. ccxt/woo.py +1137 -296
  490. ccxt/woofipro.py +2716 -0
  491. ccxt/xt.py +4627 -0
  492. ccxt/yobit.py +159 -92
  493. ccxt/zaif.py +80 -33
  494. ccxt/zonda.py +140 -69
  495. ccxt-4.4.48.dist-info/LICENSE.txt +21 -0
  496. ccxt-4.4.48.dist-info/METADATA +646 -0
  497. ccxt-4.4.48.dist-info/RECORD +669 -0
  498. {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/WHEEL +1 -1
  499. ccxt/abstract/bitbay.py +0 -47
  500. ccxt/abstract/bitfinex2.py +0 -139
  501. ccxt/abstract/hitbtc3.py +0 -115
  502. ccxt/async_support/bitbay.py +0 -17
  503. ccxt/async_support/bitfinex2.py +0 -3496
  504. ccxt/async_support/flowbtc.py +0 -34
  505. ccxt/bitbay.py +0 -17
  506. ccxt/bitfinex2.py +0 -3496
  507. ccxt/flowbtc.py +0 -34
  508. ccxt/hitbtc3.py +0 -16
  509. ccxt/pro/bitfinex2.py +0 -1081
  510. ccxt/test/base/__init__.py +0 -28
  511. ccxt/test/base/test_account.py +0 -26
  512. ccxt/test/base/test_balance.py +0 -56
  513. ccxt/test/base/test_borrow_interest.py +0 -35
  514. ccxt/test/base/test_borrow_rate.py +0 -32
  515. ccxt/test/base/test_calculate_fee.py +0 -51
  516. ccxt/test/base/test_crypto.py +0 -127
  517. ccxt/test/base/test_currency.py +0 -76
  518. ccxt/test/base/test_datetime.py +0 -103
  519. ccxt/test/base/test_decimal_to_precision.py +0 -392
  520. ccxt/test/base/test_deep_extend.py +0 -68
  521. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  522. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  523. ccxt/test/base/test_funding_rate_history.py +0 -29
  524. ccxt/test/base/test_last_price.py +0 -32
  525. ccxt/test/base/test_ledger_entry.py +0 -45
  526. ccxt/test/base/test_ledger_item.py +0 -48
  527. ccxt/test/base/test_leverage_tier.py +0 -33
  528. ccxt/test/base/test_margin_mode.py +0 -24
  529. ccxt/test/base/test_margin_modification.py +0 -35
  530. ccxt/test/base/test_market.py +0 -190
  531. ccxt/test/base/test_number.py +0 -411
  532. ccxt/test/base/test_ohlcv.py +0 -32
  533. ccxt/test/base/test_open_interest.py +0 -32
  534. ccxt/test/base/test_order.py +0 -64
  535. ccxt/test/base/test_order_book.py +0 -63
  536. ccxt/test/base/test_position.py +0 -60
  537. ccxt/test/base/test_shared_methods.py +0 -345
  538. ccxt/test/base/test_status.py +0 -24
  539. ccxt/test/base/test_throttle.py +0 -126
  540. ccxt/test/base/test_ticker.py +0 -86
  541. ccxt/test/base/test_trade.py +0 -47
  542. ccxt/test/base/test_trading_fee.py +0 -26
  543. ccxt/test/base/test_transaction.py +0 -39
  544. ccxt-4.2.77.dist-info/METADATA +0 -626
  545. ccxt-4.2.77.dist-info/RECORD +0 -534
  546. {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
ccxt/pro/bitget.py CHANGED
@@ -9,13 +9,14 @@ import hashlib
9
9
  from ccxt.base.types import Balances, 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
+ from typing import Any
12
13
  from ccxt.base.errors import ExchangeError
14
+ from ccxt.base.errors import AuthenticationError
13
15
  from ccxt.base.errors import ArgumentsRequired
14
16
  from ccxt.base.errors import BadRequest
15
- from ccxt.base.errors import NotSupported
16
17
  from ccxt.base.errors import RateLimitExceeded
17
- from ccxt.base.errors import InvalidNonce
18
- from ccxt.base.errors import AuthenticationError
18
+ from ccxt.base.errors import ChecksumError
19
+ from ccxt.base.errors import UnsubscribeError
19
20
  from ccxt.base.precise import Precise
20
21
 
21
22
 
@@ -41,6 +42,7 @@ class bitget(ccxt.async_support.bitget):
41
42
  'watchOrders': True,
42
43
  'watchTicker': True,
43
44
  'watchTickers': True,
45
+ 'watchBidsAsks': True,
44
46
  'watchTrades': True,
45
47
  'watchTradesForSymbols': True,
46
48
  'watchPositions': True,
@@ -69,6 +71,9 @@ class bitget(ccxt.async_support.bitget):
69
71
  '1d': '1D',
70
72
  '1w': '1W',
71
73
  },
74
+ 'watchOrderBook': {
75
+ 'checksum': True,
76
+ },
72
77
  },
73
78
  'streaming': {
74
79
  'ping': self.ping,
@@ -90,6 +95,7 @@ class bitget(ccxt.async_support.bitget):
90
95
  '30015': AuthenticationError, # {event: 'error', code: 30015, msg: 'Invalid sign'}
91
96
  '30016': BadRequest, # {event: 'error', code: 30016, msg: 'Param error'}
92
97
  },
98
+ 'broad': {},
93
99
  },
94
100
  },
95
101
  })
@@ -110,8 +116,10 @@ class bitget(ccxt.async_support.bitget):
110
116
  async def watch_ticker(self, symbol: str, params={}) -> Ticker:
111
117
  """
112
118
  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
119
+
120
+ https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
121
+ https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
122
+
115
123
  :param str symbol: unified symbol of the market to watch the ticker for
116
124
  :param dict [params]: extra parameters specific to the exchange API endpoint
117
125
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -122,18 +130,34 @@ class bitget(ccxt.async_support.bitget):
122
130
  messageHash = 'ticker:' + symbol
123
131
  instType = None
124
132
  instType, params = self.get_inst_type(market, params)
125
- args = {
133
+ args: dict = {
126
134
  'instType': instType,
127
135
  'channel': 'ticker',
128
136
  'instId': market['id'],
129
137
  }
130
138
  return await self.watch_public(messageHash, args, params)
131
139
 
140
+ async def un_watch_ticker(self, symbol: str, params={}) -> Any:
141
+ """
142
+ unsubscribe from the ticker channel
143
+
144
+ https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
145
+ https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
146
+
147
+ :param str symbol: unified symbol of the market to unwatch the ticker for
148
+ :param dict [params]: extra parameters specific to the exchange API endpoint
149
+ :returns any: status of the unwatch request
150
+ """
151
+ await self.load_markets()
152
+ return await self.un_watch_channel(symbol, 'ticker', 'ticker', params)
153
+
132
154
  async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
133
155
  """
134
156
  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
157
+
158
+ https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
159
+ https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
160
+
137
161
  :param str[] symbols: unified symbol of the market to watch the tickers for
138
162
  :param dict [params]: extra parameters specific to the exchange API endpoint
139
163
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -148,7 +172,7 @@ class bitget(ccxt.async_support.bitget):
148
172
  for i in range(0, len(symbols)):
149
173
  symbol = symbols[i]
150
174
  marketInner = self.market(symbol)
151
- args = {
175
+ args: dict = {
152
176
  'instType': instType,
153
177
  'channel': 'ticker',
154
178
  'instId': marketInner['id'],
@@ -157,7 +181,7 @@ class bitget(ccxt.async_support.bitget):
157
181
  messageHashes.append('ticker:' + symbol)
158
182
  tickers = await self.watch_public_multiple(messageHashes, topics, params)
159
183
  if self.newUpdates:
160
- result = {}
184
+ result: dict = {}
161
185
  result[tickers['symbol']] = tickers
162
186
  return result
163
187
  return self.filter_by_array(self.tickers, 'symbol', symbols)
@@ -193,6 +217,7 @@ class bitget(ccxt.async_support.bitget):
193
217
  # "ts": 1701842994341
194
218
  # }
195
219
  #
220
+ self.handle_bid_ask(client, message)
196
221
  ticker = self.parse_ws_ticker(message)
197
222
  symbol = ticker['symbol']
198
223
  self.tickers[symbol] = ticker
@@ -304,11 +329,75 @@ class bitget(ccxt.async_support.bitget):
304
329
  'info': ticker,
305
330
  }, market)
306
331
 
332
+ async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
333
+ """
334
+
335
+ https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
336
+ https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
337
+
338
+ watches best bid & ask for symbols
339
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
340
+ :param dict [params]: extra parameters specific to the exchange API endpoint
341
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
342
+ """
343
+ await self.load_markets()
344
+ symbols = self.market_symbols(symbols, None, False)
345
+ market = self.market(symbols[0])
346
+ instType = None
347
+ instType, params = self.get_inst_type(market, params)
348
+ topics = []
349
+ messageHashes = []
350
+ for i in range(0, len(symbols)):
351
+ symbol = symbols[i]
352
+ marketInner = self.market(symbol)
353
+ args: dict = {
354
+ 'instType': instType,
355
+ 'channel': 'ticker',
356
+ 'instId': marketInner['id'],
357
+ }
358
+ topics.append(args)
359
+ messageHashes.append('bidask:' + symbol)
360
+ tickers = await self.watch_public_multiple(messageHashes, topics, params)
361
+ if self.newUpdates:
362
+ result: dict = {}
363
+ result[tickers['symbol']] = tickers
364
+ return result
365
+ return self.filter_by_array(self.bidsasks, 'symbol', symbols)
366
+
367
+ def handle_bid_ask(self, client: Client, message):
368
+ ticker = self.parse_ws_bid_ask(message)
369
+ symbol = ticker['symbol']
370
+ self.bidsasks[symbol] = ticker
371
+ messageHash = 'bidask:' + symbol
372
+ client.resolve(ticker, messageHash)
373
+
374
+ def parse_ws_bid_ask(self, message, market=None):
375
+ arg = self.safe_value(message, 'arg', {})
376
+ data = self.safe_value(message, 'data', [])
377
+ ticker = self.safe_value(data, 0, {})
378
+ timestamp = self.safe_integer(ticker, 'ts')
379
+ instType = self.safe_string(arg, 'instType')
380
+ marketType = 'spot' if (instType == 'SPOT') else 'contract'
381
+ marketId = self.safe_string(ticker, 'instId')
382
+ market = self.safe_market(marketId, market, None, marketType)
383
+ return self.safe_ticker({
384
+ 'symbol': market['symbol'],
385
+ 'timestamp': timestamp,
386
+ 'datetime': self.iso8601(timestamp),
387
+ 'ask': self.safe_string(ticker, 'askPr'),
388
+ 'askVolume': self.safe_string(ticker, 'askSz'),
389
+ 'bid': self.safe_string(ticker, 'bidPr'),
390
+ 'bidVolume': self.safe_string(ticker, 'bidSz'),
391
+ 'info': ticker,
392
+ }, market)
393
+
307
394
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
308
395
  """
309
396
  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
397
+
398
+ https://www.bitget.com/api-doc/spot/websocket/public/Candlesticks-Channel
399
+ https://www.bitget.com/api-doc/contract/websocket/public/Candlesticks-Channel
400
+
312
401
  :param str symbol: unified symbol of the market to fetch OHLCV data for
313
402
  :param str timeframe: the length of time each candle represents
314
403
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -324,7 +413,7 @@ class bitget(ccxt.async_support.bitget):
324
413
  messageHash = 'candles:' + timeframe + ':' + symbol
325
414
  instType = None
326
415
  instType, params = self.get_inst_type(market, params)
327
- args = {
416
+ args: dict = {
328
417
  'instType': instType,
329
418
  'channel': 'candle' + interval,
330
419
  'instId': market['id'],
@@ -334,6 +423,24 @@ class bitget(ccxt.async_support.bitget):
334
423
  limit = ohlcv.getLimit(symbol, limit)
335
424
  return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
336
425
 
426
+ async def un_watch_ohlcv(self, symbol: str, timeframe='1m', params={}) -> Any:
427
+ """
428
+ unsubscribe from the ohlcv channel
429
+
430
+ https://www.bitget.com/api-doc/spot/websocket/public/Candlesticks-Channel
431
+ https://www.bitget.com/api-doc/contract/websocket/public/Candlesticks-Channel
432
+
433
+ :param str symbol: unified symbol of the market to unwatch the ohlcv for
434
+ :param str [timeframe]: the period for the ratio, default is 1 minute
435
+ :param dict [params]: extra parameters specific to the exchange API endpoint
436
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
437
+ """
438
+ await self.load_markets()
439
+ timeframes = self.safe_dict(self.options, 'timeframes')
440
+ interval = self.safe_string(timeframes, timeframe)
441
+ channel = 'candle' + interval
442
+ return await self.un_watch_channel(symbol, channel, 'candles:' + timeframe, params)
443
+
337
444
  def handle_ohlcv(self, client: Client, message):
338
445
  #
339
446
  # {
@@ -417,8 +524,10 @@ class bitget(ccxt.async_support.bitget):
417
524
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
418
525
  """
419
526
  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
527
+
528
+ https://www.bitget.com/api-doc/spot/websocket/public/Depth-Channel
529
+ https://www.bitget.com/api-doc/contract/websocket/public/Order-Book-Channel
530
+
422
531
  :param str symbol: unified symbol of the market to fetch the order book for
423
532
  :param int [limit]: the maximum amount of order book entries to return
424
533
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -426,11 +535,46 @@ class bitget(ccxt.async_support.bitget):
426
535
  """
427
536
  return await self.watch_order_book_for_symbols([symbol], limit, params)
428
537
 
538
+ async def un_watch_order_book(self, symbol: str, params={}) -> Any:
539
+ """
540
+ unsubscribe from the orderbook channel
541
+
542
+ https://www.bitget.com/api-doc/spot/websocket/public/Depth-Channel
543
+ https://www.bitget.com/api-doc/contract/websocket/public/Order-Book-Channel
544
+
545
+ :param str symbol: unified symbol of the market to fetch the order book for
546
+ :param dict [params]: extra parameters specific to the exchange API endpoint
547
+ :param int [params.limit]: orderbook limit, default is None
548
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
549
+ """
550
+ await self.load_markets()
551
+ channel = 'books'
552
+ limit = self.safe_integer(params, 'limit')
553
+ if (limit == 1) or (limit == 5) or (limit == 15):
554
+ params = self.omit(params, 'limit')
555
+ channel += str(limit)
556
+ return await self.un_watch_channel(symbol, channel, 'orderbook', params)
557
+
558
+ async def un_watch_channel(self, symbol: str, channel: str, messageHashTopic: str, params={}) -> Any:
559
+ await self.load_markets()
560
+ market = self.market(symbol)
561
+ messageHash = 'unsubscribe:' + messageHashTopic + ':' + market['symbol']
562
+ instType = None
563
+ instType, params = self.get_inst_type(market, params)
564
+ args: dict = {
565
+ 'instType': instType,
566
+ 'channel': channel,
567
+ 'instId': market['id'],
568
+ }
569
+ return await self.un_watch_public(messageHash, args, params)
570
+
429
571
  async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
430
572
  """
431
573
  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
574
+
575
+ https://www.bitget.com/api-doc/spot/websocket/public/Depth-Channel
576
+ https://www.bitget.com/api-doc/contract/websocket/public/Order-Book-Channel
577
+
434
578
  :param str[] symbols: unified array of symbols
435
579
  :param int [limit]: the maximum amount of order book entries to return
436
580
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -450,7 +594,7 @@ class bitget(ccxt.async_support.bitget):
450
594
  market = self.market(symbol)
451
595
  instType = None
452
596
  instType, params = self.get_inst_type(market, params)
453
- args = {
597
+ args: dict = {
454
598
  'instType': instType,
455
599
  'channel': channel,
456
600
  'instId': market['id'],
@@ -520,7 +664,7 @@ class bitget(ccxt.async_support.bitget):
520
664
  self.handle_deltas(storedOrderBook['bids'], bids)
521
665
  storedOrderBook['timestamp'] = timestamp
522
666
  storedOrderBook['datetime'] = self.iso8601(timestamp)
523
- checksum = self.safe_bool(self.options, 'checksum', True)
667
+ checksum = self.handle_option('watchOrderBook', 'checksum', True)
524
668
  isSnapshot = self.safe_string(message, 'action') == 'snapshot' # snapshot does not have a checksum
525
669
  if not isSnapshot and checksum:
526
670
  storedAsks = storedOrderBook['asks']
@@ -539,8 +683,12 @@ class bitget(ccxt.async_support.bitget):
539
683
  calculatedChecksum = self.crc32(payload, True)
540
684
  responseChecksum = self.safe_integer(rawOrderBook, 'checksum')
541
685
  if calculatedChecksum != responseChecksum:
542
- error = InvalidNonce(self.id + ' invalid checksum')
543
- client.reject(error, messageHash)
686
+ # if messageHash in client.subscriptions:
687
+ # # del client.subscriptions[messageHash]
688
+ # # del self.orderbooks[symbol]
689
+ # }
690
+ self.spawn(self.handle_check_sum_error, client, symbol, messageHash)
691
+ return
544
692
  else:
545
693
  orderbook = self.order_book({})
546
694
  parsedOrderbook = self.parse_order_book(rawOrderBook, symbol, timestamp)
@@ -548,6 +696,11 @@ class bitget(ccxt.async_support.bitget):
548
696
  self.orderbooks[symbol] = orderbook
549
697
  client.resolve(self.orderbooks[symbol], messageHash)
550
698
 
699
+ async def handle_check_sum_error(self, client: Client, symbol: str, messageHash: str):
700
+ await self.un_watch_order_book(symbol)
701
+ error = ChecksumError(self.id + ' ' + self.orderbook_checksum_message(symbol))
702
+ client.reject(error, messageHash)
703
+
551
704
  def handle_delta(self, bookside, delta):
552
705
  bidAsk = self.parse_bid_ask(delta, 0, 1)
553
706
  # we store the string representations in the orderbook for checksum calculation
@@ -562,8 +715,10 @@ class bitget(ccxt.async_support.bitget):
562
715
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
563
716
  """
564
717
  get the list of most recent trades for a particular symbol
565
- :see: https://www.bitget.com/api-doc/spot/websocket/public/Trades-Channel
566
- :see: https://www.bitget.com/api-doc/contract/websocket/public/New-Trades-Channel
718
+
719
+ https://www.bitget.com/api-doc/spot/websocket/public/Trades-Channel
720
+ https://www.bitget.com/api-doc/contract/websocket/public/New-Trades-Channel
721
+
567
722
  :param str symbol: unified symbol of the market to fetch trades for
568
723
  :param int [since]: timestamp in ms of the earliest trade to fetch
569
724
  :param int [limit]: the maximum amount of trades to fetch
@@ -575,9 +730,11 @@ class bitget(ccxt.async_support.bitget):
575
730
  async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
576
731
  """
577
732
  get the list of most recent trades for a particular symbol
578
- :see: https://www.bitget.com/api-doc/spot/websocket/public/Trades-Channel
579
- :see: https://www.bitget.com/api-doc/contract/websocket/public/New-Trades-Channel
580
- :param str symbol: unified symbol of the market to fetch trades for
733
+
734
+ https://www.bitget.com/api-doc/spot/websocket/public/Trades-Channel
735
+ https://www.bitget.com/api-doc/contract/websocket/public/New-Trades-Channel
736
+
737
+ :param str[] symbols: unified symbol of the market to fetch trades for
581
738
  :param int [since]: timestamp in ms of the earliest trade to fetch
582
739
  :param int [limit]: the maximum amount of trades to fetch
583
740
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -595,7 +752,7 @@ class bitget(ccxt.async_support.bitget):
595
752
  market = self.market(symbol)
596
753
  instType = None
597
754
  instType, params = self.get_inst_type(market, params)
598
- args = {
755
+ args: dict = {
599
756
  'instType': instType,
600
757
  'channel': 'trade',
601
758
  'instId': market['id'],
@@ -609,6 +766,20 @@ class bitget(ccxt.async_support.bitget):
609
766
  limit = trades.getLimit(tradeSymbol, limit)
610
767
  return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
611
768
 
769
+ async def un_watch_trades(self, symbol: str, params={}) -> Any:
770
+ """
771
+ unsubscribe from the trades channel
772
+
773
+ https://www.bitget.com/api-doc/spot/websocket/public/Trades-Channel
774
+ https://www.bitget.com/api-doc/contract/websocket/public/New-Trades-Channel
775
+
776
+ :param str symbol: unified symbol of the market to unwatch the trades for
777
+ :param dict [params]: extra parameters specific to the exchange API endpoint
778
+ :returns any: status of the unwatch request
779
+ """
780
+ await self.load_markets()
781
+ return await self.un_watch_channel(symbol, 'trade', 'trade', params)
782
+
612
783
  def handle_trades(self, client: Client, message):
613
784
  #
614
785
  # {
@@ -657,54 +828,69 @@ class bitget(ccxt.async_support.bitget):
657
828
  # "side": "buy",
658
829
  # "tradeId": "1116461060594286593"
659
830
  # }
831
+ # swap private
660
832
  #
661
- # order with trade in it
662
- # {
663
- # accBaseVolume: '0.1',
664
- # baseVolume: '0.1',
665
- # cTime: '1709221342922',
666
- # clientOid: '1147122943507734528',
667
- # enterPointSource: 'API',
668
- # feeDetail: [Array],
669
- # fillFee: '-0.0049578',
670
- # fillFeeCoin: 'USDT',
671
- # fillNotionalUsd: '8.263',
672
- # fillPrice: '82.63',
673
- # fillTime: '1709221342986',
674
- # force: 'gtc',
675
- # instId: 'LTCUSDT',
676
- # leverage: '10',
677
- # marginCoin: 'USDT',
678
- # marginMode: 'crossed',
679
- # notionalUsd: '8.268',
680
- # orderId: '1147122943499345921',
681
- # orderType: 'market',
682
- # pnl: '0',
683
- # posMode: 'hedge_mode',
684
- # posSide: 'short',
685
- # price: '0',
686
- # priceAvg: '82.63',
687
- # reduceOnly: 'no',
688
- # side: 'sell',
689
- # size: '0.1',
690
- # status: 'filled',
691
- # tradeId: '1147122943772479563',
692
- # tradeScope: 'T',
693
- # tradeSide: 'open',
694
- # uTime: '1709221342986'
695
- # }
833
+ # {
834
+ # "orderId": "1169142761031114781",
835
+ # "tradeId": "1169142761312637004",
836
+ # "symbol": "LTCUSDT",
837
+ # "orderType": "market",
838
+ # "side": "buy",
839
+ # "price": "80.87",
840
+ # "baseVolume": "0.1",
841
+ # "quoteVolume": "8.087",
842
+ # "profit": "0",
843
+ # "tradeSide": "open",
844
+ # "posMode": "hedge_mode",
845
+ # "tradeScope": "taker",
846
+ # "feeDetail": [
847
+ # {
848
+ # "feeCoin": "USDT",
849
+ # "deduction": "no",
850
+ # "totalDeductionFee": "0",
851
+ # "totalFee": "-0.0048522"
852
+ # }
853
+ # ],
854
+ # "cTime": "1714471276596",
855
+ # "uTime": "1714471276596"
856
+ # }
857
+ # spot private
858
+ # {
859
+ # "orderId": "1169142457356959747",
860
+ # "tradeId": "1169142457636958209",
861
+ # "symbol": "LTCUSDT",
862
+ # "orderType": "market",
863
+ # "side": "buy",
864
+ # "priceAvg": "81.069",
865
+ # "size": "0.074",
866
+ # "amount": "5.999106",
867
+ # "tradeScope": "taker",
868
+ # "feeDetail": [
869
+ # {
870
+ # "feeCoin": "LTC",
871
+ # "deduction": "no",
872
+ # "totalDeductionFee": "0",
873
+ # "totalFee": "0.000074"
874
+ # }
875
+ # ],
876
+ # "cTime": "1714471204194",
877
+ # "uTime": "1714471204194"
878
+ # }
696
879
  #
697
- instId = self.safe_string(trade, 'instId')
880
+ instId = self.safe_string_2(trade, 'symbol', 'instId')
881
+ posMode = self.safe_string(trade, 'posMode')
882
+ defaultType = 'contract' if (posMode is not None) else 'spot'
698
883
  if market is None:
699
- market = self.safe_market(instId, None, None, 'contract')
884
+ market = self.safe_market(instId, None, None, defaultType)
700
885
  timestamp = self.safe_integer_n(trade, ['uTime', 'cTime', 'ts'])
701
- feeCost = self.safe_string(trade, 'fillFee')
886
+ feeDetail = self.safe_list(trade, 'feeDetail', [])
887
+ first = self.safe_dict(feeDetail, 0)
702
888
  fee = None
703
- if feeCost is not None:
704
- feeCurrencyId = self.safe_string(trade, 'fillFeeCoin')
889
+ if first is not None:
890
+ feeCurrencyId = self.safe_string(first, 'feeCoin')
705
891
  feeCurrencyCode = self.safe_currency_code(feeCurrencyId)
706
892
  fee = {
707
- 'cost': Precise.string_abs(feeCost),
893
+ 'cost': Precise.string_abs(self.safe_string(first, 'totalFee')),
708
894
  'currency': feeCurrencyCode,
709
895
  }
710
896
  return self.safe_trade({
@@ -714,20 +900,24 @@ class bitget(ccxt.async_support.bitget):
714
900
  'timestamp': timestamp,
715
901
  'datetime': self.iso8601(timestamp),
716
902
  'symbol': market['symbol'],
717
- 'type': None,
903
+ 'type': self.safe_string(trade, 'orderType'),
718
904
  'side': self.safe_string(trade, 'side'),
719
- 'takerOrMaker': None,
905
+ 'takerOrMaker': self.safe_string(trade, 'tradeScope'),
720
906
  'price': self.safe_string_2(trade, 'priceAvg', 'price'),
721
- 'amount': self.safe_string(trade, 'size'),
722
- 'cost': self.safe_string(trade, 'fillNotionalUsd'),
907
+ 'amount': self.safe_string_2(trade, 'size', 'baseVolume'),
908
+ 'cost': self.safe_string_2(trade, 'amount', 'quoteVolume'),
723
909
  'fee': fee,
724
910
  }, market)
725
911
 
726
912
  async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
727
913
  """
728
914
  watch all open positions
729
- :see: https://www.bitget.com/api-doc/contract/websocket/private/Positions-Channel
915
+
916
+ https://www.bitget.com/api-doc/contract/websocket/private/Positions-Channel
917
+
730
918
  :param str[]|None symbols: list of unified market symbols
919
+ :param int [since]: the earliest time in ms to fetch positions for
920
+ :param int [limit]: the maximum number of positions to retrieve
731
921
  :param dict params: extra parameters specific to the exchange API endpoint
732
922
  :param str [params.instType]: one of 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES', default is 'USDT-FUTURES'
733
923
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
@@ -742,7 +932,7 @@ class bitget(ccxt.async_support.bitget):
742
932
  market = self.get_market_from_symbols(symbols)
743
933
  instType, params = self.get_inst_type(market, params)
744
934
  messageHash = instType + ':positions' + messageHash
745
- args = {
935
+ args: dict = {
746
936
  'instType': instType,
747
937
  'channel': 'positions',
748
938
  'instId': 'default',
@@ -794,13 +984,11 @@ class bitget(ccxt.async_support.bitget):
794
984
  instType = self.safe_string(arg, 'instType', '')
795
985
  if self.positions is None:
796
986
  self.positions = {}
797
- if not (instType in self.positions):
987
+ action = self.safe_string(message, 'action')
988
+ if not (instType in self.positions) or (action == 'snapshot'):
798
989
  self.positions[instType] = ArrayCacheBySymbolBySide()
799
990
  cache = self.positions[instType]
800
991
  rawPositions = self.safe_value(message, 'data', [])
801
- dataLength = len(rawPositions)
802
- if dataLength == 0:
803
- return
804
992
  newPositions = []
805
993
  for i in range(0, len(rawPositions)):
806
994
  rawPosition = rawPositions[i]
@@ -889,54 +1077,72 @@ class bitget(ccxt.async_support.bitget):
889
1077
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
890
1078
  """
891
1079
  watches information on multiple orders made by the user
892
- :see: https://www.bitget.com/api-doc/spot/websocket/private/Order-Channel
893
- :see: https://www.bitget.com/api-doc/contract/websocket/private/Order-Channel
894
- :see: https://www.bitget.com/api-doc/contract/websocket/private/Plan-Order-Channel
895
- :see: https://www.bitget.com/api-doc/margin/cross/websocket/private/Cross-Orders
896
- :see: https://www.bitget.com/api-doc/margin/isolated/websocket/private/Isolate-Orders
1080
+
1081
+ https://www.bitget.com/api-doc/spot/websocket/private/Order-Channel
1082
+ https://www.bitget.com/api-doc/contract/websocket/private/Order-Channel
1083
+ https://www.bitget.com/api-doc/contract/websocket/private/Plan-Order-Channel
1084
+ https://www.bitget.com/api-doc/margin/cross/websocket/private/Cross-Orders
1085
+ https://www.bitget.com/api-doc/margin/isolated/websocket/private/Isolate-Orders
1086
+
897
1087
  :param str symbol: unified market symbol of the market orders were made in
898
1088
  :param int [since]: the earliest time in ms to fetch orders for
899
1089
  :param int [limit]: the maximum number of order structures to retrieve
900
1090
  :param dict [params]: extra parameters specific to the exchange API endpoint
901
- :param boolean [params.stop]: *contract only* set to True for watching trigger orders
902
- :param str [params.marginMode]: 'isolated' or 'cross' for watching spot margin orders
903
- :returns dict[]: a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
1091
+ :param boolean [params.trigger]: *contract only* set to True for watching trigger orders
1092
+ :param str [params.marginMode]: 'isolated' or 'cross' for watching spot margin orders]
1093
+ :param str [params.type]: 'spot', 'swap'
1094
+ :param str [params.subType]: 'linear', 'inverse'
1095
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
904
1096
  """
905
1097
  await self.load_markets()
906
1098
  market = None
907
1099
  marketId = None
908
- isStop = self.safe_bool(params, 'stop', False)
909
- params = self.omit(params, 'stop')
910
- messageHash = 'triggerOrder' if (isStop) else 'order'
1100
+ isTrigger = None
1101
+ isTrigger, params = self.is_trigger_order(params)
1102
+ messageHash = 'triggerOrder' if (isTrigger) else 'order'
911
1103
  subscriptionHash = 'order:trades'
912
1104
  if symbol is not None:
913
1105
  market = self.market(symbol)
914
1106
  symbol = market['symbol']
915
1107
  marketId = market['id']
916
1108
  messageHash = messageHash + ':' + symbol
1109
+ productType = self.safe_string(params, 'productType')
917
1110
  type = None
918
1111
  type, params = self.handle_market_type_and_params('watchOrders', market, params)
919
- if (type == 'spot') and (symbol is None):
920
- raise ArgumentsRequired(self.id + ' watchOrders requires a symbol argument for ' + type + ' markets.')
921
- if isStop and type == 'spot':
922
- raise NotSupported(self.id + ' watchOrders does not support stop orders for ' + type + ' markets.')
1112
+ subType = None
1113
+ subType, params = self.handle_sub_type_and_params('watchOrders', market, params, 'linear')
1114
+ if (type == 'spot' or type == 'margin') and (symbol is None):
1115
+ marketId = 'default'
1116
+ if (productType is None) and (type != 'spot') and (symbol is None):
1117
+ messageHash = messageHash + ':' + subType
1118
+ elif productType == 'USDT-FUTURES':
1119
+ messageHash = messageHash + ':linear'
1120
+ elif productType == 'COIN-FUTURES':
1121
+ messageHash = messageHash + ':inverse'
1122
+ elif productType == 'USDC-FUTURES':
1123
+ messageHash = messageHash + ':usdcfutures' # non unified channel
923
1124
  instType = None
924
- instType, params = self.get_inst_type(market, params)
1125
+ if market is None and type == 'spot':
1126
+ instType = 'SPOT'
1127
+ else:
1128
+ instType, params = self.get_inst_type(market, params)
925
1129
  if type == 'spot':
926
1130
  subscriptionHash = subscriptionHash + ':' + symbol
927
- if isStop:
1131
+ if isTrigger:
928
1132
  subscriptionHash = subscriptionHash + ':stop' # we don't want to re-use the same subscription hash for stop orders
929
- instId = marketId if (type == 'spot') else 'default' # different from other streams here the 'rest' id is required for spot markets, contract markets require default here
930
- channel = 'orders-algo' if isStop else 'orders'
1133
+ instId = marketId if (type == 'spot' or type == 'margin') else 'default' # different from other streams here the 'rest' id is required for spot markets, contract markets require default here
1134
+ channel = 'orders-algo' if isTrigger else 'orders'
931
1135
  marginMode = None
932
1136
  marginMode, params = self.handle_margin_mode_and_params('watchOrders', params)
933
1137
  if marginMode is not None:
934
1138
  instType = 'MARGIN'
1139
+ messageHash = messageHash + ':' + marginMode
935
1140
  if marginMode == 'isolated':
936
1141
  channel = 'orders-isolated'
937
1142
  else:
938
1143
  channel = 'orders-crossed'
939
- args = {
1144
+ subscriptionHash = subscriptionHash + ':' + instType
1145
+ args: dict = {
940
1146
  'instType': instType,
941
1147
  'channel': channel,
942
1148
  'instId': instId,
@@ -946,7 +1152,7 @@ class bitget(ccxt.async_support.bitget):
946
1152
  limit = orders.getLimit(symbol, limit)
947
1153
  return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
948
1154
 
949
- def handle_order(self, client: Client, message, subscription=None):
1155
+ def handle_order(self, client: Client, message):
950
1156
  #
951
1157
  # spot
952
1158
  #
@@ -954,25 +1160,7 @@ class bitget(ccxt.async_support.bitget):
954
1160
  # "action": "snapshot",
955
1161
  # "arg": {"instType": "SPOT", "channel": "orders", "instId": "BTCUSDT"},
956
1162
  # "data": [
957
- # {
958
- # "instId": "BTCUSDT",
959
- # "orderId": "1116512721422422017",
960
- # "clientOid": "798d1425-d31d-4ada-a51b-ec701e00a1d9",
961
- # "price": "35000.00",
962
- # "size": "7.0000",
963
- # "newSize": "500.0000",
964
- # "notional": "7.000000",
965
- # "orderType": "limit",
966
- # "force": "gtc",
967
- # "side": "buy",
968
- # "accBaseVolume": "0.0000",
969
- # "priceAvg": "0.00",
970
- # "status": "live",
971
- # "cTime": "1701923297267",
972
- # "uTime": "1701923297267",
973
- # "feeDetail": [],
974
- # "enterPointSource": "WEB"
975
- # }
1163
+ # # see all examples in parseWsOrder
976
1164
  # ],
977
1165
  # "ts": 1701923297285
978
1166
  # }
@@ -983,105 +1171,26 @@ class bitget(ccxt.async_support.bitget):
983
1171
  # "action": "snapshot",
984
1172
  # "arg": {"instType": "USDT-FUTURES", "channel": "orders", "instId": "default"},
985
1173
  # "data": [
986
- # {
987
- # "accBaseVolume": "0",
988
- # "cTime": "1701920553759",
989
- # "clientOid": "1116501214318198793",
990
- # "enterPointSource": "WEB",
991
- # "feeDetail": [{
992
- # "feeCoin": "USDT",
993
- # "fee": "-0.162003"
994
- # }],
995
- # "force": "gtc",
996
- # "instId": "BTCUSDT",
997
- # "leverage": "20",
998
- # "marginCoin": "USDT",
999
- # "marginMode": "isolated",
1000
- # "notionalUsd": "105",
1001
- # "orderId": "1116501214293032964",
1002
- # "orderType": "limit",
1003
- # "posMode": "hedge_mode",
1004
- # "posSide": "long",
1005
- # "price": "35000",
1006
- # "reduceOnly": "no",
1007
- # "side": "buy",
1008
- # "size": "0.003",
1009
- # "status": "canceled",
1010
- # "tradeSide": "open",
1011
- # "uTime": "1701920595866"
1012
- # }
1174
+ # # see all examples in parseWsOrder
1013
1175
  # ],
1014
1176
  # "ts": 1701920595879
1015
1177
  # }
1016
1178
  #
1017
- # trigger
1018
- #
1019
- # {
1020
- # "action": "snapshot",
1021
- # "arg": {
1022
- # "instType": "USDT-FUTURES",
1023
- # "channel": "orders-algo",
1024
- # "instId": "default"
1025
- # },
1026
- # "data": [
1027
- # {
1028
- # "instId": "BTCUSDT",
1029
- # "orderId": "1116508960750899201",
1030
- # "clientOid": "1116508960750899200",
1031
- # "triggerPrice": "35000.000000000",
1032
- # "triggerType": "mark_price",
1033
- # "triggerTime": "1701922464373",
1034
- # "planType": "pl",
1035
- # "price": "35000.000000000",
1036
- # "size": "0.001000000",
1037
- # "actualSize": "0.000000000",
1038
- # "orderType": "limit",
1039
- # "side": "buy",
1040
- # "tradeSide": "open",
1041
- # "posSide": "long",
1042
- # "marginCoin": "USDT",
1043
- # "status": "cancelled",
1044
- # "posMode": "hedge_mode",
1045
- # "enterPointSource": "api",
1046
- # "stopSurplusTriggerType": "fill_price",
1047
- # "stopLossTriggerType": "fill_price",
1048
- # "cTime": "1701922400653",
1049
- # "uTime": "1701922464373"
1050
- # }
1051
- # ],
1052
- # "ts": 1701922464417
1053
- # }
1054
- #
1055
1179
  # isolated and cross margin
1056
1180
  #
1057
1181
  # {
1058
1182
  # "action": "snapshot",
1059
1183
  # "arg": {"instType": "MARGIN", "channel": "orders-crossed", "instId": "BTCUSDT"},
1060
1184
  # "data": [
1061
- # {
1062
- # "enterPointSource": "web",
1063
- # "force": "gtc",
1064
- # "orderType": "limit",
1065
- # "price": "35000.000000000",
1066
- # "quoteSize": "10.500000000",
1067
- # "side": "buy",
1068
- # "status": "live",
1069
- # "baseSize": "0.000300000",
1070
- # "cTime": "1701923982427",
1071
- # "clientOid": "4902047879864dc980c4840e9906db4e",
1072
- # "fillPrice": "0.000000000",
1073
- # "baseVolume": "0.000000000",
1074
- # "fillTotalAmount": "0.000000000",
1075
- # "loanType": "auto-loan-and-repay",
1076
- # "orderId": "1116515595178356737"
1077
- # }
1185
+ # # see examples in parseWsOrder
1078
1186
  # ],
1079
1187
  # "ts": 1701923982497
1080
1188
  # }
1081
1189
  #
1082
- arg = self.safe_value(message, 'arg', {})
1190
+ arg = self.safe_dict(message, 'arg', {})
1083
1191
  channel = self.safe_string(arg, 'channel')
1084
1192
  instType = self.safe_string(arg, 'instType')
1193
+ argInstId = self.safe_string(arg, 'instId')
1085
1194
  marketType = None
1086
1195
  if instType == 'SPOT':
1087
1196
  marketType = 'spot'
@@ -1089,19 +1198,21 @@ class bitget(ccxt.async_support.bitget):
1089
1198
  marketType = 'spot'
1090
1199
  else:
1091
1200
  marketType = 'contract'
1201
+ isLinearSwap = (instType == 'USDT-FUTURES')
1202
+ isInverseSwap = (instType == 'COIN-FUTURES')
1203
+ isUSDCFutures = (instType == 'USDC-FUTURES')
1092
1204
  data = self.safe_value(message, 'data', [])
1093
1205
  if self.orders is None:
1094
1206
  limit = self.safe_integer(self.options, 'ordersLimit', 1000)
1095
1207
  self.orders = ArrayCacheBySymbolById(limit)
1096
1208
  self.triggerOrders = ArrayCacheBySymbolById(limit)
1097
- stored = self.triggerOrders if (channel == 'ordersAlgo') else self.orders
1098
- messageHash = 'triggerOrder' if (channel == 'ordersAlgo') else 'order'
1099
- marketSymbols = {}
1209
+ isTrigger = (channel == 'orders-algo') or (channel == 'ordersAlgo')
1210
+ stored = self.triggerOrders if isTrigger else self.orders
1211
+ messageHash = 'triggerOrder' if isTrigger else 'order'
1212
+ marketSymbols: dict = {}
1100
1213
  for i in range(0, len(data)):
1101
1214
  order = data[i]
1102
- if 'tradeId' in order:
1103
- self.handle_my_trades(client, order)
1104
- marketId = self.safe_string(order, 'instId')
1215
+ marketId = self.safe_string(order, 'instId', argInstId)
1105
1216
  market = self.safe_market(marketId, None, None, marketType)
1106
1217
  parsed = self.parse_ws_order(order, market)
1107
1218
  stored.append(parsed)
@@ -1111,110 +1222,139 @@ class bitget(ccxt.async_support.bitget):
1111
1222
  for i in range(0, len(keys)):
1112
1223
  symbol = keys[i]
1113
1224
  innerMessageHash = messageHash + ':' + symbol
1225
+ if channel == 'orders-crossed':
1226
+ innerMessageHash = innerMessageHash + ':cross'
1227
+ elif channel == 'orders-isolated':
1228
+ innerMessageHash = innerMessageHash + ':isolated'
1114
1229
  client.resolve(stored, innerMessageHash)
1115
1230
  client.resolve(stored, messageHash)
1231
+ if isLinearSwap:
1232
+ client.resolve(stored, 'order:linear')
1233
+ if isInverseSwap:
1234
+ client.resolve(stored, 'order:inverse')
1235
+ if isUSDCFutures:
1236
+ client.resolve(stored, 'order:usdcfutures')
1116
1237
 
1117
1238
  def parse_ws_order(self, order, market=None):
1118
1239
  #
1119
1240
  # spot
1120
1241
  #
1121
- # {
1122
- # "instId": "BTCUSDT",
1123
- # "orderId": "1116512721422422017",
1124
- # "clientOid": "798d1425-d31d-4ada-a51b-ec701e00a1d9",
1125
- # "price": "35000.00",
1126
- # "size": "7.0000",
1127
- # "newSize": "500.0000",
1128
- # "notional": "7.000000",
1129
- # "orderType": "limit",
1130
- # "force": "gtc",
1131
- # "side": "buy",
1132
- # "accBaseVolume": "0.0000",
1133
- # "priceAvg": "0.00",
1134
- # "status": "live",
1135
- # "cTime": "1701923297267",
1136
- # "uTime": "1701923297267",
1137
- # "feeDetail": [],
1138
- # "enterPointSource": "WEB"
1139
- # }
1242
+ # {
1243
+ # instId: 'EOSUSDT',
1244
+ # orderId: '1171779081105780739',
1245
+ # price: '0.81075', # limit price, field not present for market orders
1246
+ # clientOid: 'a2330139-1d04-4d78-98be-07de3cfd1055',
1247
+ # notional: '5.675250', # self is not cost! but notional
1248
+ # newSize: '7.0000', # self is not cost! quanity(for limit order or market sell) or cost(for market buy order)
1249
+ # size: '5.6752', # self is not cost, neither quanity, but notional! self field for "spot" can be ignored at all
1250
+ # # Note: for limit order(even filled) we don't have cost value in response, only in market order
1251
+ # orderType: 'limit', # limit, market
1252
+ # force: 'gtc',
1253
+ # side: 'buy',
1254
+ # accBaseVolume: '0.0000', # in case of 'filled', self would be set(for limit orders, self is the only indicator of the amount filled)
1255
+ # priceAvg: '0.00000', # in case of 'filled', self would be set
1256
+ # status: 'live', # live, filled, partially_filled
1257
+ # cTime: '1715099824215',
1258
+ # uTime: '1715099824215',
1259
+ # feeDetail: [],
1260
+ # enterPointSource: 'API'
1261
+ # #### trigger order has these additional fields: ####
1262
+ # "triggerPrice": "35100",
1263
+ # "price": "35100", # self is same price
1264
+ # "executePrice": "35123", # self is limit price
1265
+ # "triggerType": "fill_price",
1266
+ # "planType": "amount",
1267
+ # #### in case order had a partial fill: ####
1268
+ # fillPrice: '35123',
1269
+ # tradeId: '1171775539946528779',
1270
+ # baseVolume: '7', # field present in market order
1271
+ # fillTime: '1715098979937',
1272
+ # fillFee: '-0.0069987',
1273
+ # fillFeeCoin: 'BTC',
1274
+ # tradeScope: 'T',
1275
+ # }
1140
1276
  #
1141
1277
  # contract
1142
1278
  #
1143
1279
  # {
1144
- # "accBaseVolume": "0",
1145
- # "cTime": "1701920553759",
1146
- # "clientOid": "1116501214318198793",
1147
- # "enterPointSource": "WEB",
1148
- # "feeDetail": [{
1280
+ # accBaseVolume: '0', # total amount filled during lifetime for order
1281
+ # cTime: '1715065875539',
1282
+ # clientOid: '1171636690041344003',
1283
+ # enterPointSource: 'API',
1284
+ # feeDetail: [{
1149
1285
  # "feeCoin": "USDT",
1150
1286
  # "fee": "-0.162003"
1151
1287
  # }],
1152
- # "force": "gtc",
1153
- # "instId": "BTCUSDT",
1154
- # "leverage": "20",
1155
- # "marginCoin": "USDT",
1156
- # "marginMode": "isolated",
1157
- # "notionalUsd": "105",
1158
- # "orderId": "1116501214293032964",
1159
- # "orderType": "limit",
1160
- # "posMode": "hedge_mode",
1161
- # "posSide": "long",
1162
- # "price": "35000",
1163
- # "reduceOnly": "no",
1164
- # "side": "buy",
1165
- # "size": "0.003",
1166
- # "status": "canceled",
1167
- # "tradeSide": "open",
1168
- # "uTime": "1701920595866"
1169
- # }
1170
- #
1171
- # trigger
1172
- #
1173
- # {
1174
- # "instId": "BTCUSDT",
1175
- # "orderId": "1116508960750899201",
1176
- # "clientOid": "1116508960750899200",
1177
- # "triggerPrice": "35000.000000000",
1288
+ # force: 'gtc',
1289
+ # instId: 'SEOSSUSDT',
1290
+ # leverage: '10',
1291
+ # marginCoin: 'USDT',
1292
+ # marginMode: 'crossed',
1293
+ # notionalUsd: '10.4468',
1294
+ # orderId: '1171636690028761089',
1295
+ # orderType: 'market',
1296
+ # posMode: 'hedge_mode', # one_way_mode, hedge_mode
1297
+ # posSide: 'short', # short, long, net
1298
+ # price: '0', # zero for market order
1299
+ # reduceOnly: 'no',
1300
+ # side: 'sell',
1301
+ # size: '13', # self is contracts amount
1302
+ # status: 'live', # live, filled, cancelled
1303
+ # tradeSide: 'open',
1304
+ # uTime: '1715065875539'
1305
+ # #### when filled order is incoming, these additional fields are present too: ###
1306
+ # baseVolume: '9', # amount filled for the incoming update/trade
1307
+ # accBaseVolume: '13', # i.e. 9 has been filled from 13 amount(self value is same as 'size')
1308
+ # fillFee: '-0.0062712',
1309
+ # fillFeeCoin: 'SUSDT',
1310
+ # fillNotionalUsd: '10.452',
1311
+ # fillPrice: '0.804',
1312
+ # fillTime: '1715065875605',
1313
+ # pnl: '0',
1314
+ # priceAvg: '0.804',
1315
+ # tradeId: '1171636690314407937',
1316
+ # tradeScope: 'T',
1317
+ # #### trigger order has these additional fields:
1318
+ # "triggerPrice": "0.800000000",
1319
+ # "price": "0.800000000", # <-- self is same price, actual limit-price is not present in initial response
1178
1320
  # "triggerType": "mark_price",
1179
- # "triggerTime": "1701922464373",
1321
+ # "triggerTime": "1715082796679",
1180
1322
  # "planType": "pl",
1181
- # "price": "35000.000000000",
1182
- # "size": "0.001000000",
1183
1323
  # "actualSize": "0.000000000",
1184
- # "orderType": "limit",
1185
- # "side": "buy",
1186
- # "tradeSide": "open",
1187
- # "posSide": "long",
1188
- # "marginCoin": "USDT",
1189
- # "status": "cancelled",
1190
- # "posMode": "hedge_mode",
1191
- # "enterPointSource": "api",
1192
1324
  # "stopSurplusTriggerType": "fill_price",
1193
1325
  # "stopLossTriggerType": "fill_price",
1194
- # "cTime": "1701922400653",
1195
- # "uTime": "1701922464373"
1196
1326
  # }
1197
1327
  #
1198
1328
  # isolated and cross margin
1199
1329
  #
1200
1330
  # {
1201
- # "enterPointSource": "web",
1202
- # "force": "gtc",
1203
- # "orderType": "limit",
1204
- # "price": "35000.000000000",
1205
- # "quoteSize": "10.500000000",
1206
- # "side": "buy",
1207
- # "status": "live",
1208
- # "baseSize": "0.000300000",
1209
- # "cTime": "1701923982427",
1210
- # "clientOid": "4902047879864dc980c4840e9906db4e",
1211
- # "fillPrice": "0.000000000",
1212
- # "baseVolume": "0.000000000",
1213
- # "fillTotalAmount": "0.000000000",
1214
- # "loanType": "auto-loan-and-repay",
1215
- # "orderId": "1116515595178356737"
1216
- # }
1331
+ # enterPointSource: "web",
1332
+ # feeDetail: [
1333
+ # {
1334
+ # feeCoin: "AAVE",
1335
+ # deduction: "no",
1336
+ # totalDeductionFee: "0",
1337
+ # totalFee: "-0.00010740",
1338
+ # },
1339
+ # ],
1340
+ # force: "gtc",
1341
+ # orderType: "limit",
1342
+ # price: "93.170000000",
1343
+ # fillPrice: "93.170000000",
1344
+ # baseSize: "0.110600000", # total amount of order
1345
+ # quoteSize: "10.304602000", # total cost of order(independently if order is filled or pending)
1346
+ # baseVolume: "0.107400000", # filled amount of order(during order's lifecycle, and not for self specific incoming update)
1347
+ # fillTotalAmount: "10.006458000", # filled cost of order(during order's lifecycle, and not for self specific incoming update)
1348
+ # side: "buy",
1349
+ # status: "partially_filled",
1350
+ # cTime: "1717875017306",
1351
+ # clientOid: "b57afe789a06454e9c560a2aab7f7201",
1352
+ # loanType: "auto-loan",
1353
+ # orderId: "1183419084588060673",
1354
+ # }
1217
1355
  #
1356
+ isSpot = not ('posMode' in order)
1357
+ isMargin = ('loanType' in order)
1218
1358
  marketId = self.safe_string(order, 'instId')
1219
1359
  market = self.safe_market(marketId, market)
1220
1360
  timestamp = self.safe_integer(order, 'cTime')
@@ -1231,22 +1371,52 @@ class bitget(ccxt.async_support.bitget):
1231
1371
  'currency': self.safe_currency_code(feeCurrency),
1232
1372
  }
1233
1373
  triggerPrice = self.safe_number(order, 'triggerPrice')
1234
- price = self.safe_string(order, 'price')
1374
+ isTriggerOrder = (triggerPrice is not None)
1375
+ price = None
1376
+ if not isTriggerOrder:
1377
+ price = self.safe_number(order, 'price')
1378
+ elif isSpot and isTriggerOrder:
1379
+ # for spot trigger order, limit price is self
1380
+ price = self.safe_number(order, 'executePrice')
1235
1381
  avgPrice = self.omit_zero(self.safe_string_2(order, 'priceAvg', 'fillPrice'))
1236
- cost = self.safe_string_n(order, ['notional', 'notionalUsd', 'quoteSize'])
1237
1382
  side = self.safe_string(order, 'side')
1238
1383
  type = self.safe_string(order, 'orderType')
1239
- if side == 'buy' and market['spot'] and (type == 'market'):
1240
- cost = self.safe_string(order, 'newSize', cost)
1241
- filled = self.safe_string_2(order, 'accBaseVolume', 'baseVolume')
1242
- # if market['spot'] and (rawStatus != 'live'):
1243
- # filled = Precise.string_div(cost, avgPrice)
1244
- # }
1245
- amount = self.safe_string(order, 'baseVolume')
1246
- if not market['spot'] or not (side == 'buy' and type == 'market'):
1247
- amount = self.safe_string(order, 'newSize', amount)
1248
- if market['swap'] and (amount is None):
1249
- amount = self.safe_string(order, 'size')
1384
+ accBaseVolume = self.omit_zero(self.safe_string(order, 'accBaseVolume'))
1385
+ newSizeValue = self.omit_zero(self.safe_string(order, 'newSize'))
1386
+ isMarketOrder = (type == 'market')
1387
+ isBuy = (side == 'buy')
1388
+ totalAmount = None
1389
+ filledAmount = None
1390
+ cost = None
1391
+ remaining = None
1392
+ totalFilled = self.safe_string(order, 'accBaseVolume')
1393
+ if isSpot:
1394
+ if isMargin:
1395
+ totalAmount = self.safe_string(order, 'baseSize')
1396
+ totalFilled = self.safe_string(order, 'baseVolume')
1397
+ cost = self.safe_string(order, 'fillTotalAmount')
1398
+ else:
1399
+ partialFillAmount = self.safe_string(order, 'baseVolume')
1400
+ if partialFillAmount is not None:
1401
+ filledAmount = partialFillAmount
1402
+ else:
1403
+ filledAmount = totalFilled
1404
+ if isMarketOrder:
1405
+ if isBuy:
1406
+ totalAmount = accBaseVolume
1407
+ cost = newSizeValue
1408
+ else:
1409
+ totalAmount = newSizeValue
1410
+ # we don't have cost for market-sell order
1411
+ else:
1412
+ totalAmount = self.safe_string(order, 'newSize')
1413
+ # we don't have cost for limit order
1414
+ else:
1415
+ # baseVolume should not be used for "amount" for contracts !
1416
+ filledAmount = self.safe_string(order, 'baseVolume')
1417
+ totalAmount = self.safe_string(order, 'size')
1418
+ cost = self.safe_string(order, 'fillNotionalUsd')
1419
+ remaining = Precise.string_sub(totalAmount, totalFilled)
1250
1420
  return self.safe_order({
1251
1421
  'info': order,
1252
1422
  'symbol': symbol,
@@ -1260,20 +1430,19 @@ class bitget(ccxt.async_support.bitget):
1260
1430
  'postOnly': None,
1261
1431
  'side': side,
1262
1432
  'price': price,
1263
- 'stopPrice': triggerPrice,
1264
1433
  'triggerPrice': triggerPrice,
1265
- 'amount': amount,
1434
+ 'amount': totalAmount,
1266
1435
  'cost': cost,
1267
1436
  'average': avgPrice,
1268
- 'filled': filled,
1269
- 'remaining': None,
1437
+ 'filled': filledAmount,
1438
+ 'remaining': remaining,
1270
1439
  'status': self.parse_ws_order_status(rawStatus),
1271
1440
  'fee': feeObject,
1272
1441
  'trades': None,
1273
1442
  }, market)
1274
1443
 
1275
1444
  def parse_ws_order_status(self, status):
1276
- statuses = {
1445
+ statuses: dict = {
1277
1446
  'live': 'open',
1278
1447
  'partially_filled': 'open',
1279
1448
  'filled': 'closed',
@@ -1285,15 +1454,15 @@ class bitget(ccxt.async_support.bitget):
1285
1454
  async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
1286
1455
  """
1287
1456
  watches trades made by the user
1288
- :see: https://www.bitget.com/api-doc/contract/websocket/private/Order-Channel
1457
+
1458
+ https://www.bitget.com/api-doc/contract/websocket/private/Order-Channel
1459
+
1289
1460
  :param str symbol: unified market symbol
1290
1461
  :param int [since]: the earliest time in ms to fetch trades for
1291
1462
  :param int [limit]: the maximum number of trades structures to retrieve
1292
1463
  :param dict [params]: extra parameters specific to the exchange API endpoint
1293
1464
  :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1294
1465
  """
1295
- # only contracts stream provides the trade info consistently in between order updates
1296
- # the spot stream only provides on limit orders updates so we can't support it for spot
1297
1466
  await self.load_markets()
1298
1467
  market = None
1299
1468
  messageHash = 'myTrades'
@@ -1303,14 +1472,15 @@ class bitget(ccxt.async_support.bitget):
1303
1472
  messageHash = messageHash + ':' + symbol
1304
1473
  type = None
1305
1474
  type, params = self.handle_market_type_and_params('watchMyTrades', market, params)
1306
- if type == 'spot':
1307
- raise NotSupported(self.id + ' watchMyTrades is not supported for ' + type + ' markets.')
1308
1475
  instType = None
1309
- instType, params = self.get_inst_type(market, params)
1310
- subscriptionHash = 'order:trades'
1311
- args = {
1476
+ if market is None and type == 'spot':
1477
+ instType = 'SPOT'
1478
+ else:
1479
+ instType, params = self.get_inst_type(market, params)
1480
+ subscriptionHash = 'fill:' + instType
1481
+ args: dict = {
1312
1482
  'instType': instType,
1313
- 'channel': 'orders',
1483
+ 'channel': 'fill',
1314
1484
  'instId': 'default',
1315
1485
  }
1316
1486
  trades = await self.watch_private(messageHash, subscriptionHash, args, params)
@@ -1320,55 +1490,101 @@ class bitget(ccxt.async_support.bitget):
1320
1490
 
1321
1491
  def handle_my_trades(self, client: Client, message):
1322
1492
  #
1323
- # order and trade mixin(contract)
1324
- #
1493
+ # spot
1494
+ # {
1495
+ # "action": "snapshot",
1496
+ # "arg": {
1497
+ # "instType": "SPOT",
1498
+ # "channel": "fill",
1499
+ # "instId": "default"
1500
+ # },
1501
+ # "data": [
1502
+ # {
1503
+ # "orderId": "1169142457356959747",
1504
+ # "tradeId": "1169142457636958209",
1505
+ # "symbol": "LTCUSDT",
1506
+ # "orderType": "market",
1507
+ # "side": "buy",
1508
+ # "priceAvg": "81.069",
1509
+ # "size": "0.074",
1510
+ # "amount": "5.999106",
1511
+ # "tradeScope": "taker",
1512
+ # "feeDetail": [
1513
+ # {
1514
+ # "feeCoin": "LTC",
1515
+ # "deduction": "no",
1516
+ # "totalDeductionFee": "0",
1517
+ # "totalFee": "0.000074"
1518
+ # }
1519
+ # ],
1520
+ # "cTime": "1714471204194",
1521
+ # "uTime": "1714471204194"
1522
+ # }
1523
+ # ],
1524
+ # "ts": 1714471204270
1525
+ # }
1526
+ # swap
1325
1527
  # {
1326
- # "accBaseVolume": "0",
1327
- # "cTime": "1701920553759",
1328
- # "clientOid": "1116501214318198793",
1329
- # "enterPointSource": "WEB",
1330
- # "feeDetail": [{
1331
- # "feeCoin": "USDT",
1332
- # "fee": "-0.162003"
1333
- # }],
1334
- # "force": "gtc",
1335
- # "instId": "BTCUSDT",
1336
- # "leverage": "20",
1337
- # "marginCoin": "USDT",
1338
- # "marginMode": "isolated",
1339
- # "notionalUsd": "105",
1340
- # "orderId": "1116501214293032964",
1341
- # "orderType": "limit",
1342
- # "posMode": "hedge_mode",
1343
- # "posSide": "long",
1344
- # "price": "35000",
1345
- # "reduceOnly": "no",
1346
- # "side": "buy",
1347
- # "size": "0.003",
1348
- # "status": "canceled",
1349
- # "tradeSide": "open",
1350
- # "uTime": "1701920595866"
1528
+ # "action": "snapshot",
1529
+ # "arg": {
1530
+ # "instType": "USDT-FUTURES",
1531
+ # "channel": "fill",
1532
+ # "instId": "default"
1533
+ # },
1534
+ # "data": [
1535
+ # {
1536
+ # "orderId": "1169142761031114781",
1537
+ # "tradeId": "1169142761312637004",
1538
+ # "symbol": "LTCUSDT",
1539
+ # "orderType": "market",
1540
+ # "side": "buy",
1541
+ # "price": "80.87",
1542
+ # "baseVolume": "0.1",
1543
+ # "quoteVolume": "8.087",
1544
+ # "profit": "0",
1545
+ # "tradeSide": "open",
1546
+ # "posMode": "hedge_mode",
1547
+ # "tradeScope": "taker",
1548
+ # "feeDetail": [
1549
+ # {
1550
+ # "feeCoin": "USDT",
1551
+ # "deduction": "no",
1552
+ # "totalDeductionFee": "0",
1553
+ # "totalFee": "-0.0048522"
1554
+ # }
1555
+ # ],
1556
+ # "cTime": "1714471276596",
1557
+ # "uTime": "1714471276596"
1558
+ # }
1559
+ # ],
1560
+ # "ts": 1714471276629
1351
1561
  # }
1352
1562
  #
1353
1563
  if self.myTrades is None:
1354
1564
  limit = self.safe_integer(self.options, 'tradesLimit', 1000)
1355
1565
  self.myTrades = ArrayCache(limit)
1356
1566
  stored = self.myTrades
1357
- parsed = self.parse_ws_trade(message)
1358
- stored.append(parsed)
1359
- symbol = parsed['symbol']
1567
+ data = self.safe_list(message, 'data', [])
1568
+ length = len(data)
1360
1569
  messageHash = 'myTrades'
1570
+ for i in range(0, length):
1571
+ trade = data[i]
1572
+ parsed = self.parse_ws_trade(trade)
1573
+ stored.append(parsed)
1574
+ symbol = parsed['symbol']
1575
+ symbolSpecificMessageHash = 'myTrades:' + symbol
1576
+ client.resolve(stored, symbolSpecificMessageHash)
1361
1577
  client.resolve(stored, messageHash)
1362
- symbolSpecificMessageHash = 'myTrades:' + symbol
1363
- client.resolve(stored, symbolSpecificMessageHash)
1364
1578
 
1365
1579
  async def watch_balance(self, params={}) -> Balances:
1366
1580
  """
1367
1581
  watch balance and get the amount of funds available for trading or funds locked in orders
1368
- :see: https://www.bitget.com/api-doc/spot/websocket/private/Account-Channel
1369
- :see: https://www.bitget.com/api-doc/contract/websocket/private/Account-Channel
1370
- :see: https://www.bitget.com/api-doc/margin/cross/websocket/private/Margin-Cross-Account-Assets
1371
- :see: https://www.bitget.com/api-doc/margin/isolated/websocket/private/Margin-isolated-account-assets
1582
+
1583
+ https://www.bitget.com/api-doc/spot/websocket/private/Account-Channel
1584
+ https://www.bitget.com/api-doc/contract/websocket/private/Account-Channel
1585
+ https://www.bitget.com/api-doc/margin/cross/websocket/private/Margin-Cross-Account-Assets
1586
+ https://www.bitget.com/api-doc/margin/isolated/websocket/private/Margin-isolated-account-assets
1587
+
1372
1588
  :param dict [params]: extra parameters specific to the exchange API endpoint
1373
1589
  :param str [params.type]: spot or contract if not provided self.options['defaultType'] is used
1374
1590
  :param str [params.instType]: one of 'SPOT', 'MARGIN', 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES'
@@ -1392,7 +1608,7 @@ class bitget(ccxt.async_support.bitget):
1392
1608
  else:
1393
1609
  instType = 'SPOT'
1394
1610
  instType, params = self.handle_option_and_params(params, 'watchBalance', 'instType', instType)
1395
- args = {
1611
+ args: dict = {
1396
1612
  'instType': instType,
1397
1613
  'channel': channel,
1398
1614
  'coin': 'default',
@@ -1482,16 +1698,25 @@ class bitget(ccxt.async_support.bitget):
1482
1698
 
1483
1699
  async def watch_public(self, messageHash, args, params={}):
1484
1700
  url = self.urls['api']['ws']['public']
1485
- request = {
1701
+ request: dict = {
1486
1702
  'op': 'subscribe',
1487
1703
  'args': [args],
1488
1704
  }
1489
1705
  message = self.extend(request, params)
1490
1706
  return await self.watch(url, messageHash, message, messageHash)
1491
1707
 
1708
+ async def un_watch_public(self, messageHash, args, params={}):
1709
+ url = self.urls['api']['ws']['public']
1710
+ request: dict = {
1711
+ 'op': 'unsubscribe',
1712
+ 'args': [args],
1713
+ }
1714
+ message = self.extend(request, params)
1715
+ return await self.watch(url, messageHash, message, messageHash)
1716
+
1492
1717
  async def watch_public_multiple(self, messageHashes, argsArray, params={}):
1493
1718
  url = self.urls['api']['ws']['public']
1494
- request = {
1719
+ request: dict = {
1495
1720
  'op': 'subscribe',
1496
1721
  'args': argsArray,
1497
1722
  }
@@ -1510,7 +1735,7 @@ class bitget(ccxt.async_support.bitget):
1510
1735
  auth = timestamp + 'GET' + '/user/verify'
1511
1736
  signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256, 'base64')
1512
1737
  operation = 'login'
1513
- request = {
1738
+ request: dict = {
1514
1739
  'op': operation,
1515
1740
  'args': [
1516
1741
  {
@@ -1523,12 +1748,12 @@ class bitget(ccxt.async_support.bitget):
1523
1748
  }
1524
1749
  message = self.extend(request, params)
1525
1750
  self.watch(url, messageHash, message, messageHash)
1526
- return future
1751
+ return await future
1527
1752
 
1528
1753
  async def watch_private(self, messageHash, subscriptionHash, args, params={}):
1529
1754
  await self.authenticate()
1530
1755
  url = self.urls['api']['ws']['private']
1531
- request = {
1756
+ request: dict = {
1532
1757
  'op': 'subscribe',
1533
1758
  'args': [args],
1534
1759
  }
@@ -1602,6 +1827,17 @@ class bitget(ccxt.async_support.bitget):
1602
1827
  # "event": "subscribe",
1603
1828
  # "arg": {instType: 'SPOT', channel: "account", instId: "default"}
1604
1829
  # }
1830
+ # unsubscribe
1831
+ # {
1832
+ # "op":"unsubscribe",
1833
+ # "args":[
1834
+ # {
1835
+ # "instType":"USDT-FUTURES",
1836
+ # "channel":"ticker",
1837
+ # "instId":"BTCUSDT"
1838
+ # }
1839
+ # ]
1840
+ # }
1605
1841
  #
1606
1842
  if self.handle_error_message(client, message):
1607
1843
  return
@@ -1619,13 +1855,22 @@ class bitget(ccxt.async_support.bitget):
1619
1855
  if event == 'subscribe':
1620
1856
  self.handle_subscription_status(client, message)
1621
1857
  return
1622
- methods = {
1858
+ if event == 'unsubscribe':
1859
+ self.handle_un_subscription_status(client, message)
1860
+ return
1861
+ methods: dict = {
1623
1862
  'ticker': self.handle_ticker,
1624
1863
  'trade': self.handle_trades,
1864
+ 'fill': self.handle_my_trades,
1625
1865
  'orders': self.handle_order,
1626
1866
  'ordersAlgo': self.handle_order,
1867
+ 'orders-algo': self.handle_order,
1868
+ 'orders-crossed': self.handle_order,
1869
+ 'orders-isolated': self.handle_order,
1627
1870
  'account': self.handle_balance,
1628
1871
  'positions': self.handle_positions,
1872
+ 'account-isolated': self.handle_balance,
1873
+ 'account-crossed': self.handle_balance,
1629
1874
  }
1630
1875
  arg = self.safe_value(message, 'arg', {})
1631
1876
  topic = self.safe_value(arg, 'channel', '')
@@ -1637,7 +1882,7 @@ class bitget(ccxt.async_support.bitget):
1637
1882
  if topic.find('books') >= 0:
1638
1883
  self.handle_order_book(client, message)
1639
1884
 
1640
- def ping(self, client):
1885
+ def ping(self, client: Client):
1641
1886
  return 'ping'
1642
1887
 
1643
1888
  def handle_pong(self, client: Client, message):
@@ -1652,3 +1897,127 @@ class bitget(ccxt.async_support.bitget):
1652
1897
  # }
1653
1898
  #
1654
1899
  return message
1900
+
1901
+ def handle_order_book_un_subscription(self, client: Client, message):
1902
+ #
1903
+ # {"event":"unsubscribe","arg":{"instType":"SPOT","channel":"books","instId":"BTCUSDT"}}
1904
+ #
1905
+ arg = self.safe_dict(message, 'arg', {})
1906
+ instType = self.safe_string_lower(arg, 'instType')
1907
+ type = 'spot' if (instType == 'spot') else 'contract'
1908
+ instId = self.safe_string(arg, 'instId')
1909
+ market = self.safe_market(instId, None, None, type)
1910
+ symbol = market['symbol']
1911
+ messageHash = 'unsubscribe:orderbook:' + market['symbol']
1912
+ subMessageHash = 'orderbook:' + symbol
1913
+ if symbol in self.orderbooks:
1914
+ del self.orderbooks[symbol]
1915
+ if subMessageHash in client.subscriptions:
1916
+ del client.subscriptions[subMessageHash]
1917
+ if messageHash in client.subscriptions:
1918
+ del client.subscriptions[messageHash]
1919
+ error = UnsubscribeError(self.id + 'orderbook ' + symbol)
1920
+ client.reject(error, subMessageHash)
1921
+ client.resolve(True, messageHash)
1922
+
1923
+ def handle_trades_un_subscription(self, client: Client, message):
1924
+ #
1925
+ # {"event":"unsubscribe","arg":{"instType":"SPOT","channel":"trade","instId":"BTCUSDT"}}
1926
+ #
1927
+ arg = self.safe_dict(message, 'arg', {})
1928
+ instType = self.safe_string_lower(arg, 'instType')
1929
+ type = 'spot' if (instType == 'spot') else 'contract'
1930
+ instId = self.safe_string(arg, 'instId')
1931
+ market = self.safe_market(instId, None, None, type)
1932
+ symbol = market['symbol']
1933
+ messageHash = 'unsubscribe:trade:' + market['symbol']
1934
+ subMessageHash = 'trade:' + symbol
1935
+ if symbol in self.trades:
1936
+ del self.trades[symbol]
1937
+ if subMessageHash in client.subscriptions:
1938
+ del client.subscriptions[subMessageHash]
1939
+ if messageHash in client.subscriptions:
1940
+ del client.subscriptions[messageHash]
1941
+ error = UnsubscribeError(self.id + 'trades ' + symbol)
1942
+ client.reject(error, subMessageHash)
1943
+ client.resolve(True, messageHash)
1944
+
1945
+ def handle_ticker_un_subscription(self, client: Client, message):
1946
+ #
1947
+ # {"event":"unsubscribe","arg":{"instType":"SPOT","channel":"trade","instId":"BTCUSDT"}}
1948
+ #
1949
+ arg = self.safe_dict(message, 'arg', {})
1950
+ instType = self.safe_string_lower(arg, 'instType')
1951
+ type = 'spot' if (instType == 'spot') else 'contract'
1952
+ instId = self.safe_string(arg, 'instId')
1953
+ market = self.safe_market(instId, None, None, type)
1954
+ symbol = market['symbol']
1955
+ messageHash = 'unsubscribe:ticker:' + market['symbol']
1956
+ subMessageHash = 'ticker:' + symbol
1957
+ if symbol in self.tickers:
1958
+ del self.tickers[symbol]
1959
+ if subMessageHash in client.subscriptions:
1960
+ del client.subscriptions[subMessageHash]
1961
+ if messageHash in client.subscriptions:
1962
+ del client.subscriptions[messageHash]
1963
+ error = UnsubscribeError(self.id + 'ticker ' + symbol)
1964
+ client.reject(error, subMessageHash)
1965
+ client.resolve(True, messageHash)
1966
+
1967
+ def handle_ohlcv_un_subscription(self, client: Client, message):
1968
+ #
1969
+ # {"event":"unsubscribe","arg":{"instType":"SPOT","channel":"candle1m","instId":"BTCUSDT"}}
1970
+ #
1971
+ arg = self.safe_dict(message, 'arg', {})
1972
+ instType = self.safe_string_lower(arg, 'instType')
1973
+ type = 'spot' if (instType == 'spot') else 'contract'
1974
+ instId = self.safe_string(arg, 'instId')
1975
+ channel = self.safe_string(arg, 'channel')
1976
+ interval = channel.replace('candle', '')
1977
+ timeframes = self.safe_value(self.options, 'timeframes')
1978
+ timeframe = self.find_timeframe(interval, timeframes)
1979
+ market = self.safe_market(instId, None, None, type)
1980
+ symbol = market['symbol']
1981
+ messageHash = 'unsubscribe:candles:' + timeframe + ':' + market['symbol']
1982
+ subMessageHash = 'candles:' + timeframe + ':' + symbol
1983
+ if symbol in self.ohlcvs:
1984
+ if timeframe in self.ohlcvs[symbol]:
1985
+ del self.ohlcvs[symbol][timeframe]
1986
+ self.clean_unsubscription(client, subMessageHash, messageHash)
1987
+
1988
+ def handle_un_subscription_status(self, client: Client, message):
1989
+ #
1990
+ # {
1991
+ # "op":"unsubscribe",
1992
+ # "args":[
1993
+ # {
1994
+ # "instType":"USDT-FUTURES",
1995
+ # "channel":"ticker",
1996
+ # "instId":"BTCUSDT"
1997
+ # },
1998
+ # {
1999
+ # "instType":"USDT-FUTURES",
2000
+ # "channel":"candle1m",
2001
+ # "instId":"BTCUSDT"
2002
+ # }
2003
+ # ]
2004
+ # }
2005
+ # or
2006
+ # {"event":"unsubscribe","arg":{"instType":"SPOT","channel":"books","instId":"BTCUSDT"}}
2007
+ #
2008
+ argsList = self.safe_list(message, 'args')
2009
+ if argsList is None:
2010
+ argsList = [self.safe_dict(message, 'arg', {})]
2011
+ for i in range(0, len(argsList)):
2012
+ arg = argsList[i]
2013
+ channel = self.safe_string(arg, 'channel')
2014
+ if channel == 'books':
2015
+ # for now only unWatchOrderBook is supporteod
2016
+ self.handle_order_book_un_subscription(client, message)
2017
+ elif channel == 'trade':
2018
+ self.handle_trades_un_subscription(client, message)
2019
+ elif channel == 'ticker':
2020
+ self.handle_ticker_un_subscription(client, message)
2021
+ elif channel.startswith('candle'):
2022
+ self.handle_ohlcv_un_subscription(client, message)
2023
+ return message