ccxt 4.2.77__py2.py3-none-any.whl → 4.4.49__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 +3205 -937
  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 +1525 -573
  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 +223 -97
  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 +639 -323
  126. ccxt/async_support/digifinex.py +465 -233
  127. ccxt/async_support/ellipx.py +1887 -0
  128. ccxt/async_support/exmo.py +317 -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 +433 -178
  133. ccxt/async_support/hollaex.py +207 -83
  134. ccxt/async_support/htx.py +1095 -563
  135. ccxt/async_support/huobijp.py +178 -56
  136. ccxt/async_support/hyperliquid.py +1678 -292
  137. ccxt/async_support/idex.py +219 -95
  138. ccxt/async_support/independentreserve.py +300 -31
  139. ccxt/async_support/indodax.py +226 -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 +198 -107
  145. ccxt/async_support/latoken.py +199 -79
  146. ccxt/async_support/lbank.py +360 -113
  147. ccxt/async_support/luno.py +185 -62
  148. ccxt/async_support/lykke.py +168 -55
  149. ccxt/async_support/mercado.py +101 -29
  150. ccxt/async_support/mexc.py +995 -429
  151. ccxt/async_support/myokx.py +53 -0
  152. ccxt/async_support/ndax.py +234 -82
  153. ccxt/async_support/novadax.py +195 -75
  154. ccxt/async_support/oceanex.py +244 -59
  155. ccxt/async_support/okcoin.py +301 -165
  156. ccxt/async_support/okx.py +1776 -454
  157. ccxt/async_support/onetrading.py +198 -414
  158. ccxt/async_support/oxfun.py +2898 -0
  159. ccxt/async_support/p2b.py +142 -52
  160. ccxt/async_support/paradex.py +2085 -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 +3205 -937
  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 +1525 -573
  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 +223 -97
  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 +639 -323
  234. ccxt/digifinex.py +465 -233
  235. ccxt/ellipx.py +1887 -0
  236. ccxt/exmo.py +317 -128
  237. ccxt/gate.py +1472 -463
  238. ccxt/gemini.py +206 -84
  239. ccxt/hashkey.py +4164 -0
  240. ccxt/hitbtc.py +433 -178
  241. ccxt/hollaex.py +207 -83
  242. ccxt/htx.py +1095 -563
  243. ccxt/huobijp.py +178 -56
  244. ccxt/hyperliquid.py +1677 -292
  245. ccxt/idex.py +219 -95
  246. ccxt/independentreserve.py +299 -31
  247. ccxt/indodax.py +226 -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 +198 -107
  253. ccxt/latoken.py +199 -79
  254. ccxt/lbank.py +360 -113
  255. ccxt/luno.py +185 -62
  256. ccxt/lykke.py +168 -55
  257. ccxt/mercado.py +101 -29
  258. ccxt/mexc.py +994 -429
  259. ccxt/myokx.py +53 -0
  260. ccxt/ndax.py +234 -82
  261. ccxt/novadax.py +195 -75
  262. ccxt/oceanex.py +244 -59
  263. ccxt/okcoin.py +301 -165
  264. ccxt/okx.py +1776 -454
  265. ccxt/onetrading.py +198 -414
  266. ccxt/oxfun.py +2897 -0
  267. ccxt/p2b.py +142 -52
  268. ccxt/paradex.py +2085 -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 +143 -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.49.dist-info/LICENSE.txt +21 -0
  496. ccxt-4.4.49.dist-info/METADATA +646 -0
  497. ccxt-4.4.49.dist-info/RECORD +669 -0
  498. {ccxt-4.2.77.dist-info → ccxt-4.4.49.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.49.dist-info}/top_level.txt +0 -0
@@ -8,9 +8,10 @@ from ccxt.abstract.bitget import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
10
  import json
11
- from ccxt.base.types import Balances, Currency, FundingHistory, Int, Leverage, Liquidation, MarginMode, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
11
+ from ccxt.base.types import Balances, BorrowInterest, Conversion, CrossBorrowRate, Currencies, Currency, DepositAddress, FundingHistory, Int, IsolatedBorrowRate, LedgerEntry, Leverage, LeverageTier, Liquidation, LongShortRatio, MarginMode, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
12
12
  from typing import List
13
13
  from ccxt.base.errors import ExchangeError
14
+ from ccxt.base.errors import AuthenticationError
14
15
  from ccxt.base.errors import PermissionDenied
15
16
  from ccxt.base.errors import AccountSuspended
16
17
  from ccxt.base.errors import ArgumentsRequired
@@ -20,7 +21,6 @@ from ccxt.base.errors import InsufficientFunds
20
21
  from ccxt.base.errors import InvalidAddress
21
22
  from ccxt.base.errors import InvalidOrder
22
23
  from ccxt.base.errors import OrderNotFound
23
- from ccxt.base.errors import CancelPending
24
24
  from ccxt.base.errors import NotSupported
25
25
  from ccxt.base.errors import DDoSProtection
26
26
  from ccxt.base.errors import RateLimitExceeded
@@ -28,7 +28,7 @@ from ccxt.base.errors import ExchangeNotAvailable
28
28
  from ccxt.base.errors import OnMaintenance
29
29
  from ccxt.base.errors import InvalidNonce
30
30
  from ccxt.base.errors import RequestTimeout
31
- from ccxt.base.errors import AuthenticationError
31
+ from ccxt.base.errors import CancelPending
32
32
  from ccxt.base.decimal_to_precision import TICK_SIZE
33
33
  from ccxt.base.precise import Precise
34
34
 
@@ -59,6 +59,7 @@ class bitget(Exchange, ImplicitAPI):
59
59
  'cancelOrders': True,
60
60
  'closeAllPositions': True,
61
61
  'closePosition': True,
62
+ 'createConvertTrade': True,
62
63
  'createDepositAddress': False,
63
64
  'createMarketBuyOrderWithCost': True,
64
65
  'createMarketOrderWithCost': False,
@@ -85,20 +86,27 @@ class bitget(Exchange, ImplicitAPI):
85
86
  'fetchCanceledAndClosedOrders': True,
86
87
  'fetchCanceledOrders': True,
87
88
  'fetchClosedOrders': True,
89
+ 'fetchConvertCurrencies': True,
90
+ 'fetchConvertQuote': True,
91
+ 'fetchConvertTrade': False,
92
+ 'fetchConvertTradeHistory': True,
88
93
  'fetchCrossBorrowRate': True,
89
94
  'fetchCrossBorrowRates': False,
90
95
  'fetchCurrencies': True,
91
96
  'fetchDeposit': False,
92
97
  'fetchDepositAddress': True,
93
98
  'fetchDepositAddresses': False,
99
+ 'fetchDepositAddressesByNetwork': False,
94
100
  'fetchDeposits': True,
95
101
  'fetchDepositsWithdrawals': False,
96
102
  'fetchDepositWithdrawFee': 'emulated',
97
103
  'fetchDepositWithdrawFees': True,
98
104
  'fetchFundingHistory': True,
105
+ 'fetchFundingInterval': True,
106
+ 'fetchFundingIntervals': False,
99
107
  'fetchFundingRate': True,
100
108
  'fetchFundingRateHistory': True,
101
- 'fetchFundingRates': False,
109
+ 'fetchFundingRates': True,
102
110
  'fetchIndexOHLCV': True,
103
111
  'fetchIsolatedBorrowRate': True,
104
112
  'fetchIsolatedBorrowRates': False,
@@ -106,10 +114,14 @@ class bitget(Exchange, ImplicitAPI):
106
114
  'fetchLeverage': True,
107
115
  'fetchLeverageTiers': False,
108
116
  'fetchLiquidations': False,
117
+ 'fetchLongShortRatio': False,
118
+ 'fetchLongShortRatioHistory': True,
119
+ 'fetchMarginAdjustmentHistory': False,
109
120
  'fetchMarginMode': True,
110
121
  'fetchMarketLeverageTiers': True,
111
122
  'fetchMarkets': True,
112
123
  'fetchMarkOHLCV': True,
124
+ 'fetchMarkPrice': True,
113
125
  'fetchMyLiquidations': True,
114
126
  'fetchMyTrades': True,
115
127
  'fetchOHLCV': True,
@@ -122,8 +134,10 @@ class bitget(Exchange, ImplicitAPI):
122
134
  'fetchOrders': False,
123
135
  'fetchOrderTrades': False,
124
136
  'fetchPosition': True,
137
+ 'fetchPositionHistory': 'emulated',
125
138
  'fetchPositionMode': False,
126
139
  'fetchPositions': True,
140
+ 'fetchPositionsHistory': True,
127
141
  'fetchPositionsRisk': False,
128
142
  'fetchPremiumIndexOHLCV': False,
129
143
  'fetchStatus': False,
@@ -168,7 +182,7 @@ class bitget(Exchange, ImplicitAPI):
168
182
  },
169
183
  'hostname': 'bitget.com',
170
184
  'urls': {
171
- 'logo': 'https://user-images.githubusercontent.com/1294454/195989417-4253ddb0-afbe-4a1c-9dea-9dbcd121fa5d.jpg',
185
+ 'logo': 'https://github.com/user-attachments/assets/fbaa10cc-a277-441d-a5b7-997dd9a87658',
172
186
  'api': {
173
187
  'spot': 'https://api.{hostname}',
174
188
  'mix': 'https://api.{hostname}',
@@ -277,6 +291,7 @@ class bitget(Exchange, ImplicitAPI):
277
291
  'v2/mix/market/current-fund-rate': 1,
278
292
  'v2/mix/market/contracts': 1,
279
293
  'v2/mix/market/query-position-lever': 2,
294
+ 'v2/mix/market/account-long-short': 20,
280
295
  },
281
296
  },
282
297
  'margin': {
@@ -287,6 +302,7 @@ class bitget(Exchange, ImplicitAPI):
287
302
  'margin/v1/isolated/public/tierData': 2, # 10 times/1s(IP) => 20/10 = 2
288
303
  'margin/v1/public/currencies': 1, # 20 times/1s(IP) => 20/20 = 1
289
304
  'v2/margin/currencies': 2,
305
+ 'v2/margin/market/long-short-ratio': 20,
290
306
  },
291
307
  },
292
308
  'earn': {
@@ -324,6 +340,9 @@ class bitget(Exchange, ImplicitAPI):
324
340
  'v2/spot/account/subaccount-assets': 2,
325
341
  'v2/spot/account/bills': 2,
326
342
  'v2/spot/account/transferRecords': 1,
343
+ 'v2/account/funding-assets': 2,
344
+ 'v2/account/bot-assets': 2,
345
+ 'v2/account/all-account-balance': 20,
327
346
  'v2/spot/wallet/deposit-address': 2,
328
347
  'v2/spot/wallet/deposit-records': 2,
329
348
  'v2/spot/wallet/withdrawal-records': 2,
@@ -446,6 +465,7 @@ class bitget(Exchange, ImplicitAPI):
446
465
  'v2/mix/order/orders-history': 2,
447
466
  'v2/mix/order/orders-plan-pending': 2,
448
467
  'v2/mix/order/orders-plan-history': 2,
468
+ 'v2/mix/market/position-long-short': 20,
449
469
  },
450
470
  'post': {
451
471
  'mix/v1/account/sub-account-contract-assets': 200, # 0.1 times/1s(UID) => 20/0.1 = 200
@@ -494,7 +514,7 @@ class bitget(Exchange, ImplicitAPI):
494
514
  'v2/mix/account/set-margin': 4,
495
515
  'v2/mix/account/set-margin-mode': 4,
496
516
  'v2/mix/account/set-position-mode': 4,
497
- 'v2/mix/order/place-order': 20,
517
+ 'v2/mix/order/place-order': 2,
498
518
  'v2/mix/order/click-backhand': 20,
499
519
  'v2/mix/order/batch-place-order': 20,
500
520
  'v2/mix/order/modify-order': 2,
@@ -768,6 +788,7 @@ class bitget(Exchange, ImplicitAPI):
768
788
  'v2/earn/loan/borrow-history': 2,
769
789
  'v2/earn/loan/debts': 2,
770
790
  'v2/earn/loan/reduces': 2,
791
+ 'v2/earn/account/assets': 2,
771
792
  },
772
793
  'post': {
773
794
  'v2/earn/savings/subscribe': 2,
@@ -1238,9 +1259,14 @@ class bitget(Exchange, ImplicitAPI):
1238
1259
  '40712': InsufficientFunds, # Insufficient margin
1239
1260
  '40713': ExchangeError, # Cannot exceed the maximum transferable margin amount
1240
1261
  '40714': ExchangeError, # No direct margin call is allowed
1241
- '40768': OrderNotFound, # Order does not exist"
1262
+ '40762': InsufficientFunds, # {"code":"40762","msg":"The order amount exceeds the balance","requestTime":1716572156622,"data":null}
1263
+ '40768': OrderNotFound, # Order does not exist
1264
+ '40808': InvalidOrder, # {"code":"40808","msg":"Parameter verification exception size checkBDScale error value=2293.577 checkScale=2","requestTime":1725638500052,"data":null}
1265
+ '41103': InvalidOrder, # {"code":"41103","msg":"param price scale error error","requestTime":1725635883561,"data":null}
1242
1266
  '41114': OnMaintenance, # {"code":"41114","msg":"The current trading pair is under maintenance, please refer to the official announcement for the opening time","requestTime":1679196062544,"data":null}
1243
1267
  '43011': InvalidOrder, # The parameter does not meet the specification executePrice <= 0
1268
+ '43001': OrderNotFound,
1269
+ '43012': InsufficientFunds, # {"code":"43012","msg":"Insufficient balance","requestTime":1711648951774,"data":null}
1244
1270
  '43025': InvalidOrder, # Plan order does not exist
1245
1271
  '43115': OnMaintenance, # {"code":"43115","msg":"The current trading pair is opening soon, please refer to the official announcement for the opening time","requestTime":1688907202434,"data":null}
1246
1272
  '45110': InvalidOrder, # {"code":"45110","msg":"less than the minimum amount 5 USDT","requestTime":1669911118932,"data":null}
@@ -1314,9 +1340,15 @@ class bitget(Exchange, ImplicitAPI):
1314
1340
  },
1315
1341
  'precisionMode': TICK_SIZE,
1316
1342
  'commonCurrencies': {
1343
+ 'APX': 'AstroPepeX',
1344
+ 'DEGEN': 'DegenReborn',
1317
1345
  'JADE': 'Jade Protocol',
1346
+ 'OMNI': 'omni', # conflict with Omni Network
1347
+ 'TONCOIN': 'TON',
1318
1348
  },
1319
1349
  'options': {
1350
+ 'timeDifference': 0, # the difference between system clock and Binance clock
1351
+ 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
1320
1352
  'timeframes': {
1321
1353
  'spot': {
1322
1354
  '1m': '1min',
@@ -1371,18 +1403,18 @@ class bitget(Exchange, ImplicitAPI):
1371
1403
  '1m': 30,
1372
1404
  '3m': 30,
1373
1405
  '5m': 30,
1374
- '10m': 52,
1406
+ '10m': 30,
1375
1407
  '15m': 52,
1376
- '30m': 52,
1408
+ '30m': 62,
1377
1409
  '1h': 83,
1378
1410
  '2h': 120,
1379
1411
  '4h': 240,
1380
1412
  '6h': 360,
1381
1413
  '12h': 360,
1382
- '1d': 360,
1383
- '3d': 1000,
1384
- '1w': 1000,
1385
- '1M': 1000,
1414
+ '1d': 300,
1415
+ '3d': 300,
1416
+ '1w': 300,
1417
+ '1M': 300,
1386
1418
  },
1387
1419
  },
1388
1420
  'fetchTrades': {
@@ -1413,19 +1445,243 @@ class bitget(Exchange, ImplicitAPI):
1413
1445
  },
1414
1446
  'sandboxMode': False,
1415
1447
  'networks': {
1416
- 'TRX': 'TRC20',
1417
- 'ETH': 'ERC20',
1448
+ # 'TRX': 'TRX', # different code for mainnet
1449
+ 'TRC20': 'TRC20',
1450
+ # 'ETH': 'ETH', # different code for mainnet
1451
+ 'ERC20': 'ERC20',
1452
+ 'BEP20': 'BSC',
1453
+ # 'BEP20': 'BEP20', # different for BEP20
1418
1454
  'BSC': 'BEP20',
1455
+ 'ATOM': 'ATOM',
1456
+ 'ACA': 'AcalaToken',
1457
+ 'APT': 'Aptos',
1458
+ 'ARBONE': 'ArbitrumOne',
1459
+ 'ARBNOVA': 'ArbitrumNova',
1460
+ 'AVAXC': 'C-Chain',
1461
+ 'AVAXX': 'X-Chain',
1462
+ 'AR': 'Arweave',
1463
+ 'BCH': 'BCH',
1464
+ 'BCHA': 'BCHA',
1465
+ 'BITCI': 'BITCI',
1466
+ 'BTC': 'BTC',
1467
+ 'CELO': 'CELO',
1468
+ 'CSPR': 'CSPR',
1469
+ 'ADA': 'Cardano',
1470
+ 'CHZ': 'ChilizChain',
1471
+ 'CRC20': 'CronosChain',
1472
+ 'DOGE': 'DOGE',
1473
+ 'DOT': 'DOT',
1474
+ 'EOS': 'EOS',
1475
+ 'ETHF': 'ETHFAIR',
1476
+ 'ETHW': 'ETHW',
1477
+ 'ETC': 'ETC',
1478
+ 'EGLD': 'Elrond',
1479
+ 'FIL': 'FIL',
1480
+ 'FIO': 'FIO',
1481
+ 'FTM': 'Fantom',
1482
+ 'HRC20': 'HECO',
1483
+ 'ONE': 'Harmony',
1484
+ 'HNT': 'Helium',
1485
+ 'ICP': 'ICP',
1486
+ 'IOTX': 'IoTeX',
1487
+ 'KARDIA': 'KAI',
1488
+ 'KAVA': 'KAVA',
1489
+ 'KDA': 'KDA',
1490
+ 'KLAY': 'Klaytn',
1491
+ 'KSM': 'Kusama',
1492
+ 'LAT': 'LAT',
1493
+ 'LTC': 'LTC',
1494
+ 'MINA': 'MINA',
1495
+ 'MOVR': 'MOVR',
1496
+ 'METIS': 'MetisToken',
1497
+ 'GLMR': 'Moonbeam',
1498
+ 'NEAR': 'NEARProtocol',
1499
+ 'NULS': 'NULS',
1500
+ 'OASYS': 'OASYS',
1501
+ 'OASIS': 'ROSE',
1502
+ 'OMNI': 'OMNI',
1503
+ 'ONT': 'Ontology',
1504
+ 'OPTIMISM': 'Optimism',
1505
+ 'OSMO': 'Osmosis',
1506
+ 'POKT': 'PocketNetwork',
1507
+ 'MATIC': 'Polygon',
1508
+ 'QTUM': 'QTUM',
1509
+ 'REEF': 'REEF',
1510
+ 'SOL': 'SOL',
1511
+ 'SYS': 'SYS', # SyscoinNEVM is different
1512
+ 'SXP': 'Solar',
1513
+ 'XYM': 'Symbol',
1514
+ 'TON': 'TON',
1515
+ 'TT': 'TT',
1516
+ 'TLOS': 'Telos',
1517
+ 'THETA': 'ThetaToken',
1518
+ 'VITE': 'VITE',
1519
+ 'WAVES': 'WAVES',
1520
+ 'WAX': 'WAXP',
1521
+ 'WEMIX': 'WEMIXMainnet',
1522
+ 'XDC': 'XDCNetworkXDC',
1523
+ 'XRP': 'XRP',
1524
+ 'FET': 'FETCH',
1525
+ 'NEM': 'NEM',
1526
+ 'REI': 'REINetwork',
1527
+ 'ZIL': 'ZIL',
1528
+ 'ABBC': 'ABBCCoin',
1529
+ 'RSK': 'RSK',
1530
+ 'AZERO': 'AZERO',
1531
+ 'TRC10': 'TRC10',
1532
+ 'JUNO': 'JUNO',
1533
+ # undetected: USDSP, more info at https://www.bitget.com/v1/spot/public/coinChainList
1534
+ # todo: uncomment below after unification
1535
+ # 'TERRACLASSIC': 'Terra', # tbd, that network id is also assigned to TERRANEW network
1536
+ # 'CUBENETWORK': 'CUBE',
1537
+ # 'CADUCEUS': 'CMP',
1538
+ # 'CONFLUX': 'CFX', # CFXeSpace is different
1539
+ # 'CERE': 'CERE',
1540
+ # 'CANTO': 'CANTO',
1541
+ 'ZKSYNC': 'zkSyncEra',
1542
+ 'STARKNET': 'Starknet',
1543
+ 'VIC': 'VICTION',
1419
1544
  },
1420
1545
  'networksById': {
1421
- 'TRC20': 'TRX',
1422
- 'BSC': 'BEP20',
1423
1546
  },
1424
1547
  'fetchPositions': {
1425
1548
  'method': 'privateMixGetV2MixPositionAllPosition', # or privateMixGetV2MixPositionHistoryPosition
1426
1549
  },
1427
1550
  'defaultTimeInForce': 'GTC', # 'GTC' = Good To Cancel(default), 'IOC' = Immediate Or Cancel
1428
1551
  },
1552
+ 'features': {
1553
+ 'spot': {
1554
+ 'sandbox': True,
1555
+ 'createOrder': {
1556
+ 'marginMode': True,
1557
+ 'triggerPrice': True,
1558
+ 'triggerPriceType': {
1559
+ 'last': True,
1560
+ 'mark': True,
1561
+ 'index': False, # not on spot
1562
+ },
1563
+ 'triggerDirection': False,
1564
+ 'stopLossPrice': True, # todo: not yet implemented in spot
1565
+ 'takeProfitPrice': True, # todo: not yet implemented in spot
1566
+ 'attachedStopLossTakeProfit': {
1567
+ 'triggerPriceType': {
1568
+ 'last': False,
1569
+ 'mark': False,
1570
+ 'index': False,
1571
+ },
1572
+ 'price': True,
1573
+ },
1574
+ 'timeInForce': {
1575
+ 'IOC': True,
1576
+ 'FOK': True,
1577
+ 'PO': True,
1578
+ 'GTD': False,
1579
+ },
1580
+ 'hedged': False,
1581
+ 'trailing': False,
1582
+ 'marketBuyRequiresPrice': True,
1583
+ 'marketBuyByCost': True,
1584
+ # exchange-supported features
1585
+ # 'selfTradePrevention': True,
1586
+ # 'twap': False,
1587
+ # 'iceberg': False,
1588
+ # 'oco': False,
1589
+ },
1590
+ 'createOrders': {
1591
+ 'max': 50,
1592
+ },
1593
+ 'fetchMyTrades': {
1594
+ 'marginMode': True,
1595
+ 'limit': 100,
1596
+ 'daysBack': None,
1597
+ 'untilDays': 90,
1598
+ },
1599
+ 'fetchOrder': {
1600
+ 'marginMode': False,
1601
+ 'trigger': False,
1602
+ 'trailing': False,
1603
+ },
1604
+ 'fetchOpenOrders': {
1605
+ 'marginMode': True,
1606
+ 'limit': 100,
1607
+ 'trigger': True,
1608
+ 'trailing': False,
1609
+ },
1610
+ 'fetchOrders': None,
1611
+ 'fetchClosedOrders': {
1612
+ 'marginMode': True,
1613
+ 'limit': 100,
1614
+ 'daysBack': None,
1615
+ 'daysBackCanceled': None,
1616
+ 'untilDays': 90,
1617
+ 'trigger': True,
1618
+ 'trailing': False,
1619
+ },
1620
+ 'fetchOHLCV': {
1621
+ 'limit': 1000, # variable timespans for recent endpoint, 200 for historical
1622
+ },
1623
+ },
1624
+ 'forPerps': {
1625
+ 'extends': 'spot',
1626
+ 'createOrder': {
1627
+ 'triggerPrice': True,
1628
+ 'triggerPriceType': {
1629
+ 'last': True,
1630
+ 'mark': True,
1631
+ 'index': False, # not on spot
1632
+ },
1633
+ 'triggerDirection': False,
1634
+ 'stopLossPrice': True,
1635
+ 'takeProfitPrice': True,
1636
+ 'attachedStopLossTakeProfit': {
1637
+ 'triggerPriceType': {
1638
+ 'last': True,
1639
+ 'mark': True,
1640
+ 'index': True,
1641
+ },
1642
+ 'price': False,
1643
+ },
1644
+ 'timeInForce': {
1645
+ 'IOC': True,
1646
+ 'FOK': True,
1647
+ 'PO': True,
1648
+ 'GTD': False,
1649
+ },
1650
+ 'hedged': True,
1651
+ 'trailing': True,
1652
+ 'marketBuyRequiresPrice': False,
1653
+ 'marketBuyByCost': False,
1654
+ # exchange-supported features
1655
+ # 'selfTradePrevention': True,
1656
+ # 'trailing': True,
1657
+ # 'twap': False,
1658
+ # 'iceberg': False,
1659
+ # 'oco': False,
1660
+ },
1661
+ 'fetchMyTrades': {
1662
+ 'untilDays': 7,
1663
+ },
1664
+ 'fetchClosedOrders': {
1665
+ 'trailing': True,
1666
+ },
1667
+ },
1668
+ 'swap': {
1669
+ 'linear': {
1670
+ 'extends': 'forPerps',
1671
+ },
1672
+ 'inverse': {
1673
+ 'extends': 'forPerps',
1674
+ },
1675
+ },
1676
+ 'future': {
1677
+ 'linear': {
1678
+ 'extends': 'forPerps',
1679
+ },
1680
+ 'inverse': {
1681
+ 'extends': 'forPerps',
1682
+ },
1683
+ },
1684
+ },
1429
1685
  })
1430
1686
 
1431
1687
  def set_sandbox_mode(self, enabled):
@@ -1492,7 +1748,9 @@ class bitget(Exchange, ImplicitAPI):
1492
1748
  async def fetch_time(self, params={}):
1493
1749
  """
1494
1750
  fetches the current integer timestamp in milliseconds from the exchange server
1495
- :see: https://www.bitget.com/api-doc/common/public/Get-Server-Time
1751
+
1752
+ https://www.bitget.com/api-doc/common/public/Get-Server-Time
1753
+
1496
1754
  :param dict [params]: extra parameters specific to the exchange API endpoint
1497
1755
  :returns int: the current integer timestamp in milliseconds from the exchange server
1498
1756
  """
@@ -1510,22 +1768,28 @@ class bitget(Exchange, ImplicitAPI):
1510
1768
  data = self.safe_value(response, 'data', {})
1511
1769
  return self.safe_integer(data, 'serverTime')
1512
1770
 
1513
- async def fetch_markets(self, params={}):
1771
+ async def fetch_markets(self, params={}) -> List[Market]:
1514
1772
  """
1515
1773
  retrieves data on all markets for bitget
1516
- :see: https://www.bitget.com/api-doc/spot/market/Get-Symbols
1517
- :see: https://www.bitget.com/api-doc/contract/market/Get-All-Symbols-Contracts
1774
+
1775
+ https://www.bitget.com/api-doc/spot/market/Get-Symbols
1776
+ https://www.bitget.com/api-doc/contract/market/Get-All-Symbols-Contracts
1777
+ https://www.bitget.com/api-doc/margin/common/support-currencies
1778
+
1518
1779
  :param dict [params]: extra parameters specific to the exchange API endpoint
1519
1780
  :returns dict[]: an array of objects representing market data
1520
1781
  """
1782
+ if self.options['adjustForTimeDifference']:
1783
+ await self.load_time_difference()
1521
1784
  sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
1522
1785
  types = self.safe_value(self.options, 'fetchMarkets', ['spot', 'swap'])
1523
1786
  if sandboxMode:
1524
1787
  types = ['swap']
1525
1788
  promises = []
1789
+ fetchMargins = False
1526
1790
  for i in range(0, len(types)):
1527
1791
  type = types[i]
1528
- if type == 'swap':
1792
+ if (type == 'swap') or (type == 'future'):
1529
1793
  subTypes = None
1530
1794
  if sandboxMode:
1531
1795
  # the following are simulated trading markets ['SUSDT-FUTURES', 'SCOIN-FUTURES', 'SUSDC-FUTURES']
@@ -1533,18 +1797,36 @@ class bitget(Exchange, ImplicitAPI):
1533
1797
  else:
1534
1798
  subTypes = ['USDT-FUTURES', 'COIN-FUTURES', 'USDC-FUTURES']
1535
1799
  for j in range(0, len(subTypes)):
1536
- promises.append(self.fetch_markets_by_type(type, self.extend(params, {
1800
+ promises.append(self.publicMixGetV2MixMarketContracts(self.extend(params, {
1537
1801
  'productType': subTypes[j],
1538
1802
  })))
1803
+ elif type == 'spot':
1804
+ promises.append(self.publicSpotGetV2SpotPublicSymbols(params))
1805
+ fetchMargins = True
1806
+ promises.append(self.publicMarginGetV2MarginCurrencies(params))
1539
1807
  else:
1540
- promises.append(self.fetch_markets_by_type(types[i], params))
1541
- promises = await asyncio.gather(*promises)
1542
- result = promises[0]
1543
- for i in range(1, len(promises)):
1544
- result = self.array_concat(result, promises[i])
1808
+ raise NotSupported(self.id + ' does not support ' + type + ' market')
1809
+ results = await asyncio.gather(*promises)
1810
+ markets = []
1811
+ self.options['crossMarginPairsData'] = []
1812
+ self.options['isolatedMarginPairsData'] = []
1813
+ for i in range(0, len(results)):
1814
+ res = self.safe_dict(results, i)
1815
+ data = self.safe_list(res, 'data', [])
1816
+ firstData = self.safe_dict(data, 0, {})
1817
+ isBorrowable = self.safe_string(firstData, 'isBorrowable')
1818
+ if fetchMargins and isBorrowable is not None:
1819
+ keysList = list(self.index_by(data, 'symbol').keys())
1820
+ self.options['crossMarginPairsData'] = keysList
1821
+ self.options['isolatedMarginPairsData'] = keysList
1822
+ else:
1823
+ markets = self.array_concat(markets, data)
1824
+ result = []
1825
+ for i in range(0, len(markets)):
1826
+ result.append(self.parse_market(markets[i]))
1545
1827
  return result
1546
1828
 
1547
- def parse_market(self, market) -> Market:
1829
+ def parse_market(self, market: dict) -> Market:
1548
1830
  #
1549
1831
  # spot
1550
1832
  #
@@ -1629,11 +1911,20 @@ class bitget(Exchange, ImplicitAPI):
1629
1911
  expiry = None
1630
1912
  expiryDatetime = None
1631
1913
  symbolType = self.safe_string(market, 'symbolType')
1914
+ marginModes = None
1915
+ isMarginTradingAllowed = False
1632
1916
  if symbolType is None:
1633
1917
  type = 'spot'
1634
1918
  spot = True
1635
1919
  pricePrecision = self.parse_number(self.parse_precision(self.safe_string(market, 'pricePrecision')))
1636
1920
  amountPrecision = self.parse_number(self.parse_precision(self.safe_string(market, 'quantityPrecision')))
1921
+ hasCrossMargin = self.in_array(marketId, self.options['crossMarginPairsData'])
1922
+ hasIsolatedMargin = self.in_array(marketId, self.options['isolatedMarginPairsData'])
1923
+ marginModes = {
1924
+ 'cross': hasCrossMargin,
1925
+ 'isolated': hasIsolatedMargin,
1926
+ }
1927
+ isMarginTradingAllowed = hasCrossMargin or hasCrossMargin
1637
1928
  else:
1638
1929
  if symbolType == 'perpetual':
1639
1930
  type = 'swap'
@@ -1669,6 +1960,10 @@ class bitget(Exchange, ImplicitAPI):
1669
1960
  preciseAmount.reduce()
1670
1961
  amountString = str(preciseAmount)
1671
1962
  amountPrecision = self.parse_number(amountString)
1963
+ marginModes = {
1964
+ 'cross': True,
1965
+ 'isolated': True,
1966
+ }
1672
1967
  status = self.safe_string_2(market, 'status', 'symbolStatus')
1673
1968
  active = None
1674
1969
  if status is not None:
@@ -1688,7 +1983,8 @@ class bitget(Exchange, ImplicitAPI):
1688
1983
  'settleId': settleId,
1689
1984
  'type': type,
1690
1985
  'spot': spot,
1691
- 'margin': None,
1986
+ 'margin': spot and isMarginTradingAllowed,
1987
+ 'marginModes': marginModes,
1692
1988
  'swap': swap,
1693
1989
  'future': future,
1694
1990
  'option': False,
@@ -1729,92 +2025,12 @@ class bitget(Exchange, ImplicitAPI):
1729
2025
  'info': market,
1730
2026
  }
1731
2027
 
1732
- async def fetch_markets_by_type(self, type, params={}):
1733
- response = None
1734
- if type == 'spot':
1735
- response = await self.publicSpotGetV2SpotPublicSymbols(params)
1736
- elif (type == 'swap') or (type == 'future'):
1737
- response = await self.publicMixGetV2MixMarketContracts(params)
1738
- else:
1739
- raise NotSupported(self.id + ' does not support ' + type + ' market')
1740
- #
1741
- # spot
1742
- #
1743
- # {
1744
- # "code": "00000",
1745
- # "msg": "success",
1746
- # "requestTime": 1700102364653,
1747
- # "data": [
1748
- # {
1749
- # "symbol": "TRXUSDT",
1750
- # "baseCoin": "TRX",
1751
- # "quoteCoin": "USDT",
1752
- # "minTradeAmount": "0",
1753
- # "maxTradeAmount": "10000000000",
1754
- # "takerFeeRate": "0.002",
1755
- # "makerFeeRate": "0.002",
1756
- # "pricePrecision": "6",
1757
- # "quantityPrecision": "4",
1758
- # "quotePrecision": "6",
1759
- # "status": "online",
1760
- # "minTradeUSDT": "5",
1761
- # "buyLimitPriceRatio": "0.05",
1762
- # "sellLimitPriceRatio": "0.05"
1763
- # },
1764
- # ]
1765
- # }
1766
- #
1767
- # swap and future
1768
- #
1769
- # {
1770
- # "code": "00000",
1771
- # "msg": "success",
1772
- # "requestTime": 1700102364709,
1773
- # "data": [
1774
- # {
1775
- # "symbol": "BTCUSDT",
1776
- # "baseCoin": "BTC",
1777
- # "quoteCoin": "USDT",
1778
- # "buyLimitPriceRatio": "0.01",
1779
- # "sellLimitPriceRatio": "0.01",
1780
- # "feeRateUpRatio": "0.005",
1781
- # "makerFeeRate": "0.0002",
1782
- # "takerFeeRate": "0.0006",
1783
- # "openCostUpRatio": "0.01",
1784
- # "supportMarginCoins": ["USDT"],
1785
- # "minTradeNum": "0.001",
1786
- # "priceEndStep": "1",
1787
- # "volumePlace": "3",
1788
- # "pricePlace": "1",
1789
- # "sizeMultiplier": "0.001",
1790
- # "symbolType": "perpetual",
1791
- # "minTradeUSDT": "5",
1792
- # "maxSymbolOrderNum": "200",
1793
- # "maxProductOrderNum": "400",
1794
- # "maxPositionNum": "150",
1795
- # "symbolStatus": "normal",
1796
- # "offTime": "-1",
1797
- # "limitOpenTime": "-1",
1798
- # "deliveryTime": "",
1799
- # "deliveryStartTime": "",
1800
- # "deliveryPeriod": "",
1801
- # "launchTime": "",
1802
- # "fundInterval": "8",
1803
- # "minLever": "1",
1804
- # "maxLever": "125",
1805
- # "posLimit": "0.05",
1806
- # "maintainTime": ""
1807
- # },
1808
- # ]
1809
- # }
1810
- #
1811
- data = self.safe_value(response, 'data', [])
1812
- return self.parse_markets(data)
1813
-
1814
- async def fetch_currencies(self, params={}):
2028
+ async def fetch_currencies(self, params={}) -> Currencies:
1815
2029
  """
1816
2030
  fetches all available currencies on an exchange
1817
- :see: https://www.bitget.com/api-doc/spot/market/Get-Coin-List
2031
+
2032
+ https://www.bitget.com/api-doc/spot/market/Get-Coin-List
2033
+
1818
2034
  :param dict [params]: extra parameters specific to the exchange API endpoint
1819
2035
  :returns dict: an associative dictionary of currencies
1820
2036
  """
@@ -1848,14 +2064,14 @@ class bitget(Exchange, ImplicitAPI):
1848
2064
  # "requestTime": "1700120731773"
1849
2065
  # }
1850
2066
  #
1851
- result = {}
2067
+ result: dict = {}
1852
2068
  data = self.safe_value(response, 'data', [])
1853
2069
  for i in range(0, len(data)):
1854
2070
  entry = data[i]
1855
- id = self.safe_string(entry, 'coinId')
1856
- code = self.safe_currency_code(self.safe_string(entry, 'coin'))
2071
+ id = self.safe_string(entry, 'coin') # we don't use 'coinId' has no use. it is 'coin' field that needs to be used in currency related endpoints(deposit, withdraw, etc..)
2072
+ code = self.safe_currency_code(id)
1857
2073
  chains = self.safe_value(entry, 'chains', [])
1858
- networks = {}
2074
+ networks: dict = {}
1859
2075
  deposit = False
1860
2076
  withdraw = False
1861
2077
  minWithdrawString = None
@@ -1864,7 +2080,9 @@ class bitget(Exchange, ImplicitAPI):
1864
2080
  for j in range(0, len(chains)):
1865
2081
  chain = chains[j]
1866
2082
  networkId = self.safe_string(chain, 'chain')
1867
- network = self.safe_currency_code(networkId)
2083
+ network = self.network_id_to_code(networkId, code)
2084
+ if network is not None:
2085
+ network = network.upper()
1868
2086
  withdrawEnabled = self.safe_string(chain, 'withdrawable')
1869
2087
  canWithdraw = withdrawEnabled == 'true'
1870
2088
  withdraw = canWithdraw if (canWithdraw) else withdraw
@@ -1930,12 +2148,14 @@ class bitget(Exchange, ImplicitAPI):
1930
2148
  }
1931
2149
  return result
1932
2150
 
1933
- async def fetch_market_leverage_tiers(self, symbol: str, params={}):
2151
+ async def fetch_market_leverage_tiers(self, symbol: str, params={}) -> List[LeverageTier]:
1934
2152
  """
1935
2153
  retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes for a single market
1936
- :see: https://www.bitget.com/api-doc/contract/position/Get-Query-Position-Lever
1937
- :see: https://www.bitget.com/api-doc/margin/cross/account/Cross-Tier-Data
1938
- :see: https://www.bitget.com/api-doc/margin/isolated/account/Isolated-Tier-Data
2154
+
2155
+ https://www.bitget.com/api-doc/contract/position/Get-Query-Position-Lever
2156
+ https://www.bitget.com/api-doc/margin/cross/account/Cross-Tier-Data
2157
+ https://www.bitget.com/api-doc/margin/isolated/account/Isolated-Tier-Data
2158
+
1939
2159
  :param str symbol: unified market symbol
1940
2160
  :param dict [params]: extra parameters specific to the exchange API endpoint
1941
2161
  :param str [params.marginMode]: for spot margin 'cross' or 'isolated', default is 'isolated'
@@ -1951,7 +2171,7 @@ class bitget(Exchange, ImplicitAPI):
1951
2171
  market = self.market(sandboxSymbol)
1952
2172
  else:
1953
2173
  market = self.market(symbol)
1954
- request = {}
2174
+ request: dict = {}
1955
2175
  response = None
1956
2176
  marginMode = None
1957
2177
  marginMode, params = self.handle_margin_mode_and_params('fetchMarketLeverageTiers', params, 'isolated')
@@ -1970,7 +2190,7 @@ class bitget(Exchange, ImplicitAPI):
1970
2190
  raise ArgumentsRequired(self.id + ' fetchMarketLeverageTiers() requires a code argument')
1971
2191
  params = self.omit(params, 'code')
1972
2192
  currency = self.currency(code)
1973
- request['coin'] = currency['code']
2193
+ request['coin'] = currency['id']
1974
2194
  response = await self.privateMarginGetV2MarginCrossedTierData(self.extend(request, params))
1975
2195
  else:
1976
2196
  raise BadRequest(self.id + ' fetchMarketLeverageTiers() symbol does not support market ' + market['symbol'])
@@ -2034,7 +2254,7 @@ class bitget(Exchange, ImplicitAPI):
2034
2254
  result = self.safe_value(response, 'data', [])
2035
2255
  return self.parse_market_leverage_tiers(result, market)
2036
2256
 
2037
- def parse_market_leverage_tiers(self, info, market: Market = None):
2257
+ def parse_market_leverage_tiers(self, info, market: Market = None) -> List[LeverageTier]:
2038
2258
  #
2039
2259
  # swap and future
2040
2260
  #
@@ -2081,8 +2301,10 @@ class bitget(Exchange, ImplicitAPI):
2081
2301
  maxNotional = self.safe_number_n(item, ['endUnit', 'maxBorrowableAmount', 'baseMaxBorrowableAmount'])
2082
2302
  marginCurrency = self.safe_string_2(item, 'coin', 'baseCoin')
2083
2303
  currencyId = marginCurrency if (marginCurrency is not None) else market['base']
2304
+ marketId = self.safe_string(item, 'symbol')
2084
2305
  tiers.append({
2085
2306
  'tier': self.safe_integer_2(item, 'level', 'tier'),
2307
+ 'symbol': self.safe_symbol(marketId, market),
2086
2308
  'currency': self.safe_currency_code(currencyId),
2087
2309
  'minNotional': minNotional,
2088
2310
  'maxNotional': maxNotional,
@@ -2096,7 +2318,9 @@ class bitget(Exchange, ImplicitAPI):
2096
2318
  async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2097
2319
  """
2098
2320
  fetch all deposits made to an account
2099
- :see: https://www.bitget.com/api-doc/spot/account/Get-Deposit-Record
2321
+
2322
+ https://www.bitget.com/api-doc/spot/account/Get-Deposit-Record
2323
+
2100
2324
  :param str code: unified currency code
2101
2325
  :param int [since]: the earliest time in ms to fetch deposits for
2102
2326
  :param int [limit]: the maximum number of deposits structures to retrieve
@@ -2116,8 +2340,8 @@ class bitget(Exchange, ImplicitAPI):
2116
2340
  currency = self.currency(code)
2117
2341
  if since is None:
2118
2342
  since = self.milliseconds() - 7776000000 # 90 days
2119
- request = {
2120
- 'coin': currency['code'],
2343
+ request: dict = {
2344
+ 'coin': currency['id'],
2121
2345
  'startTime': since,
2122
2346
  'endTime': self.milliseconds(),
2123
2347
  }
@@ -2148,13 +2372,15 @@ class bitget(Exchange, ImplicitAPI):
2148
2372
  # ]
2149
2373
  # }
2150
2374
  #
2151
- rawTransactions = self.safe_value(response, 'data', [])
2375
+ rawTransactions = self.safe_list(response, 'data', [])
2152
2376
  return self.parse_transactions(rawTransactions, currency, since, limit)
2153
2377
 
2154
- async def withdraw(self, code: str, amount: float, address, tag=None, params={}):
2378
+ async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
2155
2379
  """
2156
2380
  make a withdrawal
2157
- :see: https://www.bitget.com/api-doc/spot/account/Wallet-Withdrawal
2381
+
2382
+ https://www.bitget.com/api-doc/spot/account/Wallet-Withdrawal
2383
+
2158
2384
  :param str code: unified currency code
2159
2385
  :param float amount: the amount to withdraw
2160
2386
  :param str address: the address to withdraw to
@@ -2164,15 +2390,15 @@ class bitget(Exchange, ImplicitAPI):
2164
2390
  :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
2165
2391
  """
2166
2392
  self.check_address(address)
2167
- chain = self.safe_string_2(params, 'chain', 'network')
2168
- params = self.omit(params, 'network')
2169
- if chain is None:
2170
- raise ArgumentsRequired(self.id + ' withdraw() requires a chain parameter or a network parameter')
2393
+ networkCode = None
2394
+ networkCode, params = self.handle_network_code_and_params(params)
2395
+ if networkCode is None:
2396
+ raise ArgumentsRequired(self.id + ' withdraw() requires a "network" parameter')
2171
2397
  await self.load_markets()
2172
2398
  currency = self.currency(code)
2173
- networkId = self.network_code_to_id(chain)
2174
- request = {
2175
- 'coin': currency['code'],
2399
+ networkId = self.network_code_to_id(networkCode)
2400
+ request: dict = {
2401
+ 'coin': currency['id'],
2176
2402
  'address': address,
2177
2403
  'chain': networkId,
2178
2404
  'size': amount,
@@ -2193,27 +2419,8 @@ class bitget(Exchange, ImplicitAPI):
2193
2419
  # }
2194
2420
  #
2195
2421
  data = self.safe_value(response, 'data', {})
2196
- result = {
2197
- 'id': self.safe_string(data, 'orderId'),
2198
- 'info': response,
2199
- 'txid': None,
2200
- 'timestamp': None,
2201
- 'datetime': None,
2202
- 'network': None,
2203
- 'addressFrom': None,
2204
- 'address': None,
2205
- 'addressTo': None,
2206
- 'amount': None,
2207
- 'type': 'withdrawal',
2208
- 'currency': None,
2209
- 'status': None,
2210
- 'updated': None,
2211
- 'tagFrom': None,
2212
- 'tag': None,
2213
- 'tagTo': None,
2214
- 'comment': None,
2215
- 'fee': None,
2216
- }
2422
+ result = self.parse_transaction(data, currency)
2423
+ result['type'] = 'withdrawal'
2217
2424
  withdrawOptions = self.safe_value(self.options, 'withdraw', {})
2218
2425
  fillResponseFromRequest = self.safe_bool(withdrawOptions, 'fillResponseFromRequest', True)
2219
2426
  if fillResponseFromRequest:
@@ -2224,13 +2431,15 @@ class bitget(Exchange, ImplicitAPI):
2224
2431
  result['tag'] = tag
2225
2432
  result['address'] = address
2226
2433
  result['addressTo'] = address
2227
- result['network'] = chain
2434
+ result['network'] = networkCode
2228
2435
  return result
2229
2436
 
2230
2437
  async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2231
2438
  """
2232
2439
  fetch all withdrawals made from an account
2233
- :see: https://www.bitget.com/api-doc/spot/account/Get-Withdraw-Record
2440
+
2441
+ https://www.bitget.com/api-doc/spot/account/Get-Withdraw-Record
2442
+
2234
2443
  :param str code: unified currency code
2235
2444
  :param int [since]: the earliest time in ms to fetch withdrawals for
2236
2445
  :param int [limit]: the maximum number of withdrawals structures to retrieve
@@ -2250,8 +2459,8 @@ class bitget(Exchange, ImplicitAPI):
2250
2459
  currency = self.currency(code)
2251
2460
  if since is None:
2252
2461
  since = self.milliseconds() - 7776000000 # 90 days
2253
- request = {
2254
- 'coin': currency['code'],
2462
+ request: dict = {
2463
+ 'coin': currency['id'],
2255
2464
  'startTime': since,
2256
2465
  'endTime': self.milliseconds(),
2257
2466
  }
@@ -2285,10 +2494,10 @@ class bitget(Exchange, ImplicitAPI):
2285
2494
  # ]
2286
2495
  # }
2287
2496
  #
2288
- rawTransactions = self.safe_value(response, 'data', [])
2497
+ rawTransactions = self.safe_list(response, 'data', [])
2289
2498
  return self.parse_transactions(rawTransactions, currency, since, limit)
2290
2499
 
2291
- def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
2500
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
2292
2501
  #
2293
2502
  # fetchDeposits
2294
2503
  #
@@ -2363,8 +2572,8 @@ class bitget(Exchange, ImplicitAPI):
2363
2572
  'fee': fee,
2364
2573
  }
2365
2574
 
2366
- def parse_transaction_status(self, status):
2367
- statuses = {
2575
+ def parse_transaction_status(self, status: Str):
2576
+ statuses: dict = {
2368
2577
  'success': 'ok',
2369
2578
  'Pending': 'pending',
2370
2579
  'pending_review': 'pending',
@@ -2373,26 +2582,25 @@ class bitget(Exchange, ImplicitAPI):
2373
2582
  }
2374
2583
  return self.safe_string(statuses, status, status)
2375
2584
 
2376
- async def fetch_deposit_address(self, code: str, params={}):
2585
+ async def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
2377
2586
  """
2378
2587
  fetch the deposit address for a currency associated with self account
2379
- :see: https://www.bitget.com/api-doc/spot/account/Get-Deposit-Address
2588
+
2589
+ https://www.bitget.com/api-doc/spot/account/Get-Deposit-Address
2590
+
2380
2591
  :param str code: unified currency code
2381
2592
  :param dict [params]: extra parameters specific to the exchange API endpoint
2382
2593
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
2383
2594
  """
2384
2595
  await self.load_markets()
2385
- networkCode = self.safe_string_2(params, 'chain', 'network')
2386
- params = self.omit(params, 'network')
2387
- networkId = None
2388
- if networkCode is not None:
2389
- networkId = self.network_code_to_id(networkCode, code)
2596
+ networkCode = None
2597
+ networkCode, params = self.handle_network_code_and_params(params)
2390
2598
  currency = self.currency(code)
2391
- request = {
2392
- 'coin': currency['code'],
2599
+ request: dict = {
2600
+ 'coin': currency['id'],
2393
2601
  }
2394
- if networkId is not None:
2395
- request['chain'] = networkId
2602
+ if networkCode is not None:
2603
+ request['chain'] = self.network_code_to_id(networkCode, code)
2396
2604
  response = await self.privateSpotGetV2SpotWalletDepositAddress(self.extend(request, params))
2397
2605
  #
2398
2606
  # {
@@ -2408,10 +2616,10 @@ class bitget(Exchange, ImplicitAPI):
2408
2616
  # }
2409
2617
  # }
2410
2618
  #
2411
- data = self.safe_value(response, 'data', {})
2619
+ data = self.safe_dict(response, 'data', {})
2412
2620
  return self.parse_deposit_address(data, currency)
2413
2621
 
2414
- def parse_deposit_address(self, depositAddress, currency: Currency = None):
2622
+ def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
2415
2623
  #
2416
2624
  # {
2417
2625
  # "coin": "BTC",
@@ -2428,18 +2636,20 @@ class bitget(Exchange, ImplicitAPI):
2428
2636
  if networkId is not None:
2429
2637
  network = self.network_id_to_code(networkId, parsedCurrency)
2430
2638
  return {
2639
+ 'info': depositAddress,
2431
2640
  'currency': parsedCurrency,
2641
+ 'network': network,
2432
2642
  'address': self.safe_string(depositAddress, 'address'),
2433
2643
  'tag': self.safe_string(depositAddress, 'tag'),
2434
- 'network': network,
2435
- 'info': depositAddress,
2436
2644
  }
2437
2645
 
2438
2646
  async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
2439
2647
  """
2440
2648
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
2441
- :see: https://www.bitget.com/api-doc/spot/market/Get-Orderbook
2442
- :see: https://www.bitget.com/api-doc/contract/market/Get-Merge-Depth
2649
+
2650
+ https://www.bitget.com/api-doc/spot/market/Get-Orderbook
2651
+ https://www.bitget.com/api-doc/contract/market/Get-Merge-Depth
2652
+
2443
2653
  :param str symbol: unified symbol of the market to fetch the order book for
2444
2654
  :param int [limit]: the maximum amount of order book entries to return
2445
2655
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2453,7 +2663,7 @@ class bitget(Exchange, ImplicitAPI):
2453
2663
  market = self.market(sandboxSymbol)
2454
2664
  else:
2455
2665
  market = self.market(symbol)
2456
- request = {
2666
+ request: dict = {
2457
2667
  'symbol': market['id'],
2458
2668
  }
2459
2669
  if limit is not None:
@@ -2482,7 +2692,15 @@ class bitget(Exchange, ImplicitAPI):
2482
2692
  timestamp = self.safe_integer(data, 'ts')
2483
2693
  return self.parse_order_book(data, market['symbol'], timestamp)
2484
2694
 
2485
- def parse_ticker(self, ticker, market: Market = None) -> Ticker:
2695
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
2696
+ #
2697
+ # {
2698
+ # "symbol": "BTCUSDT",
2699
+ # "price": "26242",
2700
+ # "indexPrice": "34867",
2701
+ # "markPrice": "25555",
2702
+ # "ts": "1695793390482"
2703
+ # }
2486
2704
  #
2487
2705
  # spot: fetchTicker, fetchTickers
2488
2706
  #
@@ -2555,7 +2773,7 @@ class bitget(Exchange, ImplicitAPI):
2555
2773
  #
2556
2774
  marketId = self.safe_string(ticker, 'symbol')
2557
2775
  close = self.safe_string(ticker, 'lastPr')
2558
- timestamp = self.safe_integer(ticker, 'ts')
2776
+ timestamp = self.safe_integer_omit_zero(ticker, 'ts') # exchange bitget provided 0
2559
2777
  change = self.safe_string(ticker, 'change24h')
2560
2778
  open24 = self.safe_string(ticker, 'open24')
2561
2779
  open = self.safe_string(ticker, 'open')
@@ -2587,14 +2805,18 @@ class bitget(Exchange, ImplicitAPI):
2587
2805
  'average': None,
2588
2806
  'baseVolume': self.safe_string(ticker, 'baseVolume'),
2589
2807
  'quoteVolume': self.safe_string(ticker, 'quoteVolume'),
2808
+ 'indexPrice': self.safe_string(ticker, 'indexPrice'),
2809
+ 'markPrice': self.safe_string(ticker, 'markPrice'),
2590
2810
  'info': ticker,
2591
2811
  }, market)
2592
2812
 
2593
2813
  async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
2594
2814
  """
2595
2815
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
2596
- :see: https://www.bitget.com/api-doc/spot/market/Get-Tickers
2597
- :see: https://www.bitget.com/api-doc/contract/market/Get-Ticker
2816
+
2817
+ https://www.bitget.com/api-doc/spot/market/Get-Tickers
2818
+ https://www.bitget.com/api-doc/contract/market/Get-Ticker
2819
+
2598
2820
  :param str symbol: unified symbol of the market to fetch the ticker for
2599
2821
  :param dict [params]: extra parameters specific to the exchange API endpoint
2600
2822
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -2607,7 +2829,7 @@ class bitget(Exchange, ImplicitAPI):
2607
2829
  market = self.market(sandboxSymbol)
2608
2830
  else:
2609
2831
  market = self.market(symbol)
2610
- request = {
2832
+ request: dict = {
2611
2833
  'symbol': market['id'],
2612
2834
  }
2613
2835
  response = None
@@ -2681,16 +2903,51 @@ class bitget(Exchange, ImplicitAPI):
2681
2903
  # ]
2682
2904
  # }
2683
2905
  #
2684
- data = self.safe_value(response, 'data', [])
2906
+ data = self.safe_list(response, 'data', [])
2907
+ return self.parse_ticker(data[0], market)
2908
+
2909
+ async def fetch_mark_price(self, symbol: str, params={}) -> Ticker:
2910
+ """
2911
+ fetches the mark price for a specific market
2912
+
2913
+ https://www.bitget.com/api-doc/contract/market/Get-Symbol-Price
2914
+
2915
+ :param str symbol: unified symbol of the market to fetch the ticker for
2916
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2917
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
2918
+ """
2919
+ await self.load_markets()
2920
+ sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
2921
+ market = None
2922
+ if sandboxMode:
2923
+ sandboxSymbol = self.convert_symbol_for_sandbox(symbol)
2924
+ market = self.market(sandboxSymbol)
2925
+ else:
2926
+ market = self.market(symbol)
2927
+ request: dict = {
2928
+ 'symbol': market['id'],
2929
+ }
2930
+ response = None
2931
+ if market['spot']:
2932
+ raise NotSupported(self.id + ' fetchMarkPrice() is not supported for spot markets')
2933
+ else:
2934
+ productType = None
2935
+ productType, params = self.handle_product_type_and_params(market, params)
2936
+ request['productType'] = productType
2937
+ response = await self.publicMixGetV2MixMarketSymbolPrice(self.extend(request, params))
2938
+ data = self.safe_list(response, 'data', [])
2685
2939
  return self.parse_ticker(data[0], market)
2686
2940
 
2687
2941
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
2688
2942
  """
2689
2943
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
2690
- :see: https://www.bitget.com/api-doc/spot/market/Get-Tickers
2691
- :see: https://www.bitget.com/api-doc/contract/market/Get-All-Symbol-Ticker
2944
+
2945
+ https://www.bitget.com/api-doc/spot/market/Get-Tickers
2946
+ https://www.bitget.com/api-doc/contract/market/Get-All-Symbol-Ticker
2947
+
2692
2948
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
2693
2949
  :param dict [params]: extra parameters specific to the exchange API endpoint
2950
+ :param str [params.subType]: *contract only* 'linear', 'inverse'
2694
2951
  :param str [params.productType]: *contract only* 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES'
2695
2952
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
2696
2953
  """
@@ -2704,15 +2961,20 @@ class bitget(Exchange, ImplicitAPI):
2704
2961
  market = self.market(sandboxSymbol)
2705
2962
  else:
2706
2963
  market = self.market(symbol)
2707
- request = {}
2964
+ response = None
2965
+ request: dict = {}
2708
2966
  type = None
2709
2967
  type, params = self.handle_market_type_and_params('fetchTickers', market, params)
2710
- response = None
2711
- if type == 'spot':
2968
+ # Calls like `.fetchTickers(None, {subType:'inverse'})` should be supported for self exchange, so
2969
+ # as "options.defaultSubType" is also set in exchange options, we should consider `params.subType`
2970
+ # with higher priority and only default to spot, if `subType` is not set in params
2971
+ passedSubType = self.safe_string(params, 'subType')
2972
+ productType = None
2973
+ productType, params = self.handle_product_type_and_params(market, params)
2974
+ # only if passedSubType and productType is None, then use spot
2975
+ if type == 'spot' and passedSubType is None:
2712
2976
  response = await self.publicSpotGetV2SpotMarketTickers(self.extend(request, params))
2713
2977
  else:
2714
- productType = None
2715
- productType, params = self.handle_product_type_and_params(market, params)
2716
2978
  request['productType'] = productType
2717
2979
  response = await self.publicMixGetV2MixMarketTickers(self.extend(request, params))
2718
2980
  #
@@ -2772,10 +3034,10 @@ class bitget(Exchange, ImplicitAPI):
2772
3034
  # ]
2773
3035
  # }
2774
3036
  #
2775
- data = self.safe_value(response, 'data', [])
3037
+ data = self.safe_list(response, 'data', [])
2776
3038
  return self.parse_tickers(data, symbols)
2777
3039
 
2778
- def parse_trade(self, trade, market: Market = None) -> Trade:
3040
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
2779
3041
  #
2780
3042
  # spot, swap and future: fetchTrades
2781
3043
  #
@@ -2895,10 +3157,12 @@ class bitget(Exchange, ImplicitAPI):
2895
3157
  async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
2896
3158
  """
2897
3159
  get the list of most recent trades for a particular symbol
2898
- :see: https://www.bitget.com/api-doc/spot/market/Get-Recent-Trades
2899
- :see: https://www.bitget.com/api-doc/spot/market/Get-Market-Trades
2900
- :see: https://www.bitget.com/api-doc/contract/market/Get-Recent-Fills
2901
- :see: https://www.bitget.com/api-doc/contract/market/Get-Fills-History
3160
+
3161
+ https://www.bitget.com/api-doc/spot/market/Get-Recent-Trades
3162
+ https://www.bitget.com/api-doc/spot/market/Get-Market-Trades
3163
+ https://www.bitget.com/api-doc/contract/market/Get-Recent-Fills
3164
+ https://www.bitget.com/api-doc/contract/market/Get-Fills-History
3165
+
2902
3166
  :param str symbol: unified symbol of the market to fetch trades for
2903
3167
  :param int [since]: timestamp in ms of the earliest trade to fetch
2904
3168
  :param int [limit]: the maximum amount of trades to fetch
@@ -2919,7 +3183,7 @@ class bitget(Exchange, ImplicitAPI):
2919
3183
  market = self.market(sandboxSymbol)
2920
3184
  else:
2921
3185
  market = self.market(symbol)
2922
- request = {
3186
+ request: dict = {
2923
3187
  'symbol': market['id'],
2924
3188
  }
2925
3189
  if limit is not None:
@@ -2993,13 +3257,15 @@ class bitget(Exchange, ImplicitAPI):
2993
3257
  # ]
2994
3258
  # }
2995
3259
  #
2996
- data = self.safe_value(response, 'data', [])
3260
+ data = self.safe_list(response, 'data', [])
2997
3261
  return self.parse_trades(data, market, since, limit)
2998
3262
 
2999
- async def fetch_trading_fee(self, symbol: str, params={}):
3263
+ async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
3000
3264
  """
3001
3265
  fetch the trading fees for a market
3002
- :see: https://www.bitget.com/api-doc/common/public/Get-Trade-Rate
3266
+
3267
+ https://www.bitget.com/api-doc/common/public/Get-Trade-Rate
3268
+
3003
3269
  :param str symbol: unified market symbol
3004
3270
  :param dict [params]: extra parameters specific to the exchange API endpoint
3005
3271
  :param str [params.marginMode]: 'isolated' or 'cross', for finding the fee rate of spot margin trading pairs
@@ -3007,7 +3273,7 @@ class bitget(Exchange, ImplicitAPI):
3007
3273
  """
3008
3274
  await self.load_markets()
3009
3275
  market = self.market(symbol)
3010
- request = {
3276
+ request: dict = {
3011
3277
  'symbol': market['id'],
3012
3278
  }
3013
3279
  marginMode = None
@@ -3034,12 +3300,14 @@ class bitget(Exchange, ImplicitAPI):
3034
3300
  data = self.safe_value(response, 'data', {})
3035
3301
  return self.parse_trading_fee(data, market)
3036
3302
 
3037
- async def fetch_trading_fees(self, params={}):
3303
+ async def fetch_trading_fees(self, params={}) -> TradingFees:
3038
3304
  """
3039
3305
  fetch the trading fees for multiple markets
3040
- :see: https://www.bitget.com/api-doc/spot/market/Get-Symbols
3041
- :see: https://www.bitget.com/api-doc/contract/market/Get-All-Symbols-Contracts
3042
- :see: https://www.bitget.com/api-doc/margin/common/support-currencies
3306
+
3307
+ https://www.bitget.com/api-doc/spot/market/Get-Symbols
3308
+ https://www.bitget.com/api-doc/contract/market/Get-All-Symbols-Contracts
3309
+ https://www.bitget.com/api-doc/margin/common/support-currencies
3310
+
3043
3311
  :param dict [params]: extra parameters specific to the exchange API endpoint
3044
3312
  :param str [params.productType]: *contract only* 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES'
3045
3313
  :param boolean [params.margin]: set to True for spot margin
@@ -3137,7 +3405,7 @@ class bitget(Exchange, ImplicitAPI):
3137
3405
  # }
3138
3406
  #
3139
3407
  data = self.safe_value(response, 'data', [])
3140
- result = {}
3408
+ result: dict = {}
3141
3409
  for i in range(0, len(data)):
3142
3410
  entry = data[i]
3143
3411
  marketId = self.safe_string(entry, 'symbol')
@@ -3154,6 +3422,8 @@ class bitget(Exchange, ImplicitAPI):
3154
3422
  'symbol': self.safe_symbol(marketId, market),
3155
3423
  'maker': self.safe_number(data, 'makerFeeRate'),
3156
3424
  'taker': self.safe_number(data, 'takerFeeRate'),
3425
+ 'percentage': None,
3426
+ 'tierBased': None,
3157
3427
  }
3158
3428
 
3159
3429
  def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
@@ -3180,18 +3450,21 @@ class bitget(Exchange, ImplicitAPI):
3180
3450
  async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
3181
3451
  """
3182
3452
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
3183
- :see: https://www.bitget.com/api-doc/spot/market/Get-Candle-Data
3184
- :see: https://www.bitget.com/api-doc/spot/market/Get-History-Candle-Data
3185
- :see: https://www.bitget.com/api-doc/contract/market/Get-Candle-Data
3186
- :see: https://www.bitget.com/api-doc/contract/market/Get-History-Candle-Data
3187
- :see: https://www.bitget.com/api-doc/contract/market/Get-History-Index-Candle-Data
3188
- :see: https://www.bitget.com/api-doc/contract/market/Get-History-Mark-Candle-Data
3453
+
3454
+ https://www.bitget.com/api-doc/spot/market/Get-Candle-Data
3455
+ https://www.bitget.com/api-doc/spot/market/Get-History-Candle-Data
3456
+ https://www.bitget.com/api-doc/contract/market/Get-Candle-Data
3457
+ https://www.bitget.com/api-doc/contract/market/Get-History-Candle-Data
3458
+ https://www.bitget.com/api-doc/contract/market/Get-History-Index-Candle-Data
3459
+ https://www.bitget.com/api-doc/contract/market/Get-History-Mark-Candle-Data
3460
+
3189
3461
  :param str symbol: unified symbol of the market to fetch OHLCV data for
3190
3462
  :param str timeframe: the length of time each candle represents
3191
3463
  :param int [since]: timestamp in ms of the earliest candle to fetch
3192
3464
  :param int [limit]: the maximum amount of candles to fetch
3193
3465
  :param dict [params]: extra parameters specific to the exchange API endpoint
3194
3466
  :param int [params.until]: timestamp in ms of the latest candle to fetch
3467
+ :param boolean [params.useHistoryEndpoint]: whether to force to use historical endpoint(it has max limit of 200)
3195
3468
  :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
3196
3469
  :param str [params.price]: *swap only* "mark"(to fetch mark price candles) or "index"(to fetch index price candles)
3197
3470
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
@@ -3203,8 +3476,9 @@ class bitget(Exchange, ImplicitAPI):
3203
3476
  paginate = False
3204
3477
  paginate, params = self.handle_option_and_params(params, 'fetchOHLCV', 'paginate')
3205
3478
  if paginate:
3206
- return await self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimitForHistoryEndpoint)
3479
+ return await self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimitForRecentEndpoint)
3207
3480
  sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
3481
+ useHistoryEndpoint = self.safe_bool(params, 'useHistoryEndpoint', False)
3208
3482
  market = None
3209
3483
  if sandboxMode:
3210
3484
  sandboxSymbol = self.convert_symbol_for_sandbox(symbol)
@@ -3215,15 +3489,15 @@ class bitget(Exchange, ImplicitAPI):
3215
3489
  timeframes = self.options['timeframes'][marketType]
3216
3490
  msInDay = 86400000
3217
3491
  duration = self.parse_timeframe(timeframe) * 1000
3218
- request = {
3492
+ request: dict = {
3219
3493
  'symbol': market['id'],
3220
3494
  'granularity': self.safe_string(timeframes, timeframe, timeframe),
3221
3495
  }
3222
- until = self.safe_integer_2(params, 'until', 'till')
3496
+ until = self.safe_integer(params, 'until')
3223
3497
  limitDefined = limit is not None
3224
3498
  sinceDefined = since is not None
3225
3499
  untilDefined = until is not None
3226
- params = self.omit(params, ['until', 'till'])
3500
+ params = self.omit(params, ['until'])
3227
3501
  response = None
3228
3502
  now = self.milliseconds()
3229
3503
  # retrievable periods listed here:
@@ -3232,7 +3506,7 @@ class bitget(Exchange, ImplicitAPI):
3232
3506
  ohlcOptions = self.safe_dict(self.options, 'fetchOHLCV', {})
3233
3507
  retrievableDaysMap = self.safe_dict(ohlcOptions, 'maxDaysPerTimeframe', {})
3234
3508
  maxRetrievableDaysForRecent = self.safe_integer(retrievableDaysMap, timeframe, 30) # default to safe minimum
3235
- endpointTsBoundary = now - maxRetrievableDaysForRecent * msInDay
3509
+ endpointTsBoundary = now - (maxRetrievableDaysForRecent - 1) * msInDay
3236
3510
  if limitDefined:
3237
3511
  limit = min(limit, maxLimitForRecentEndpoint)
3238
3512
  request['limit'] = limit
@@ -3263,7 +3537,7 @@ class bitget(Exchange, ImplicitAPI):
3263
3537
  # make request
3264
3538
  if market['spot']:
3265
3539
  # checks if we need history endpoint
3266
- if historicalEndpointNeeded:
3540
+ if historicalEndpointNeeded or useHistoryEndpoint:
3267
3541
  response = await self.publicSpotGetV2SpotMarketHistoryCandles(self.extend(request, params))
3268
3542
  else:
3269
3543
  response = await self.publicSpotGetV2SpotMarketCandles(self.extend(request, params))
@@ -3287,7 +3561,7 @@ class bitget(Exchange, ImplicitAPI):
3287
3561
  elif priceType == 'index':
3288
3562
  response = await self.publicMixGetV2MixMarketHistoryIndexCandles(extended)
3289
3563
  else:
3290
- if historicalEndpointNeeded:
3564
+ if historicalEndpointNeeded or useHistoryEndpoint:
3291
3565
  response = await self.publicMixGetV2MixMarketHistoryCandles(extended)
3292
3566
  else:
3293
3567
  response = await self.publicMixGetV2MixMarketCandles(extended)
@@ -3300,18 +3574,20 @@ class bitget(Exchange, ImplicitAPI):
3300
3574
  async def fetch_balance(self, params={}) -> Balances:
3301
3575
  """
3302
3576
  query for balance and get the amount of funds available for trading or funds locked in orders
3303
- :see: https://www.bitget.com/api-doc/spot/account/Get-Account-Assets
3304
- :see: https://www.bitget.com/api-doc/contract/account/Get-Account-List
3305
- :see: https://www.bitget.com/api-doc/margin/cross/account/Get-Cross-Assets
3306
- :see: https://www.bitget.com/api-doc/margin/isolated/account/Get-Isolated-Assets
3307
- :see: https://bitgetlimited.github.io/apidoc/en/margin/#get-cross-assets
3308
- :see: https://bitgetlimited.github.io/apidoc/en/margin/#get-isolated-assets
3577
+
3578
+ https://www.bitget.com/api-doc/spot/account/Get-Account-Assets
3579
+ https://www.bitget.com/api-doc/contract/account/Get-Account-List
3580
+ https://www.bitget.com/api-doc/margin/cross/account/Get-Cross-Assets
3581
+ https://www.bitget.com/api-doc/margin/isolated/account/Get-Isolated-Assets
3582
+ https://bitgetlimited.github.io/apidoc/en/margin/#get-cross-assets
3583
+ https://bitgetlimited.github.io/apidoc/en/margin/#get-isolated-assets
3584
+
3309
3585
  :param dict [params]: extra parameters specific to the exchange API endpoint
3310
3586
  :param str [params.productType]: *contract only* 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES'
3311
3587
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
3312
3588
  """
3313
3589
  await self.load_markets()
3314
- request = {}
3590
+ request: dict = {}
3315
3591
  marketType = None
3316
3592
  marginMode = None
3317
3593
  response = None
@@ -3421,7 +3697,7 @@ class bitget(Exchange, ImplicitAPI):
3421
3697
  return self.parse_balance(data)
3422
3698
 
3423
3699
  def parse_balance(self, balance) -> Balances:
3424
- result = {'info': balance}
3700
+ result: dict = {'info': balance}
3425
3701
  #
3426
3702
  # spot
3427
3703
  #
@@ -3508,8 +3784,8 @@ class bitget(Exchange, ImplicitAPI):
3508
3784
  result[code] = account
3509
3785
  return self.safe_balance(result)
3510
3786
 
3511
- def parse_order_status(self, status):
3512
- statuses = {
3787
+ def parse_order_status(self, status: Str):
3788
+ statuses: dict = {
3513
3789
  'new': 'open',
3514
3790
  'init': 'open',
3515
3791
  'not_trigger': 'open',
@@ -3529,7 +3805,7 @@ class bitget(Exchange, ImplicitAPI):
3529
3805
  }
3530
3806
  return self.safe_string(statuses, status, status)
3531
3807
 
3532
- def parse_order(self, order, market: Market = None) -> Order:
3808
+ def parse_order(self, order: dict, market: Market = None) -> Order:
3533
3809
  #
3534
3810
  # createOrder, editOrder, closePosition
3535
3811
  #
@@ -3822,7 +4098,7 @@ class bitget(Exchange, ImplicitAPI):
3822
4098
  if feeCostString is not None:
3823
4099
  # swap
3824
4100
  fee = {
3825
- 'cost': self.parse_number(Precise.string_abs(feeCostString)),
4101
+ 'cost': self.parse_number(Precise.string_neg(feeCostString)),
3826
4102
  'currency': market['settle'],
3827
4103
  }
3828
4104
  feeDetail = self.safe_value(order, 'feeDetail')
@@ -3836,7 +4112,7 @@ class bitget(Exchange, ImplicitAPI):
3836
4112
  feeObject = feeValue
3837
4113
  break
3838
4114
  fee = {
3839
- 'cost': self.parse_number(Precise.string_abs(self.safe_string(feeObject, 'totalFee'))),
4115
+ 'cost': self.parse_number(Precise.string_neg(self.safe_string(feeObject, 'totalFee'))),
3840
4116
  'currency': self.safe_currency_code(self.safe_string(feeObject, 'feeCoinCode')),
3841
4117
  }
3842
4118
  postOnly = None
@@ -3894,7 +4170,6 @@ class bitget(Exchange, ImplicitAPI):
3894
4170
  'timeInForce': timeInForce,
3895
4171
  'postOnly': postOnly,
3896
4172
  'reduceOnly': reduceOnly,
3897
- 'stopPrice': self.safe_number(order, 'triggerPrice'),
3898
4173
  'triggerPrice': self.safe_number(order, 'triggerPrice'),
3899
4174
  'takeProfitPrice': self.safe_number_2(order, 'presetStopSurplusPrice', 'stopSurplusTriggerPrice'),
3900
4175
  'stopLossPrice': self.safe_number_2(order, 'presetStopLossPrice', 'stopLossTriggerPrice'),
@@ -3906,9 +4181,11 @@ class bitget(Exchange, ImplicitAPI):
3906
4181
  async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
3907
4182
  """
3908
4183
  create a market buy order by providing the symbol and cost
3909
- :see: https://www.bitget.com/api-doc/spot/trade/Place-Order
3910
- :see: https://www.bitget.com/api-doc/margin/cross/trade/Cross-Place-Order
3911
- :see: https://www.bitget.com/api-doc/margin/isolated/trade/Isolated-Place-Order
4184
+
4185
+ https://www.bitget.com/api-doc/spot/trade/Place-Order
4186
+ https://www.bitget.com/api-doc/margin/cross/trade/Cross-Place-Order
4187
+ https://www.bitget.com/api-doc/margin/isolated/trade/Isolated-Place-Order
4188
+
3912
4189
  :param str symbol: unified symbol of the market to create an order in
3913
4190
  :param float cost: how much you want to trade in units of the quote currency
3914
4191
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -3918,24 +4195,28 @@ class bitget(Exchange, ImplicitAPI):
3918
4195
  market = self.market(symbol)
3919
4196
  if not market['spot']:
3920
4197
  raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
3921
- params['createMarketBuyOrderRequiresPrice'] = False
3922
- return await self.create_order(symbol, 'market', 'buy', cost, None, params)
4198
+ req = {
4199
+ 'createMarketBuyOrderRequiresPrice': False,
4200
+ }
4201
+ return await self.create_order(symbol, 'market', 'buy', cost, None, self.extend(req, params))
3923
4202
 
3924
4203
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
3925
4204
  """
3926
4205
  create a trade order
3927
- :see: https://www.bitget.com/api-doc/spot/trade/Place-Order
3928
- :see: https://www.bitget.com/api-doc/spot/plan/Place-Plan-Order
3929
- :see: https://www.bitget.com/api-doc/contract/trade/Place-Order
3930
- :see: https://www.bitget.com/api-doc/contract/plan/Place-Tpsl-Order
3931
- :see: https://www.bitget.com/api-doc/contract/plan/Place-Plan-Order
3932
- :see: https://www.bitget.com/api-doc/margin/cross/trade/Cross-Place-Order
3933
- :see: https://www.bitget.com/api-doc/margin/isolated/trade/Isolated-Place-Order
4206
+
4207
+ https://www.bitget.com/api-doc/spot/trade/Place-Order
4208
+ https://www.bitget.com/api-doc/spot/plan/Place-Plan-Order
4209
+ https://www.bitget.com/api-doc/contract/trade/Place-Order
4210
+ https://www.bitget.com/api-doc/contract/plan/Place-Tpsl-Order
4211
+ https://www.bitget.com/api-doc/contract/plan/Place-Plan-Order
4212
+ https://www.bitget.com/api-doc/margin/cross/trade/Cross-Place-Order
4213
+ https://www.bitget.com/api-doc/margin/isolated/trade/Isolated-Place-Order
4214
+
3934
4215
  :param str symbol: unified symbol of the market to create an order in
3935
4216
  :param str type: 'market' or 'limit'
3936
4217
  :param str side: 'buy' or 'sell'
3937
4218
  :param float amount: how much you want to trade in units of the base currency
3938
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
4219
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
3939
4220
  :param dict [params]: extra parameters specific to the exchange API endpoint
3940
4221
  :param float [params.cost]: *spot only* how much you want to trade in units of the quote currency, for market buy orders only
3941
4222
  :param float [params.triggerPrice]: *swap only* The price at which a trigger order is triggered at
@@ -3957,6 +4238,8 @@ class bitget(Exchange, ImplicitAPI):
3957
4238
  :param str [params.trailingTriggerPrice]: *swap and future only* the price to trigger a trailing stop order, default uses the price argument
3958
4239
  :param str [params.triggerType]: *swap and future only* 'fill_price', 'mark_price' or 'index_price'
3959
4240
  :param boolean [params.oneWayMode]: *swap and future only* required to set self to True in one_way_mode and you can leave self in hedge_mode, can adjust the mode using the setPositionMode() method
4241
+ :param bool [params.hedged]: *swap and future only* True for hedged mode, False for one way mode, default is False
4242
+ :param bool [params.reduceOnly]: True or False whether the order is reduce-only
3960
4243
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3961
4244
  """
3962
4245
  await self.load_markets()
@@ -4001,7 +4284,7 @@ class bitget(Exchange, ImplicitAPI):
4001
4284
  # }
4002
4285
  # }
4003
4286
  #
4004
- data = self.safe_value(response, 'data', {})
4287
+ data = self.safe_dict(response, 'data', {})
4005
4288
  return self.parse_order(data, market)
4006
4289
 
4007
4290
  def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
@@ -4016,7 +4299,7 @@ class bitget(Exchange, ImplicitAPI):
4016
4299
  marginMode = None
4017
4300
  marketType, params = self.handle_market_type_and_params('createOrder', market, params)
4018
4301
  marginMode, params = self.handle_margin_mode_and_params('createOrder', params)
4019
- request = {
4302
+ request: dict = {
4020
4303
  'symbol': market['id'],
4021
4304
  'orderType': type,
4022
4305
  }
@@ -4040,7 +4323,7 @@ class bitget(Exchange, ImplicitAPI):
4040
4323
  raise ExchangeError(self.id + ' createOrder() params can only contain one of triggerPrice, stopLossPrice, takeProfitPrice, trailingPercent')
4041
4324
  if type == 'limit':
4042
4325
  request['price'] = self.price_to_precision(symbol, price)
4043
- triggerType = self.safe_string(params, 'triggerType', 'mark_price')
4326
+ triggerPriceType = self.safe_string_2(params, 'triggerPriceType', 'triggerType', 'mark_price')
4044
4327
  reduceOnly = self.safe_bool(params, 'reduceOnly', False)
4045
4328
  clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId')
4046
4329
  exchangeSpecificTifParam = self.safe_string_2(params, 'force', 'timeInForce')
@@ -4066,7 +4349,7 @@ class bitget(Exchange, ImplicitAPI):
4066
4349
  if clientOrderId is not None:
4067
4350
  request['clientOid'] = clientOrderId
4068
4351
  if isTriggerOrder or isStopLossOrTakeProfitTrigger or isTrailingPercentOrder:
4069
- request['triggerType'] = triggerType
4352
+ request['triggerType'] = triggerPriceType
4070
4353
  if isTrailingPercentOrder:
4071
4354
  if not isMarketOrder:
4072
4355
  raise BadRequest(self.id + ' createOrder() bitget trailing orders must be market orders')
@@ -4116,18 +4399,23 @@ class bitget(Exchange, ImplicitAPI):
4116
4399
  marginMode = 'cross'
4117
4400
  marginModeRequest = 'crossed' if (marginMode == 'cross') else 'isolated'
4118
4401
  request['marginMode'] = marginModeRequest
4119
- oneWayMode = self.safe_bool(params, 'oneWayMode', False)
4120
- params = self.omit(params, 'oneWayMode')
4402
+ hedged = None
4403
+ hedged, params = self.handle_param_bool(params, 'hedged', False)
4404
+ # backward compatibility for `oneWayMode`
4405
+ oneWayMode = None
4406
+ oneWayMode, params = self.handle_param_bool(params, 'oneWayMode')
4407
+ if oneWayMode is not None:
4408
+ hedged = not oneWayMode
4121
4409
  requestSide = side
4122
4410
  if reduceOnly:
4123
- if oneWayMode:
4411
+ if not hedged:
4124
4412
  request['reduceOnly'] = 'YES'
4125
4413
  else:
4126
4414
  # on bitget hedge mode if the position is long the side is always buy, and if the position is short the side is always sell
4127
4415
  requestSide = 'sell' if (side == 'buy') else 'buy'
4128
4416
  request['tradeSide'] = 'Close'
4129
4417
  else:
4130
- if not oneWayMode:
4418
+ if hedged:
4131
4419
  request['tradeSide'] = 'Open'
4132
4420
  request['side'] = requestSide
4133
4421
  elif marketType == 'spot':
@@ -4161,7 +4449,7 @@ class bitget(Exchange, ImplicitAPI):
4161
4449
  request['clientOid'] = clientOrderId
4162
4450
  if marginMode is not None:
4163
4451
  request['loanType'] = 'normal'
4164
- if createMarketBuyOrderRequiresPrice and isMarketOrder and (side == 'buy'):
4452
+ if isMarketOrder and (side == 'buy'):
4165
4453
  request['quoteSize'] = quantity
4166
4454
  else:
4167
4455
  request['baseSize'] = quantity
@@ -4170,7 +4458,7 @@ class bitget(Exchange, ImplicitAPI):
4170
4458
  request['size'] = quantity
4171
4459
  if triggerPrice is not None:
4172
4460
  request['planType'] = planType
4173
- request['triggerType'] = triggerType
4461
+ request['triggerType'] = triggerPriceType
4174
4462
  request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
4175
4463
  if price is not None:
4176
4464
  request['executePrice'] = self.price_to_precision(symbol, price)
@@ -4181,10 +4469,12 @@ class bitget(Exchange, ImplicitAPI):
4181
4469
  async def create_orders(self, orders: List[OrderRequest], params={}):
4182
4470
  """
4183
4471
  create a list of trade orders(all orders should be of the same symbol)
4184
- :see: https://www.bitget.com/api-doc/spot/trade/Batch-Place-Orders
4185
- :see: https://www.bitget.com/api-doc/contract/trade/Batch-Order
4186
- :see: https://www.bitget.com/api-doc/margin/isolated/trade/Isolated-Batch-Order
4187
- :see: https://www.bitget.com/api-doc/margin/cross/trade/Cross-Batch-Order
4472
+
4473
+ https://www.bitget.com/api-doc/spot/trade/Batch-Place-Orders
4474
+ https://www.bitget.com/api-doc/contract/trade/Batch-Order
4475
+ https://www.bitget.com/api-doc/margin/isolated/trade/Isolated-Batch-Order
4476
+ https://www.bitget.com/api-doc/margin/cross/trade/Cross-Batch-Order
4477
+
4188
4478
  :param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
4189
4479
  :param dict [params]: extra parameters specific to the api endpoint
4190
4480
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -4223,7 +4513,7 @@ class bitget(Exchange, ImplicitAPI):
4223
4513
  market = self.market(sandboxSymbol)
4224
4514
  else:
4225
4515
  market = self.market(symbol)
4226
- request = {
4516
+ request: dict = {
4227
4517
  'symbol': market['id'],
4228
4518
  'orderList': ordersRequests,
4229
4519
  }
@@ -4276,16 +4566,18 @@ class bitget(Exchange, ImplicitAPI):
4276
4566
  async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
4277
4567
  """
4278
4568
  edit a trade order
4279
- :see: https://www.bitget.com/api-doc/spot/plan/Modify-Plan-Order
4280
- :see: https://www.bitget.com/api-doc/contract/trade/Modify-Order
4281
- :see: https://www.bitget.com/api-doc/contract/plan/Modify-Tpsl-Order
4282
- :see: https://www.bitget.com/api-doc/contract/plan/Modify-Plan-Order
4569
+
4570
+ https://www.bitget.com/api-doc/spot/plan/Modify-Plan-Order
4571
+ https://www.bitget.com/api-doc/contract/trade/Modify-Order
4572
+ https://www.bitget.com/api-doc/contract/plan/Modify-Tpsl-Order
4573
+ https://www.bitget.com/api-doc/contract/plan/Modify-Plan-Order
4574
+
4283
4575
  :param str id: cancel order id
4284
4576
  :param str symbol: unified symbol of the market to create an order in
4285
4577
  :param str type: 'market' or 'limit'
4286
4578
  :param str side: 'buy' or 'sell'
4287
4579
  :param float amount: how much you want to trade in units of the base currency
4288
- :param float [price]: the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
4580
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
4289
4581
  :param dict [params]: extra parameters specific to the exchange API endpoint
4290
4582
  :param float [params.triggerPrice]: the price that a trigger order is triggered at
4291
4583
  :param float [params.stopLossPrice]: *swap only* The price at which a stop loss order is triggered at
@@ -4311,7 +4603,7 @@ class bitget(Exchange, ImplicitAPI):
4311
4603
  market = self.market(sandboxSymbol)
4312
4604
  else:
4313
4605
  market = self.market(symbol)
4314
- request = {
4606
+ request: dict = {
4315
4607
  'orderId': id,
4316
4608
  }
4317
4609
  isMarketOrder = type == 'market'
@@ -4336,6 +4628,8 @@ class bitget(Exchange, ImplicitAPI):
4336
4628
  params = self.omit(params, ['stopPrice', 'triggerType', 'stopLossPrice', 'takeProfitPrice', 'stopLoss', 'takeProfit', 'clientOrderId', 'trailingTriggerPrice', 'trailingPercent'])
4337
4629
  response = None
4338
4630
  if market['spot']:
4631
+ if triggerPrice is None:
4632
+ raise NotSupported(self.id + 'editOrder() only supports plan/trigger spot orders')
4339
4633
  editMarketBuyOrderRequiresPrice = self.safe_bool(self.options, 'editMarketBuyOrderRequiresPrice', True)
4340
4634
  if editMarketBuyOrderRequiresPrice and isMarketOrder and (side == 'buy'):
4341
4635
  if price is None:
@@ -4418,23 +4712,25 @@ class bitget(Exchange, ImplicitAPI):
4418
4712
  # }
4419
4713
  # }
4420
4714
  #
4421
- data = self.safe_value(response, 'data', {})
4715
+ data = self.safe_dict(response, 'data', {})
4422
4716
  return self.parse_order(data, market)
4423
4717
 
4424
4718
  async def cancel_order(self, id: str, symbol: Str = None, params={}):
4425
4719
  """
4426
4720
  cancels an open order
4427
- :see: https://www.bitget.com/api-doc/spot/trade/Cancel-Order
4428
- :see: https://www.bitget.com/api-doc/spot/plan/Cancel-Plan-Order
4429
- :see: https://www.bitget.com/api-doc/contract/trade/Cancel-Order
4430
- :see: https://www.bitget.com/api-doc/contract/plan/Cancel-Plan-Order
4431
- :see: https://www.bitget.com/api-doc/margin/cross/trade/Cross-Cancel-Order
4432
- :see: https://www.bitget.com/api-doc/margin/isolated/trade/Isolated-Cancel-Order
4721
+
4722
+ https://www.bitget.com/api-doc/spot/trade/Cancel-Order
4723
+ https://www.bitget.com/api-doc/spot/plan/Cancel-Plan-Order
4724
+ https://www.bitget.com/api-doc/contract/trade/Cancel-Order
4725
+ https://www.bitget.com/api-doc/contract/plan/Cancel-Plan-Order
4726
+ https://www.bitget.com/api-doc/margin/cross/trade/Cross-Cancel-Order
4727
+ https://www.bitget.com/api-doc/margin/isolated/trade/Isolated-Cancel-Order
4728
+
4433
4729
  :param str id: order id
4434
4730
  :param str symbol: unified symbol of the market the order was made in
4435
4731
  :param dict [params]: extra parameters specific to the exchange API endpoint
4436
4732
  :param str [params.marginMode]: 'isolated' or 'cross' for spot margin trading
4437
- :param boolean [params.stop]: set to True for canceling trigger orders
4733
+ :param boolean [params.trigger]: set to True for canceling trigger orders
4438
4734
  :param str [params.planType]: *swap only* either profit_plan, loss_plan, normal_plan, pos_profit, pos_loss, moving_plan or track_plan
4439
4735
  :param boolean [params.trailing]: set to True if you want to cancel a trailing order
4440
4736
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -4452,21 +4748,21 @@ class bitget(Exchange, ImplicitAPI):
4452
4748
  marginMode = None
4453
4749
  response = None
4454
4750
  marginMode, params = self.handle_margin_mode_and_params('cancelOrder', params)
4455
- request = {}
4751
+ request: dict = {}
4456
4752
  trailing = self.safe_value(params, 'trailing')
4457
- stop = self.safe_value_2(params, 'stop', 'trigger')
4753
+ trigger = self.safe_value_2(params, 'stop', 'trigger')
4458
4754
  params = self.omit(params, ['stop', 'trigger', 'trailing'])
4459
- if not (market['spot'] and stop):
4755
+ if not (market['spot'] and trigger):
4460
4756
  request['symbol'] = market['id']
4461
- if not ((market['swap'] or market['future']) and stop):
4757
+ if not ((market['swap'] or market['future']) and trigger):
4462
4758
  request['orderId'] = id
4463
4759
  if (market['swap']) or (market['future']):
4464
4760
  productType = None
4465
4761
  productType, params = self.handle_product_type_and_params(market, params)
4466
4762
  request['productType'] = productType
4467
- if stop or trailing:
4763
+ if trigger or trailing:
4468
4764
  orderIdList = []
4469
- orderId = {
4765
+ orderId: dict = {
4470
4766
  'orderId': id,
4471
4767
  }
4472
4768
  orderIdList.append(orderId)
@@ -4475,7 +4771,7 @@ class bitget(Exchange, ImplicitAPI):
4475
4771
  planType = self.safe_string(params, 'planType', 'track_plan')
4476
4772
  request['planType'] = planType
4477
4773
  response = await self.privateMixPostV2MixOrderCancelPlanOrder(self.extend(request, params))
4478
- elif stop:
4774
+ elif trigger:
4479
4775
  response = await self.privateMixPostV2MixOrderCancelPlanOrder(self.extend(request, params))
4480
4776
  else:
4481
4777
  response = await self.privateMixPostV2MixOrderCancelOrder(self.extend(request, params))
@@ -4486,7 +4782,7 @@ class bitget(Exchange, ImplicitAPI):
4486
4782
  elif marginMode == 'cross':
4487
4783
  response = await self.privateMarginPostV2MarginCrossedCancelOrder(self.extend(request, params))
4488
4784
  else:
4489
- if stop:
4785
+ if trigger:
4490
4786
  response = await self.privateSpotPostV2SpotTradeCancelPlanOrder(self.extend(request, params))
4491
4787
  else:
4492
4788
  response = await self.privateSpotPostV2SpotTradeCancelOrder(self.extend(request, params))
@@ -4535,7 +4831,7 @@ class bitget(Exchange, ImplicitAPI):
4535
4831
  #
4536
4832
  data = self.safe_value(response, 'data', {})
4537
4833
  order = None
4538
- if (market['swap'] or market['future']) and stop:
4834
+ if (market['swap'] or market['future']) and trigger:
4539
4835
  orderInfo = self.safe_value(data, 'successList', [])
4540
4836
  order = orderInfo[0]
4541
4837
  else:
@@ -4545,16 +4841,18 @@ class bitget(Exchange, ImplicitAPI):
4545
4841
  async def cancel_orders(self, ids, symbol: Str = None, params={}):
4546
4842
  """
4547
4843
  cancel multiple orders
4548
- :see: https://www.bitget.com/api-doc/spot/trade/Batch-Cancel-Orders
4549
- :see: https://www.bitget.com/api-doc/contract/trade/Batch-Cancel-Orders
4550
- :see: https://www.bitget.com/api-doc/contract/plan/Cancel-Plan-Order
4551
- :see: https://www.bitget.com/api-doc/margin/cross/trade/Cross-Batch-Cancel-Order
4552
- :see: https://www.bitget.com/api-doc/margin/isolated/trade/Isolated-Batch-Cancel-Orders
4844
+
4845
+ https://www.bitget.com/api-doc/spot/trade/Batch-Cancel-Orders
4846
+ https://www.bitget.com/api-doc/contract/trade/Batch-Cancel-Orders
4847
+ https://www.bitget.com/api-doc/contract/plan/Cancel-Plan-Order
4848
+ https://www.bitget.com/api-doc/margin/cross/trade/Cross-Batch-Cancel-Order
4849
+ https://www.bitget.com/api-doc/margin/isolated/trade/Isolated-Batch-Cancel-Orders
4850
+
4553
4851
  :param str[] ids: order ids
4554
4852
  :param str symbol: unified market symbol, default is None
4555
4853
  :param dict [params]: extra parameters specific to the exchange API endpoint
4556
4854
  :param str [params.marginMode]: 'isolated' or 'cross' for spot margin trading
4557
- :param boolean [params.stop]: *contract only* set to True for canceling trigger orders
4855
+ :param boolean [params.trigger]: *contract only* set to True for canceling trigger orders
4558
4856
  :returns dict: an array of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4559
4857
  """
4560
4858
  if symbol is None:
@@ -4569,16 +4867,16 @@ class bitget(Exchange, ImplicitAPI):
4569
4867
  market = self.market(symbol)
4570
4868
  marginMode = None
4571
4869
  marginMode, params = self.handle_margin_mode_and_params('cancelOrders', params)
4572
- stop = self.safe_value_2(params, 'stop', 'trigger')
4870
+ trigger = self.safe_value_2(params, 'stop', 'trigger')
4573
4871
  params = self.omit(params, ['stop', 'trigger'])
4574
4872
  orderIdList = []
4575
4873
  for i in range(0, len(ids)):
4576
4874
  individualId = ids[i]
4577
- orderId = {
4875
+ orderId: dict = {
4578
4876
  'orderId': individualId,
4579
4877
  }
4580
4878
  orderIdList.append(orderId)
4581
- request = {
4879
+ request: dict = {
4582
4880
  'symbol': market['id'],
4583
4881
  }
4584
4882
  if market['spot'] and (marginMode is None):
@@ -4598,7 +4896,7 @@ class bitget(Exchange, ImplicitAPI):
4598
4896
  productType = None
4599
4897
  productType, params = self.handle_product_type_and_params(market, params)
4600
4898
  request['productType'] = productType
4601
- if stop:
4899
+ if trigger:
4602
4900
  response = await self.privateMixPostV2MixOrderCancelPlanOrder(self.extend(request, params))
4603
4901
  else:
4604
4902
  response = await self.privateMixPostV2MixOrderBatchCancelOrders(self.extend(request, params))
@@ -4619,21 +4917,23 @@ class bitget(Exchange, ImplicitAPI):
4619
4917
  # }
4620
4918
  #
4621
4919
  data = self.safe_value(response, 'data', {})
4622
- orders = self.safe_value(data, 'successList', [])
4920
+ orders = self.safe_list(data, 'successList', [])
4623
4921
  return self.parse_orders(orders, market)
4624
4922
 
4625
4923
  async def cancel_all_orders(self, symbol: Str = None, params={}):
4626
4924
  """
4627
4925
  cancel all open orders
4628
- :see: https://www.bitget.com/api-doc/spot/trade/Cancel-Symbol-Orders
4629
- :see: https://www.bitget.com/api-doc/spot/plan/Batch-Cancel-Plan-Order
4630
- :see: https://www.bitget.com/api-doc/contract/trade/Batch-Cancel-Orders
4631
- :see: https://bitgetlimited.github.io/apidoc/en/margin/#isolated-batch-cancel-orders
4632
- :see: https://bitgetlimited.github.io/apidoc/en/margin/#cross-batch-cancel-order
4926
+
4927
+ https://www.bitget.com/api-doc/spot/trade/Cancel-Symbol-Orders
4928
+ https://www.bitget.com/api-doc/spot/plan/Batch-Cancel-Plan-Order
4929
+ https://www.bitget.com/api-doc/contract/trade/Batch-Cancel-Orders
4930
+ https://bitgetlimited.github.io/apidoc/en/margin/#isolated-batch-cancel-orders
4931
+ https://bitgetlimited.github.io/apidoc/en/margin/#cross-batch-cancel-order
4932
+
4633
4933
  :param str symbol: unified market symbol
4634
4934
  :param dict [params]: extra parameters specific to the exchange API endpoint
4635
4935
  :param str [params.marginMode]: 'isolated' or 'cross' for spot margin trading
4636
- :param boolean [params.stop]: *contract only* set to True for canceling trigger orders
4936
+ :param boolean [params.trigger]: *contract only* set to True for canceling trigger orders
4637
4937
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4638
4938
  """
4639
4939
  if symbol is None:
@@ -4648,10 +4948,10 @@ class bitget(Exchange, ImplicitAPI):
4648
4948
  market = self.market(symbol)
4649
4949
  marginMode = None
4650
4950
  marginMode, params = self.handle_margin_mode_and_params('cancelAllOrders', params)
4651
- request = {
4951
+ request: dict = {
4652
4952
  'symbol': market['id'],
4653
4953
  }
4654
- stop = self.safe_bool_2(params, 'stop', 'trigger')
4954
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
4655
4955
  params = self.omit(params, ['stop', 'trigger'])
4656
4956
  response = None
4657
4957
  if market['spot']:
@@ -4660,103 +4960,115 @@ class bitget(Exchange, ImplicitAPI):
4660
4960
  response = await self.privateMarginPostMarginV1CrossOrderBatchCancelOrder(self.extend(request, params))
4661
4961
  else:
4662
4962
  response = await self.privateMarginPostMarginV1IsolatedOrderBatchCancelOrder(self.extend(request, params))
4963
+ #
4964
+ # {
4965
+ # "code": "00000",
4966
+ # "msg": "success",
4967
+ # "requestTime": 1700717155622,
4968
+ # "data": {
4969
+ # "resultList": [
4970
+ # {
4971
+ # "orderId": "1111453253721796609",
4972
+ # "clientOid": "2ae7fc8a4ff949b6b60d770ca3950e2d"
4973
+ # },
4974
+ # ],
4975
+ # "failure": []
4976
+ # }
4977
+ # }
4978
+ #
4663
4979
  else:
4664
- if stop:
4665
- stopRequest = {
4980
+ if trigger:
4981
+ stopRequest: dict = {
4666
4982
  'symbolList': [market['id']],
4667
4983
  }
4668
4984
  response = await self.privateSpotPostV2SpotTradeBatchCancelPlanOrder(self.extend(stopRequest, params))
4669
4985
  else:
4670
4986
  response = await self.privateSpotPostV2SpotTradeCancelSymbolOrder(self.extend(request, params))
4987
+ #
4988
+ # {
4989
+ # "code": "00000",
4990
+ # "msg": "success",
4991
+ # "requestTime": 1700716953996,
4992
+ # "data": {
4993
+ # "symbol": "BTCUSDT"
4994
+ # }
4995
+ # }
4996
+ #
4997
+ timestamp = self.safe_integer(response, 'requestTime')
4998
+ responseData = self.safe_dict(response, 'data')
4999
+ marketId = self.safe_string(responseData, 'symbol')
5000
+ return [
5001
+ self.safe_order({
5002
+ 'info': response,
5003
+ 'symbol': self.safe_symbol(marketId, None, None, 'spot'),
5004
+ 'timestamp': timestamp,
5005
+ 'datetime': self.iso8601(timestamp),
5006
+ }),
5007
+ ]
4671
5008
  else:
4672
5009
  productType = None
4673
5010
  productType, params = self.handle_product_type_and_params(market, params)
4674
5011
  request['productType'] = productType
4675
- if stop:
5012
+ if trigger:
4676
5013
  response = await self.privateMixPostV2MixOrderCancelPlanOrder(self.extend(request, params))
4677
5014
  else:
4678
5015
  response = await self.privateMixPostV2MixOrderBatchCancelOrders(self.extend(request, params))
4679
- #
4680
- # spot
4681
- #
4682
- # {
4683
- # "code": "00000",
4684
- # "msg": "success",
4685
- # "requestTime": 1700716953996,
4686
- # "data": {
4687
- # "symbol": "BTCUSDT"
4688
- # }
4689
- # }
4690
- #
4691
- # swap
4692
- #
4693
- # {
4694
- # "code": "00000",
4695
- # "msg": "success",
4696
- # "requestTime": "1680008815965",
4697
- # "data": {
4698
- # "successList": [
4699
- # {
4700
- # "orderId": "1024598257429823488",
4701
- # "clientOid": "876493ce-c287-4bfc-9f4a-8b1905881313"
4702
- # },
4703
- # ],
4704
- # "failureList": []
4705
- # }
4706
- # }
4707
- #
4708
- # spot margin
4709
- #
4710
- # {
4711
- # "code": "00000",
4712
- # "msg": "success",
4713
- # "requestTime": 1700717155622,
4714
- # "data": {
4715
- # "resultList": [
4716
- # {
4717
- # "orderId": "1111453253721796609",
4718
- # "clientOid": "2ae7fc8a4ff949b6b60d770ca3950e2d"
4719
- # },
4720
- # ],
4721
- # "failure": []
4722
- # }
4723
- # }
4724
- #
4725
- return response
4726
-
4727
- async def fetch_order(self, id: str, symbol: Str = None, params={}):
4728
- """
4729
- fetches information on an order made by the user
4730
- :see: https://www.bitget.com/api-doc/spot/trade/Get-Order-Info
4731
- :see: https://www.bitget.com/api-doc/contract/trade/Get-Order-Details
4732
- :param str symbol: unified symbol of the market the order was made in
4733
- :param dict [params]: extra parameters specific to the exchange API endpoint
4734
- :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4735
- """
4736
- if symbol is None:
4737
- raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
4738
- await self.load_markets()
4739
- sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
4740
- market = None
4741
- if sandboxMode:
4742
- sandboxSymbol = self.convert_symbol_for_sandbox(symbol)
4743
- market = self.market(sandboxSymbol)
4744
- else:
4745
- market = self.market(symbol)
4746
- request = {
4747
- 'orderId': id,
4748
- }
4749
- response = None
4750
- if market['spot']:
4751
- response = await self.privateSpotGetV2SpotTradeOrderInfo(self.extend(request, params))
4752
- elif market['swap'] or market['future']:
4753
- request['symbol'] = market['id']
4754
- productType = None
4755
- productType, params = self.handle_product_type_and_params(market, params)
4756
- request['productType'] = productType
4757
- response = await self.privateMixGetV2MixOrderDetail(self.extend(request, params))
4758
- else:
4759
- raise NotSupported(self.id + ' fetchOrder() does not support ' + market['type'] + ' orders')
5016
+ # {
5017
+ # "code": "00000",
5018
+ # "msg": "success",
5019
+ # "requestTime": "1680008815965",
5020
+ # "data": {
5021
+ # "successList": [
5022
+ # {
5023
+ # "orderId": "1024598257429823488",
5024
+ # "clientOid": "876493ce-c287-4bfc-9f4a-8b1905881313"
5025
+ # },
5026
+ # ],
5027
+ # "failureList": []
5028
+ # }
5029
+ # }
5030
+ data = self.safe_dict(response, 'data')
5031
+ resultList = self.safe_list_2(data, 'resultList', 'successList')
5032
+ failureList = self.safe_list_2(data, 'failure', 'failureList')
5033
+ responseList = self.array_concat(resultList, failureList)
5034
+ return self.parse_orders(responseList)
5035
+
5036
+ async def fetch_order(self, id: str, symbol: Str = None, params={}):
5037
+ """
5038
+ fetches information on an order made by the user
5039
+
5040
+ https://www.bitget.com/api-doc/spot/trade/Get-Order-Info
5041
+ https://www.bitget.com/api-doc/contract/trade/Get-Order-Details
5042
+
5043
+ :param str id: the order id
5044
+ :param str symbol: unified symbol of the market the order was made in
5045
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5046
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
5047
+ """
5048
+ if symbol is None:
5049
+ raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
5050
+ await self.load_markets()
5051
+ sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
5052
+ market = None
5053
+ if sandboxMode:
5054
+ sandboxSymbol = self.convert_symbol_for_sandbox(symbol)
5055
+ market = self.market(sandboxSymbol)
5056
+ else:
5057
+ market = self.market(symbol)
5058
+ request: dict = {
5059
+ 'orderId': id,
5060
+ }
5061
+ response = None
5062
+ if market['spot']:
5063
+ response = await self.privateSpotGetV2SpotTradeOrderInfo(self.extend(request, params))
5064
+ elif market['swap'] or market['future']:
5065
+ request['symbol'] = market['id']
5066
+ productType = None
5067
+ productType, params = self.handle_product_type_and_params(market, params)
5068
+ request['productType'] = productType
5069
+ response = await self.privateMixGetV2MixOrderDetail(self.extend(request, params))
5070
+ else:
5071
+ raise NotSupported(self.id + ' fetchOrder() does not support ' + market['type'] + ' orders')
4760
5072
  #
4761
5073
  # spot
4762
5074
  #
@@ -4826,26 +5138,34 @@ class bitget(Exchange, ImplicitAPI):
4826
5138
  #
4827
5139
  if isinstance(response, str):
4828
5140
  response = json.loads(response)
4829
- data = self.safe_value(response, 'data')
4830
- first = self.safe_value(data, 0, data)
5141
+ data = self.safe_dict(response, 'data')
5142
+ if (data is not None):
5143
+ if not isinstance(data, list):
5144
+ return self.parse_order(data, market)
5145
+ dataList = self.safe_list(response, 'data', [])
5146
+ first = self.safe_dict(dataList, 0, {})
4831
5147
  return self.parse_order(first, market)
5148
+ # first = self.safe_dict(data, 0, data)
5149
+ # return self.parse_order(first, market)
4832
5150
 
4833
5151
  async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
4834
5152
  """
4835
5153
  fetch all unfilled currently open orders
4836
- :see: https://www.bitget.com/api-doc/spot/trade/Get-Unfilled-Orders
4837
- :see: https://www.bitget.com/api-doc/spot/plan/Get-Current-Plan-Order
4838
- :see: https://www.bitget.com/api-doc/contract/trade/Get-Orders-Pending
4839
- :see: https://www.bitget.com/api-doc/contract/plan/get-orders-plan-pending
4840
- :see: https://www.bitget.com/api-doc/margin/cross/trade/Get-Cross-Open-Orders
4841
- :see: https://www.bitget.com/api-doc/margin/isolated/trade/Isolated-Open-Orders
5154
+
5155
+ https://www.bitget.com/api-doc/spot/trade/Get-Unfilled-Orders
5156
+ https://www.bitget.com/api-doc/spot/plan/Get-Current-Plan-Order
5157
+ https://www.bitget.com/api-doc/contract/trade/Get-Orders-Pending
5158
+ https://www.bitget.com/api-doc/contract/plan/get-orders-plan-pending
5159
+ https://www.bitget.com/api-doc/margin/cross/trade/Get-Cross-Open-Orders
5160
+ https://www.bitget.com/api-doc/margin/isolated/trade/Isolated-Open-Orders
5161
+
4842
5162
  :param str symbol: unified market symbol
4843
5163
  :param int [since]: the earliest time in ms to fetch open orders for
4844
5164
  :param int [limit]: the maximum number of open order structures to retrieve
4845
5165
  :param dict [params]: extra parameters specific to the exchange API endpoint
4846
5166
  :param int [params.until]: the latest time in ms to fetch orders for
4847
5167
  :param str [params.planType]: *contract stop only* 'normal_plan': average trigger order, 'profit_loss': opened tp/sl orders, 'track_plan': trailing stop order, default is 'normal_plan'
4848
- :param boolean [params.stop]: set to True for fetching trigger orders
5168
+ :param boolean [params.trigger]: set to True for fetching trigger orders
4849
5169
  :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
4850
5170
  :param str [params.isPlan]: *swap only* 'plan' for stop orders and 'profit_loss' for tp/sl orders, default is 'plan'
4851
5171
  :param boolean [params.trailing]: set to True if you want to fetch trailing orders
@@ -4855,7 +5175,7 @@ class bitget(Exchange, ImplicitAPI):
4855
5175
  sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
4856
5176
  market = None
4857
5177
  type = None
4858
- request = {}
5178
+ request: dict = {}
4859
5179
  marginMode = None
4860
5180
  marginMode, params = self.handle_margin_mode_and_params('fetchOpenOrders', params)
4861
5181
  if symbol is not None:
@@ -4883,9 +5203,9 @@ class bitget(Exchange, ImplicitAPI):
4883
5203
  return await self.fetch_paginated_call_cursor('fetchOpenOrders', symbol, since, limit, params, cursorReceived, 'idLessThan')
4884
5204
  response = None
4885
5205
  trailing = self.safe_bool(params, 'trailing')
4886
- stop = self.safe_bool_2(params, 'stop', 'trigger')
5206
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
4887
5207
  planTypeDefined = self.safe_string(params, 'planType') is not None
4888
- isStop = (stop or planTypeDefined)
5208
+ isTrigger = (trigger or planTypeDefined)
4889
5209
  params = self.omit(params, ['stop', 'trigger', 'trailing'])
4890
5210
  request, params = self.handle_until_option('endTime', request, params)
4891
5211
  if since is not None:
@@ -4909,7 +5229,7 @@ class bitget(Exchange, ImplicitAPI):
4909
5229
  elif marginMode == 'cross':
4910
5230
  response = await self.privateMarginGetV2MarginCrossedOpenOrders(self.extend(request, query))
4911
5231
  else:
4912
- if stop:
5232
+ if trigger:
4913
5233
  response = await self.privateSpotGetV2SpotTradeCurrentPlanOrder(self.extend(request, query))
4914
5234
  else:
4915
5235
  response = await self.privateSpotGetV2SpotTradeUnfilledOrders(self.extend(request, query))
@@ -4921,7 +5241,7 @@ class bitget(Exchange, ImplicitAPI):
4921
5241
  planType = self.safe_string(params, 'planType', 'track_plan')
4922
5242
  request['planType'] = planType
4923
5243
  response = await self.privateMixGetV2MixOrderOrdersPlanPending(self.extend(request, query))
4924
- elif isStop:
5244
+ elif isTrigger:
4925
5245
  planType = self.safe_string(query, 'planType', 'normal_plan')
4926
5246
  request['planType'] = planType
4927
5247
  response = await self.privateMixGetV2MixOrderOrdersPlanPending(self.extend(request, query))
@@ -5104,23 +5424,25 @@ class bitget(Exchange, ImplicitAPI):
5104
5424
  #
5105
5425
  data = self.safe_value(response, 'data')
5106
5426
  if type == 'spot':
5107
- if (marginMode is not None) or stop:
5108
- resultList = self.safe_value(data, 'orderList', [])
5427
+ if (marginMode is not None) or trigger:
5428
+ resultList = self.safe_list(data, 'orderList', [])
5109
5429
  return self.parse_orders(resultList, market, since, limit)
5110
5430
  else:
5111
- result = self.safe_value(data, 'entrustedList', [])
5431
+ result = self.safe_list(data, 'entrustedList', [])
5112
5432
  return self.parse_orders(result, market, since, limit)
5113
5433
  return self.parse_orders(data, market, since, limit)
5114
5434
 
5115
5435
  async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
5116
5436
  """
5117
5437
  fetches information on multiple closed orders made by the user
5118
- :see: https://www.bitget.com/api-doc/spot/trade/Get-History-Orders
5119
- :see: https://www.bitget.com/api-doc/spot/plan/Get-History-Plan-Order
5120
- :see: https://www.bitget.com/api-doc/contract/trade/Get-Orders-History
5121
- :see: https://www.bitget.com/api-doc/contract/plan/orders-plan-history
5122
- :see: https://www.bitget.com/api-doc/margin/cross/trade/Get-Cross-Order-History
5123
- :see: https://www.bitget.com/api-doc/margin/isolated/trade/Get-Isolated-Order-History
5438
+
5439
+ https://www.bitget.com/api-doc/spot/trade/Get-History-Orders
5440
+ https://www.bitget.com/api-doc/spot/plan/Get-History-Plan-Order
5441
+ https://www.bitget.com/api-doc/contract/trade/Get-Orders-History
5442
+ https://www.bitget.com/api-doc/contract/plan/orders-plan-history
5443
+ https://www.bitget.com/api-doc/margin/cross/trade/Get-Cross-Order-History
5444
+ https://www.bitget.com/api-doc/margin/isolated/trade/Get-Isolated-Order-History
5445
+
5124
5446
  :param str symbol: unified market symbol of the closed orders
5125
5447
  :param int [since]: timestamp in ms of the earliest order
5126
5448
  :param int [limit]: the max number of closed orders to return
@@ -5139,12 +5461,14 @@ class bitget(Exchange, ImplicitAPI):
5139
5461
  async def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5140
5462
  """
5141
5463
  fetches information on multiple canceled orders made by the user
5142
- :see: https://www.bitget.com/api-doc/spot/trade/Get-History-Orders
5143
- :see: https://www.bitget.com/api-doc/spot/plan/Get-History-Plan-Order
5144
- :see: https://www.bitget.com/api-doc/contract/trade/Get-Orders-History
5145
- :see: https://www.bitget.com/api-doc/contract/plan/orders-plan-history
5146
- :see: https://www.bitget.com/api-doc/margin/cross/trade/Get-Cross-Order-History
5147
- :see: https://www.bitget.com/api-doc/margin/isolated/trade/Get-Isolated-Order-History
5464
+
5465
+ https://www.bitget.com/api-doc/spot/trade/Get-History-Orders
5466
+ https://www.bitget.com/api-doc/spot/plan/Get-History-Plan-Order
5467
+ https://www.bitget.com/api-doc/contract/trade/Get-Orders-History
5468
+ https://www.bitget.com/api-doc/contract/plan/orders-plan-history
5469
+ https://www.bitget.com/api-doc/margin/cross/trade/Get-Cross-Order-History
5470
+ https://www.bitget.com/api-doc/margin/isolated/trade/Get-Isolated-Order-History
5471
+
5148
5472
  :param str symbol: unified market symbol of the canceled orders
5149
5473
  :param int [since]: timestamp in ms of the earliest order
5150
5474
  :param int [limit]: the max number of canceled orders to return
@@ -5162,12 +5486,14 @@ class bitget(Exchange, ImplicitAPI):
5162
5486
 
5163
5487
  async def fetch_canceled_and_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5164
5488
  """
5165
- :see: https://www.bitget.com/api-doc/spot/trade/Get-History-Orders
5166
- :see: https://www.bitget.com/api-doc/spot/plan/Get-History-Plan-Order
5167
- :see: https://www.bitget.com/api-doc/contract/trade/Get-Orders-History
5168
- :see: https://www.bitget.com/api-doc/contract/plan/orders-plan-history
5169
- :see: https://www.bitget.com/api-doc/margin/cross/trade/Get-Cross-Order-History
5170
- :see: https://www.bitget.com/api-doc/margin/isolated/trade/Get-Isolated-Order-History
5489
+
5490
+ https://www.bitget.com/api-doc/spot/trade/Get-History-Orders
5491
+ https://www.bitget.com/api-doc/spot/plan/Get-History-Plan-Order
5492
+ https://www.bitget.com/api-doc/contract/trade/Get-Orders-History
5493
+ https://www.bitget.com/api-doc/contract/plan/orders-plan-history
5494
+ https://www.bitget.com/api-doc/margin/cross/trade/Get-Cross-Order-History
5495
+ https://www.bitget.com/api-doc/margin/isolated/trade/Get-Isolated-Order-History
5496
+
5171
5497
  fetches information on multiple canceled and closed orders made by the user
5172
5498
  :param str symbol: unified market symbol of the market orders were made in
5173
5499
  :param int [since]: the earliest time in ms to fetch orders for
@@ -5182,7 +5508,7 @@ class bitget(Exchange, ImplicitAPI):
5182
5508
  if symbol is not None:
5183
5509
  sandboxSymbol = self.convert_symbol_for_sandbox(symbol)
5184
5510
  symbol = sandboxSymbol
5185
- request = {}
5511
+ request: dict = {}
5186
5512
  if symbol is not None:
5187
5513
  market = self.market(symbol)
5188
5514
  request['symbol'] = market['id']
@@ -5202,7 +5528,7 @@ class bitget(Exchange, ImplicitAPI):
5202
5528
  return await self.fetch_paginated_call_cursor('fetchCanceledAndClosedOrders', symbol, since, limit, params, cursorReceived, 'idLessThan')
5203
5529
  response = None
5204
5530
  trailing = self.safe_value(params, 'trailing')
5205
- stop = self.safe_bool_2(params, 'stop', 'trigger')
5531
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
5206
5532
  params = self.omit(params, ['stop', 'trigger', 'trailing'])
5207
5533
  request, params = self.handle_until_option('endTime', request, params)
5208
5534
  if since is not None:
@@ -5224,20 +5550,19 @@ class bitget(Exchange, ImplicitAPI):
5224
5550
  response = await self.privateMarginGetV2MarginIsolatedHistoryOrders(self.extend(request, params))
5225
5551
  elif marginMode == 'cross':
5226
5552
  response = await self.privateMarginGetV2MarginCrossedHistoryOrders(self.extend(request, params))
5553
+ elif trigger:
5554
+ if symbol is None:
5555
+ raise ArgumentsRequired(self.id + ' fetchCanceledAndClosedOrders() requires a symbol argument')
5556
+ endTime = self.safe_integer_n(params, ['endTime', 'until'])
5557
+ params = self.omit(params, ['until'])
5558
+ if since is None:
5559
+ since = now - 7776000000
5560
+ request['startTime'] = since
5561
+ if endTime is None:
5562
+ request['endTime'] = now
5563
+ response = await self.privateSpotGetV2SpotTradeHistoryPlanOrder(self.extend(request, params))
5227
5564
  else:
5228
- if stop:
5229
- if symbol is None:
5230
- raise ArgumentsRequired(self.id + ' fetchCanceledAndClosedOrders() requires a symbol argument')
5231
- endTime = self.safe_integer_n(params, ['endTime', 'until', 'till'])
5232
- params = self.omit(params, ['until', 'till'])
5233
- if since is None:
5234
- since = now - 7776000000
5235
- request['startTime'] = since
5236
- if endTime is None:
5237
- request['endTime'] = now
5238
- response = await self.privateSpotGetV2SpotTradeHistoryPlanOrder(self.extend(request, params))
5239
- else:
5240
- response = await self.privateSpotGetV2SpotTradeHistoryOrders(self.extend(request, params))
5565
+ response = await self.privateSpotGetV2SpotTradeHistoryOrders(self.extend(request, params))
5241
5566
  else:
5242
5567
  productType = None
5243
5568
  productType, params = self.handle_product_type_and_params(market, params)
@@ -5246,7 +5571,7 @@ class bitget(Exchange, ImplicitAPI):
5246
5571
  planType = self.safe_string(params, 'planType', 'track_plan')
5247
5572
  request['planType'] = planType
5248
5573
  response = await self.privateMixGetV2MixOrderOrdersPlanHistory(self.extend(request, params))
5249
- elif stop:
5574
+ elif trigger:
5250
5575
  planType = self.safe_string(params, 'planType', 'normal_plan')
5251
5576
  request['planType'] = planType
5252
5577
  response = await self.privateMixGetV2MixOrderOrdersPlanHistory(self.extend(request, params))
@@ -5432,29 +5757,31 @@ class bitget(Exchange, ImplicitAPI):
5432
5757
  #
5433
5758
  data = self.safe_value(response, 'data', {})
5434
5759
  if marketType == 'spot':
5435
- if (marginMode is not None) or stop:
5760
+ if (marginMode is not None) or trigger:
5436
5761
  return self.parse_orders(self.safe_value(data, 'orderList', []), market, since, limit)
5437
5762
  else:
5438
5763
  return self.parse_orders(self.safe_value(data, 'entrustedList', []), market, since, limit)
5439
5764
  if isinstance(response, str):
5440
5765
  response = json.loads(response)
5441
- orders = self.safe_value(response, 'data', [])
5766
+ orders = self.safe_list(response, 'data', [])
5442
5767
  return self.parse_orders(orders, market, since, limit)
5443
5768
 
5444
- async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
5769
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
5445
5770
  """
5446
- :see: https://www.bitget.com/api-doc/spot/account/Get-Account-Bills
5447
- :see: https://www.bitget.com/api-doc/contract/account/Get-Account-Bill
5448
- fetch the history of changes, actions done by the user or operations that altered balance of the user
5449
- :param str code: unified currency code, default is None
5771
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
5772
+
5773
+ https://www.bitget.com/api-doc/spot/account/Get-Account-Bills
5774
+ https://www.bitget.com/api-doc/contract/account/Get-Account-Bill
5775
+
5776
+ :param str [code]: unified currency code, default is None
5450
5777
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
5451
- :param int [limit]: max number of ledger entrys to return, default is None
5778
+ :param int [limit]: max number of ledger entries to return, default is None
5452
5779
  :param dict [params]: extra parameters specific to the exchange API endpoint
5453
5780
  :param int [params.until]: end time in ms
5454
5781
  :param str [params.symbol]: *contract only* unified market symbol
5455
5782
  :param str [params.productType]: *contract only* 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES'
5456
5783
  :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
5457
- :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
5784
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
5458
5785
  """
5459
5786
  await self.load_markets()
5460
5787
  symbol = self.safe_string(params, 'symbol')
@@ -5477,10 +5804,10 @@ class bitget(Exchange, ImplicitAPI):
5477
5804
  cursorReceived = 'endId'
5478
5805
  return await self.fetch_paginated_call_cursor('fetchLedger', symbol, since, limit, params, cursorReceived, 'idLessThan')
5479
5806
  currency = None
5480
- request = {}
5807
+ request: dict = {}
5481
5808
  if code is not None:
5482
5809
  currency = self.currency(code)
5483
- request['coin'] = currency['code']
5810
+ request['coin'] = currency['id']
5484
5811
  request, params = self.handle_until_option('endTime', request, params)
5485
5812
  if since is not None:
5486
5813
  request['startTime'] = since
@@ -5546,7 +5873,7 @@ class bitget(Exchange, ImplicitAPI):
5546
5873
  return self.parse_ledger(bills, currency, since, limit)
5547
5874
  return self.parse_ledger(data, currency, since, limit)
5548
5875
 
5549
- def parse_ledger_entry(self, item, currency: Currency = None):
5876
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
5550
5877
  #
5551
5878
  # spot
5552
5879
  #
@@ -5576,6 +5903,7 @@ class bitget(Exchange, ImplicitAPI):
5576
5903
  #
5577
5904
  currencyId = self.safe_string(item, 'coin')
5578
5905
  code = self.safe_currency_code(currencyId, currency)
5906
+ currency = self.safe_currency(currencyId, currency)
5579
5907
  timestamp = self.safe_integer(item, 'cTime')
5580
5908
  after = self.safe_number(item, 'balance')
5581
5909
  fee = self.safe_number_2(item, 'fees', 'fee')
@@ -5584,7 +5912,7 @@ class bitget(Exchange, ImplicitAPI):
5584
5912
  direction = 'in'
5585
5913
  if amountRaw.find('-') >= 0:
5586
5914
  direction = 'out'
5587
- return {
5915
+ return self.safe_ledger_entry({
5588
5916
  'info': item,
5589
5917
  'id': self.safe_string(item, 'billId'),
5590
5918
  'timestamp': timestamp,
@@ -5599,11 +5927,14 @@ class bitget(Exchange, ImplicitAPI):
5599
5927
  'before': None,
5600
5928
  'after': after,
5601
5929
  'status': None,
5602
- 'fee': fee,
5603
- }
5930
+ 'fee': {
5931
+ 'currency': code,
5932
+ 'cost': fee,
5933
+ },
5934
+ }, currency)
5604
5935
 
5605
5936
  def parse_ledger_type(self, type):
5606
- types = {
5937
+ types: dict = {
5607
5938
  'trans_to_cross': 'transfer',
5608
5939
  'trans_from_cross': 'transfer',
5609
5940
  'trans_to_exchange': 'transfer',
@@ -5650,10 +5981,12 @@ class bitget(Exchange, ImplicitAPI):
5650
5981
  async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
5651
5982
  """
5652
5983
  fetch all trades made by the user
5653
- :see: https://www.bitget.com/api-doc/spot/trade/Get-Fills
5654
- :see: https://www.bitget.com/api-doc/contract/trade/Get-Order-Fills
5655
- :see: https://www.bitget.com/api-doc/margin/cross/trade/Get-Cross-Order-Fills
5656
- :see: https://www.bitget.com/api-doc/margin/isolated/trade/Get-Isolated-Transaction-Details
5984
+
5985
+ https://www.bitget.com/api-doc/spot/trade/Get-Fills
5986
+ https://www.bitget.com/api-doc/contract/trade/Get-Order-Fills
5987
+ https://www.bitget.com/api-doc/margin/cross/trade/Get-Cross-Order-Fills
5988
+ https://www.bitget.com/api-doc/margin/isolated/trade/Get-Isolated-Transaction-Details
5989
+
5657
5990
  :param str symbol: unified market symbol
5658
5991
  :param int [since]: the earliest time in ms to fetch trades for
5659
5992
  :param int [limit]: the maximum number of trades structures to retrieve
@@ -5685,7 +6018,7 @@ class bitget(Exchange, ImplicitAPI):
5685
6018
  cursorReceived = 'endId'
5686
6019
  return await self.fetch_paginated_call_cursor('fetchMyTrades', symbol, since, limit, params, cursorReceived, 'idLessThan')
5687
6020
  response = None
5688
- request = {
6021
+ request: dict = {
5689
6022
  'symbol': market['id'],
5690
6023
  }
5691
6024
  request, params = self.handle_until_option('endTime', request, params)
@@ -5809,17 +6142,19 @@ class bitget(Exchange, ImplicitAPI):
5809
6142
  #
5810
6143
  data = self.safe_value(response, 'data')
5811
6144
  if (market['swap']) or (market['future']):
5812
- fillList = self.safe_value(data, 'fillList', [])
6145
+ fillList = self.safe_list(data, 'fillList', [])
5813
6146
  return self.parse_trades(fillList, market, since, limit)
5814
6147
  elif marginMode is not None:
5815
- fills = self.safe_value(data, 'fills', [])
6148
+ fills = self.safe_list(data, 'fills', [])
5816
6149
  return self.parse_trades(fills, market, since, limit)
5817
6150
  return self.parse_trades(data, market, since, limit)
5818
6151
 
5819
6152
  async def fetch_position(self, symbol: str, params={}):
5820
6153
  """
5821
6154
  fetch data on a single open contract trade position
5822
- :see: https://www.bitget.com/api-doc/contract/position/get-single-position
6155
+
6156
+ https://www.bitget.com/api-doc/contract/position/get-single-position
6157
+
5823
6158
  :param str symbol: unified market symbol of the market the position is held in
5824
6159
  :param dict [params]: extra parameters specific to the exchange API endpoint
5825
6160
  :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
@@ -5834,7 +6169,7 @@ class bitget(Exchange, ImplicitAPI):
5834
6169
  market = self.market(symbol)
5835
6170
  productType = None
5836
6171
  productType, params = self.handle_product_type_and_params(market, params)
5837
- request = {
6172
+ request: dict = {
5838
6173
  'symbol': market['id'],
5839
6174
  'marginCoin': market['settleId'],
5840
6175
  'productType': productType,
@@ -5870,15 +6205,17 @@ class bitget(Exchange, ImplicitAPI):
5870
6205
  # ]
5871
6206
  # }
5872
6207
  #
5873
- data = self.safe_value(response, 'data', [])
5874
- first = self.safe_value(data, 0, {})
6208
+ data = self.safe_list(response, 'data', [])
6209
+ first = self.safe_dict(data, 0, {})
5875
6210
  return self.parse_position(first, market)
5876
6211
 
5877
6212
  async def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
5878
6213
  """
5879
6214
  fetch all open positions
5880
- :see: https://www.bitget.com/api-doc/contract/position/get-all-position
5881
- :see: https://www.bitget.com/api-doc/contract/position/Get-History-Position
6215
+
6216
+ https://www.bitget.com/api-doc/contract/position/get-all-position
6217
+ https://www.bitget.com/api-doc/contract/position/Get-History-Position
6218
+
5882
6219
  :param str[] [symbols]: list of unified market symbols
5883
6220
  :param dict [params]: extra parameters specific to the exchange API endpoint
5884
6221
  :param str [params.marginCoin]: the settle currency of the positions, needs to match the productType
@@ -5910,7 +6247,7 @@ class bitget(Exchange, ImplicitAPI):
5910
6247
  market = self.market(first)
5911
6248
  productType = None
5912
6249
  productType, params = self.handle_product_type_and_params(market, params)
5913
- request = {
6250
+ request: dict = {
5914
6251
  'productType': productType,
5915
6252
  }
5916
6253
  response = None
@@ -6011,7 +6348,7 @@ class bitget(Exchange, ImplicitAPI):
6011
6348
  symbols = self.market_symbols(symbols)
6012
6349
  return self.filter_by_array_positions(result, 'symbol', symbols, False)
6013
6350
 
6014
- def parse_position(self, position, market: Market = None):
6351
+ def parse_position(self, position: dict, market: Market = None):
6015
6352
  #
6016
6353
  # fetchPosition
6017
6354
  #
@@ -6061,7 +6398,7 @@ class bitget(Exchange, ImplicitAPI):
6061
6398
  # "cTime": "1700807507275"
6062
6399
  # }
6063
6400
  #
6064
- # fetchPositions: privateMixGetV2MixPositionHistoryPosition
6401
+ # fetchPositionsHistory: privateMixGetV2MixPositionHistoryPosition
6065
6402
  #
6066
6403
  # {
6067
6404
  # "symbol": "BTCUSDT",
@@ -6177,7 +6514,9 @@ class bitget(Exchange, ImplicitAPI):
6177
6514
  async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6178
6515
  """
6179
6516
  fetches historical funding rate prices
6180
- :see: https://www.bitget.com/api-doc/contract/market/Get-History-Funding-Rate
6517
+
6518
+ https://www.bitget.com/api-doc/contract/market/Get-History-Funding-Rate
6519
+
6181
6520
  :param str symbol: unified symbol of the market to fetch the funding rate history for
6182
6521
  :param int [since]: timestamp in ms of the earliest funding rate to fetch
6183
6522
  :param int [limit]: the maximum amount of funding rate structures to fetch
@@ -6201,7 +6540,7 @@ class bitget(Exchange, ImplicitAPI):
6201
6540
  market = self.market(symbol)
6202
6541
  productType = None
6203
6542
  productType, params = self.handle_product_type_and_params(market, params)
6204
- request = {
6543
+ request: dict = {
6205
6544
  'symbol': market['id'],
6206
6545
  'productType': productType,
6207
6546
  # 'pageSize': limit, # default 20
@@ -6241,10 +6580,12 @@ class bitget(Exchange, ImplicitAPI):
6241
6580
  sorted = self.sort_by(rates, 'timestamp')
6242
6581
  return self.filter_by_symbol_since_limit(sorted, market['symbol'], since, limit)
6243
6582
 
6244
- async def fetch_funding_rate(self, symbol: str, params={}):
6583
+ async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
6245
6584
  """
6246
6585
  fetch the current funding rate
6247
- :see: https://www.bitget.com/api-doc/contract/market/Get-Current-Funding-Rate
6586
+
6587
+ https://www.bitget.com/api-doc/contract/market/Get-Current-Funding-Rate
6588
+
6248
6589
  :param str symbol: unified market symbol
6249
6590
  :param dict [params]: extra parameters specific to the exchange API endpoint
6250
6591
  :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
@@ -6261,7 +6602,7 @@ class bitget(Exchange, ImplicitAPI):
6261
6602
  raise BadSymbol(self.id + ' fetchFundingRate() supports swap contracts only')
6262
6603
  productType = None
6263
6604
  productType, params = self.handle_product_type_and_params(market, params)
6264
- request = {
6605
+ request: dict = {
6265
6606
  'symbol': market['id'],
6266
6607
  'productType': productType,
6267
6608
  }
@@ -6282,39 +6623,148 @@ class bitget(Exchange, ImplicitAPI):
6282
6623
  data = self.safe_value(response, 'data', [])
6283
6624
  return self.parse_funding_rate(data[0], market)
6284
6625
 
6285
- def parse_funding_rate(self, contract, market: Market = None):
6626
+ async def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
6627
+ """
6628
+ fetch the current funding rates for all markets
6629
+
6630
+ https://www.bitget.com/api-doc/contract/market/Get-All-Symbol-Ticker
6631
+
6632
+ :param str[] [symbols]: list of unified market symbols
6633
+ :param dict [params]: extra parameters specific to the exchange API endpoint
6634
+ :param str [params.subType]: *contract only* 'linear', 'inverse'
6635
+ :param str [params.productType]: *contract only* 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES'
6636
+ :returns dict: a dictionary of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexed by market symbols
6637
+ """
6638
+ await self.load_markets()
6639
+ market = None
6640
+ if symbols is not None:
6641
+ symbol = self.safe_value(symbols, 0)
6642
+ sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
6643
+ if sandboxMode:
6644
+ sandboxSymbol = self.convert_symbol_for_sandbox(symbol)
6645
+ market = self.market(sandboxSymbol)
6646
+ else:
6647
+ market = self.market(symbol)
6648
+ request: dict = {}
6649
+ productType = None
6650
+ productType, params = self.handle_product_type_and_params(market, params)
6651
+ request['productType'] = productType
6652
+ response = await self.publicMixGetV2MixMarketTickers(self.extend(request, params))
6653
+ # {
6654
+ # "code": "00000",
6655
+ # "msg": "success",
6656
+ # "requestTime": 1700533773477,
6657
+ # "data": [
6658
+ # {
6659
+ # "symbol": "BTCUSD",
6660
+ # "lastPr": "29904.5",
6661
+ # "askPr": "29904.5",
6662
+ # "bidPr": "29903.5",
6663
+ # "bidSz": "0.5091",
6664
+ # "askSz": "2.2694",
6665
+ # "high24h": "0",
6666
+ # "low24h": "0",
6667
+ # "ts": "1695794271400",
6668
+ # "change24h": "0",
6669
+ # "baseVolume": "0",
6670
+ # "quoteVolume": "0",
6671
+ # "usdtVolume": "0",
6672
+ # "openUtc": "0",
6673
+ # "changeUtc24h": "0",
6674
+ # "indexPrice": "29132.353333",
6675
+ # "fundingRate": "-0.0007",
6676
+ # "holdingAmount": "125.6844",
6677
+ # "deliveryStartTime": null,
6678
+ # "deliveryTime": null,
6679
+ # "deliveryStatus": "delivery_normal",
6680
+ # "open24h": "0",
6681
+ # "markPrice": "12345"
6682
+ # },
6683
+ # ]
6684
+ # }
6685
+ symbols = self.market_symbols(symbols)
6686
+ data = self.safe_list(response, 'data', [])
6687
+ return self.parse_funding_rates(data, symbols)
6688
+
6689
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
6690
+ #
6691
+ # fetchFundingRate
6286
6692
  #
6287
6693
  # {
6288
6694
  # "symbol": "BTCUSDT",
6289
6695
  # "fundingRate": "-0.000182"
6290
6696
  # }
6291
6697
  #
6698
+ # fetchFundingInterval
6699
+ #
6700
+ # {
6701
+ # "symbol": "BTCUSDT",
6702
+ # "nextFundingTime": "1727942400000",
6703
+ # "ratePeriod": "8"
6704
+ # }
6705
+ # fetchFundingRates
6706
+ # {
6707
+ # "symbol": "BTCUSD",
6708
+ # "lastPr": "29904.5",
6709
+ # "askPr": "29904.5",
6710
+ # "bidPr": "29903.5",
6711
+ # "bidSz": "0.5091",
6712
+ # "askSz": "2.2694",
6713
+ # "high24h": "0",
6714
+ # "low24h": "0",
6715
+ # "ts": "1695794271400",
6716
+ # "change24h": "0",
6717
+ # "baseVolume": "0",
6718
+ # "quoteVolume": "0",
6719
+ # "usdtVolume": "0",
6720
+ # "openUtc": "0",
6721
+ # "changeUtc24h": "0",
6722
+ # "indexPrice": "29132.353333",
6723
+ # "fundingRate": "-0.0007",
6724
+ # "holdingAmount": "125.6844",
6725
+ # "deliveryStartTime": null,
6726
+ # "deliveryTime": null,
6727
+ # "deliveryStatus": "delivery_normal",
6728
+ # "open24h": "0",
6729
+ # "markPrice": "12345"
6730
+ # }
6292
6731
  marketId = self.safe_string(contract, 'symbol')
6293
6732
  symbol = self.safe_symbol(marketId, market, None, 'swap')
6733
+ fundingTimestamp = self.safe_integer(contract, 'nextFundingTime')
6734
+ interval = self.safe_string(contract, 'ratePeriod')
6735
+ timestamp = self.safe_integer(contract, 'ts')
6736
+ markPrice = self.safe_number(contract, 'markPrice')
6737
+ indexPrice = self.safe_number(contract, 'indexPrice')
6738
+ intervalString = None
6739
+ if interval is not None:
6740
+ intervalString = interval + 'h'
6294
6741
  return {
6295
6742
  'info': contract,
6296
6743
  'symbol': symbol,
6297
- 'markPrice': None,
6298
- 'indexPrice': None,
6744
+ 'markPrice': markPrice,
6745
+ 'indexPrice': indexPrice,
6299
6746
  'interestRate': None,
6300
6747
  'estimatedSettlePrice': None,
6301
- 'timestamp': None,
6302
- 'datetime': None,
6748
+ 'timestamp': timestamp,
6749
+ 'datetime': self.iso8601(timestamp),
6303
6750
  'fundingRate': self.safe_number(contract, 'fundingRate'),
6304
- 'fundingTimestamp': None,
6305
- 'fundingDatetime': None,
6751
+ 'fundingTimestamp': fundingTimestamp,
6752
+ 'fundingDatetime': self.iso8601(fundingTimestamp),
6306
6753
  'nextFundingRate': None,
6307
6754
  'nextFundingTimestamp': None,
6308
6755
  'nextFundingDatetime': None,
6309
6756
  'previousFundingRate': None,
6310
6757
  'previousFundingTimestamp': None,
6311
6758
  'previousFundingDatetime': None,
6759
+ 'interval': intervalString,
6312
6760
  }
6313
6761
 
6314
6762
  async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[FundingHistory]:
6315
6763
  """
6316
6764
  fetch the funding history
6317
- :see: https://www.bitget.com/api-doc/contract/account/Get-Account-Bill
6765
+
6766
+ https://www.bitget.com/api-doc/contract/account/Get-Account-Bill
6767
+
6318
6768
  :param str symbol: unified market symbol
6319
6769
  :param int [since]: the starting timestamp in milliseconds
6320
6770
  :param int [limit]: the number of entries to return
@@ -6341,7 +6791,7 @@ class bitget(Exchange, ImplicitAPI):
6341
6791
  raise BadSymbol(self.id + ' fetchFundingHistory() supports swap contracts only')
6342
6792
  productType = None
6343
6793
  productType, params = self.handle_product_type_and_params(market, params)
6344
- request = {
6794
+ request: dict = {
6345
6795
  'symbol': market['id'],
6346
6796
  'marginCoin': market['settleId'],
6347
6797
  'businessType': 'contract_settle_fee',
@@ -6416,7 +6866,7 @@ class bitget(Exchange, ImplicitAPI):
6416
6866
  sorted = self.sort_by(result, 'timestamp')
6417
6867
  return self.filter_by_since_limit(sorted, since, limit)
6418
6868
 
6419
- async def modify_margin_helper(self, symbol: str, amount, type, params={}):
6869
+ async def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
6420
6870
  await self.load_markets()
6421
6871
  holdSide = self.safe_string(params, 'holdSide')
6422
6872
  sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
@@ -6428,7 +6878,7 @@ class bitget(Exchange, ImplicitAPI):
6428
6878
  market = self.market(symbol)
6429
6879
  productType = None
6430
6880
  productType, params = self.handle_product_type_and_params(market, params)
6431
- request = {
6881
+ request: dict = {
6432
6882
  'symbol': market['id'],
6433
6883
  'marginCoin': market['settleId'],
6434
6884
  'amount': self.amount_to_precision(symbol, amount), # positive value for adding margin, negative for reducing
@@ -6450,22 +6900,38 @@ class bitget(Exchange, ImplicitAPI):
6450
6900
  'type': type,
6451
6901
  })
6452
6902
 
6453
- def parse_margin_modification(self, data, market: Market = None):
6903
+ def parse_margin_modification(self, data: dict, market: Market = None) -> MarginModification:
6904
+ #
6905
+ # addMargin/reduceMargin
6906
+ #
6907
+ # {
6908
+ # "code": "00000",
6909
+ # "msg": "success",
6910
+ # "requestTime": 1700813444618,
6911
+ # "data": ""
6912
+ # }
6913
+ #
6454
6914
  errorCode = self.safe_string(data, 'code')
6455
6915
  status = 'ok' if (errorCode == '00000') else 'failed'
6456
6916
  return {
6457
6917
  'info': data,
6918
+ 'symbol': market['symbol'],
6458
6919
  'type': None,
6920
+ 'marginMode': 'isolated',
6459
6921
  'amount': None,
6922
+ 'total': None,
6460
6923
  'code': market['settle'],
6461
- 'symbol': market['symbol'],
6462
6924
  'status': status,
6925
+ 'timestamp': None,
6926
+ 'datetime': None,
6463
6927
  }
6464
6928
 
6465
- async def reduce_margin(self, symbol: str, amount, params={}):
6929
+ async def reduce_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
6466
6930
  """
6467
6931
  remove margin from a position
6468
- :see: https://www.bitget.com/api-doc/contract/account/Change-Margin
6932
+
6933
+ https://www.bitget.com/api-doc/contract/account/Change-Margin
6934
+
6469
6935
  :param str symbol: unified market symbol
6470
6936
  :param float amount: the amount of margin to remove
6471
6937
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -6478,10 +6944,12 @@ class bitget(Exchange, ImplicitAPI):
6478
6944
  raise ArgumentsRequired(self.id + ' reduceMargin() requires a holdSide parameter, either long or short')
6479
6945
  return await self.modify_margin_helper(symbol, amount, 'reduce', params)
6480
6946
 
6481
- async def add_margin(self, symbol: str, amount, params={}):
6947
+ async def add_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
6482
6948
  """
6483
6949
  add margin
6484
- :see: https://www.bitget.com/api-doc/contract/account/Change-Margin
6950
+
6951
+ https://www.bitget.com/api-doc/contract/account/Change-Margin
6952
+
6485
6953
  :param str symbol: unified market symbol
6486
6954
  :param float amount: the amount of margin to add
6487
6955
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -6495,7 +6963,9 @@ class bitget(Exchange, ImplicitAPI):
6495
6963
  async def fetch_leverage(self, symbol: str, params={}) -> Leverage:
6496
6964
  """
6497
6965
  fetch the set leverage for a market
6498
- :see: https://www.bitget.com/api-doc/contract/account/Get-Single-Account
6966
+
6967
+ https://www.bitget.com/api-doc/contract/account/Get-Single-Account
6968
+
6499
6969
  :param str symbol: unified market symbol
6500
6970
  :param dict [params]: extra parameters specific to the exchange API endpoint
6501
6971
  :returns dict: a `leverage structure <https://docs.ccxt.com/#/?id=leverage-structure>`
@@ -6510,7 +6980,7 @@ class bitget(Exchange, ImplicitAPI):
6510
6980
  market = self.market(symbol)
6511
6981
  productType = None
6512
6982
  productType, params = self.handle_product_type_and_params(market, params)
6513
- request = {
6983
+ request: dict = {
6514
6984
  'symbol': market['id'],
6515
6985
  'marginCoin': market['settleId'],
6516
6986
  'productType': productType,
@@ -6547,7 +7017,7 @@ class bitget(Exchange, ImplicitAPI):
6547
7017
  data = self.safe_dict(response, 'data', {})
6548
7018
  return self.parse_leverage(data, market)
6549
7019
 
6550
- def parse_leverage(self, leverage, market=None) -> Leverage:
7020
+ def parse_leverage(self, leverage: dict, market: Market = None) -> Leverage:
6551
7021
  return {
6552
7022
  'info': leverage,
6553
7023
  'symbol': market['symbol'],
@@ -6559,7 +7029,9 @@ class bitget(Exchange, ImplicitAPI):
6559
7029
  async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
6560
7030
  """
6561
7031
  set the level of leverage for a market
6562
- :see: https://www.bitget.com/api-doc/contract/account/Change-Leverage
7032
+
7033
+ https://www.bitget.com/api-doc/contract/account/Change-Leverage
7034
+
6563
7035
  :param int leverage: the rate of leverage
6564
7036
  :param str symbol: unified market symbol
6565
7037
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -6578,7 +7050,7 @@ class bitget(Exchange, ImplicitAPI):
6578
7050
  market = self.market(symbol)
6579
7051
  productType = None
6580
7052
  productType, params = self.handle_product_type_and_params(market, params)
6581
- request = {
7053
+ request: dict = {
6582
7054
  'symbol': market['id'],
6583
7055
  'marginCoin': market['settleId'],
6584
7056
  'leverage': self.number_to_string(leverage),
@@ -6606,7 +7078,9 @@ class bitget(Exchange, ImplicitAPI):
6606
7078
  async def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
6607
7079
  """
6608
7080
  set margin mode to 'cross' or 'isolated'
6609
- :see: https://www.bitget.com/api-doc/contract/account/Change-Margin-Mode
7081
+
7082
+ https://www.bitget.com/api-doc/contract/account/Change-Margin-Mode
7083
+
6610
7084
  :param str marginMode: 'cross' or 'isolated'
6611
7085
  :param str symbol: unified market symbol
6612
7086
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -6629,7 +7103,7 @@ class bitget(Exchange, ImplicitAPI):
6629
7103
  market = self.market(symbol)
6630
7104
  productType = None
6631
7105
  productType, params = self.handle_product_type_and_params(market, params)
6632
- request = {
7106
+ request: dict = {
6633
7107
  'symbol': market['id'],
6634
7108
  'marginCoin': market['settleId'],
6635
7109
  'marginMode': marginMode,
@@ -6655,7 +7129,9 @@ class bitget(Exchange, ImplicitAPI):
6655
7129
  async def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
6656
7130
  """
6657
7131
  set hedged to True or False for a market
6658
- :see: https://www.bitget.com/api-doc/contract/account/Change-Hold-Mode
7132
+
7133
+ https://www.bitget.com/api-doc/contract/account/Change-Hold-Mode
7134
+
6659
7135
  :param bool hedged: set to True to use dualSidePosition
6660
7136
  :param str symbol: not used by bitget setPositionMode()
6661
7137
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -6674,7 +7150,7 @@ class bitget(Exchange, ImplicitAPI):
6674
7150
  market = self.market(symbol)
6675
7151
  productType = None
6676
7152
  productType, params = self.handle_product_type_and_params(market, params)
6677
- request = {
7153
+ request: dict = {
6678
7154
  'posMode': posMode,
6679
7155
  'productType': productType,
6680
7156
  }
@@ -6694,7 +7170,9 @@ class bitget(Exchange, ImplicitAPI):
6694
7170
  async def fetch_open_interest(self, symbol: str, params={}):
6695
7171
  """
6696
7172
  retrieves the open interest of a contract trading pair
6697
- :see: https://www.bitget.com/api-doc/contract/market/Get-Open-Interest
7173
+
7174
+ https://www.bitget.com/api-doc/contract/market/Get-Open-Interest
7175
+
6698
7176
  :param str symbol: unified CCXT market symbol
6699
7177
  :param dict [params]: exchange specific parameters
6700
7178
  :returns dict} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure:
@@ -6711,7 +7189,7 @@ class bitget(Exchange, ImplicitAPI):
6711
7189
  raise BadRequest(self.id + ' fetchOpenInterest() supports contract markets only')
6712
7190
  productType = None
6713
7191
  productType, params = self.handle_product_type_and_params(market, params)
6714
- request = {
7192
+ request: dict = {
6715
7193
  'symbol': market['id'],
6716
7194
  'productType': productType,
6717
7195
  }
@@ -6732,7 +7210,7 @@ class bitget(Exchange, ImplicitAPI):
6732
7210
  # }
6733
7211
  # }
6734
7212
  #
6735
- data = self.safe_value(response, 'data', {})
7213
+ data = self.safe_dict(response, 'data', {})
6736
7214
  return self.parse_open_interest(data, market)
6737
7215
 
6738
7216
  def parse_open_interest(self, interest, market: Market = None):
@@ -6759,10 +7237,12 @@ class bitget(Exchange, ImplicitAPI):
6759
7237
  'info': interest,
6760
7238
  }, market)
6761
7239
 
6762
- async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
7240
+ async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[TransferEntry]:
6763
7241
  """
6764
7242
  fetch a history of internal transfers made on an account
6765
- :see: https://www.bitget.com/api-doc/spot/account/Get-Account-TransferRecords
7243
+
7244
+ https://www.bitget.com/api-doc/spot/account/Get-Account-TransferRecords
7245
+
6766
7246
  :param str code: unified currency code of the currency transferred
6767
7247
  :param int [since]: the earliest time in ms to fetch transfers for
6768
7248
  :param int [limit]: the maximum number of transfers structures to retrieve
@@ -6780,8 +7260,8 @@ class bitget(Exchange, ImplicitAPI):
6780
7260
  accountsByType = self.safe_value(self.options, 'accountsByType', {})
6781
7261
  type = self.safe_string(accountsByType, fromAccount)
6782
7262
  currency = self.currency(code)
6783
- request = {
6784
- 'coin': currency['code'],
7263
+ request: dict = {
7264
+ 'coin': currency['id'],
6785
7265
  'fromType': type,
6786
7266
  }
6787
7267
  if since is not None:
@@ -6811,13 +7291,15 @@ class bitget(Exchange, ImplicitAPI):
6811
7291
  # ]
6812
7292
  # }
6813
7293
  #
6814
- data = self.safe_value(response, 'data', [])
7294
+ data = self.safe_list(response, 'data', [])
6815
7295
  return self.parse_transfers(data, currency, since, limit)
6816
7296
 
6817
7297
  async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
6818
7298
  """
6819
7299
  transfer currency internally between wallets on the same account
6820
- :see: https://www.bitget.com/api-doc/spot/account/Wallet-Transfer
7300
+
7301
+ https://www.bitget.com/api-doc/spot/account/Wallet-Transfer
7302
+
6821
7303
  :param str code: unified currency code
6822
7304
  :param float amount: amount to transfer
6823
7305
  :param str fromAccount: account to transfer from
@@ -6832,11 +7314,11 @@ class bitget(Exchange, ImplicitAPI):
6832
7314
  accountsByType = self.safe_value(self.options, 'accountsByType', {})
6833
7315
  fromType = self.safe_string(accountsByType, fromAccount)
6834
7316
  toType = self.safe_string(accountsByType, toAccount)
6835
- request = {
7317
+ request: dict = {
6836
7318
  'fromType': fromType,
6837
7319
  'toType': toType,
6838
7320
  'amount': amount,
6839
- 'coin': currency['code'],
7321
+ 'coin': currency['id'],
6840
7322
  }
6841
7323
  symbol = self.safe_string(params, 'symbol')
6842
7324
  params = self.omit(params, 'symbol')
@@ -6860,7 +7342,7 @@ class bitget(Exchange, ImplicitAPI):
6860
7342
  data['ts'] = self.safe_integer(response, 'requestTime')
6861
7343
  return self.parse_transfer(data, currency)
6862
7344
 
6863
- def parse_transfer(self, transfer, currency: Currency = None):
7345
+ def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
6864
7346
  #
6865
7347
  # transfer
6866
7348
  #
@@ -6905,8 +7387,8 @@ class bitget(Exchange, ImplicitAPI):
6905
7387
  'status': self.parse_transfer_status(status),
6906
7388
  }
6907
7389
 
6908
- def parse_transfer_status(self, status):
6909
- statuses = {
7390
+ def parse_transfer_status(self, status: Str) -> Str:
7391
+ statuses: dict = {
6910
7392
  'successful': 'ok',
6911
7393
  }
6912
7394
  return self.safe_string(statuses, status, status)
@@ -6936,7 +7418,7 @@ class bitget(Exchange, ImplicitAPI):
6936
7418
  #
6937
7419
  chains = self.safe_value(fee, 'chains', [])
6938
7420
  chainsLength = len(chains)
6939
- result = {
7421
+ result: dict = {
6940
7422
  'info': fee,
6941
7423
  'withdraw': {
6942
7424
  'fee': None,
@@ -6965,7 +7447,9 @@ class bitget(Exchange, ImplicitAPI):
6965
7447
  async def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
6966
7448
  """
6967
7449
  fetch deposit and withdraw fees
6968
- :see: https://www.bitget.com/api-doc/spot/market/Get-Coin-List
7450
+
7451
+ https://www.bitget.com/api-doc/spot/market/Get-Coin-List
7452
+
6969
7453
  :param str[]|None codes: list of unified currency codes
6970
7454
  :param dict [params]: extra parameters specific to the exchange API endpoint
6971
7455
  :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -7001,13 +7485,15 @@ class bitget(Exchange, ImplicitAPI):
7001
7485
  # "requestTime": "1700120731773"
7002
7486
  # }
7003
7487
  #
7004
- data = self.safe_value(response, 'data', [])
7488
+ data = self.safe_list(response, 'data', [])
7005
7489
  return self.parse_deposit_withdraw_fees(data, codes, 'coin')
7006
7490
 
7007
7491
  async def borrow_cross_margin(self, code: str, amount: float, params={}):
7008
7492
  """
7009
7493
  create a loan to borrow margin
7010
- :see: https://www.bitget.com/api-doc/margin/cross/account/Cross-Borrow
7494
+
7495
+ https://www.bitget.com/api-doc/margin/cross/account/Cross-Borrow
7496
+
7011
7497
  :param str code: unified currency code of the currency to borrow
7012
7498
  :param str amount: the amount to borrow
7013
7499
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -7015,8 +7501,8 @@ class bitget(Exchange, ImplicitAPI):
7015
7501
  """
7016
7502
  await self.load_markets()
7017
7503
  currency = self.currency(code)
7018
- request = {
7019
- 'coin': currency['code'],
7504
+ request: dict = {
7505
+ 'coin': currency['id'],
7020
7506
  'borrowAmount': self.currency_to_precision(code, amount),
7021
7507
  }
7022
7508
  response = await self.privateMarginPostV2MarginCrossedAccountBorrow(self.extend(request, params))
@@ -7038,7 +7524,9 @@ class bitget(Exchange, ImplicitAPI):
7038
7524
  async def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
7039
7525
  """
7040
7526
  create a loan to borrow margin
7041
- :see: https://www.bitget.com/api-doc/margin/isolated/account/Isolated-Borrow
7527
+
7528
+ https://www.bitget.com/api-doc/margin/isolated/account/Isolated-Borrow
7529
+
7042
7530
  :param str symbol: unified market symbol
7043
7531
  :param str code: unified currency code of the currency to borrow
7044
7532
  :param str amount: the amount to borrow
@@ -7048,8 +7536,8 @@ class bitget(Exchange, ImplicitAPI):
7048
7536
  await self.load_markets()
7049
7537
  currency = self.currency(code)
7050
7538
  market = self.market(symbol)
7051
- request = {
7052
- 'coin': currency['code'],
7539
+ request: dict = {
7540
+ 'coin': currency['id'],
7053
7541
  'borrowAmount': self.currency_to_precision(code, amount),
7054
7542
  'symbol': market['id'],
7055
7543
  }
@@ -7073,7 +7561,9 @@ class bitget(Exchange, ImplicitAPI):
7073
7561
  async def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
7074
7562
  """
7075
7563
  repay borrowed margin and interest
7076
- :see: https://www.bitget.com/api-doc/margin/isolated/account/Isolated-Repay
7564
+
7565
+ https://www.bitget.com/api-doc/margin/isolated/account/Isolated-Repay
7566
+
7077
7567
  :param str symbol: unified market symbol
7078
7568
  :param str code: unified currency code of the currency to repay
7079
7569
  :param str amount: the amount to repay
@@ -7083,8 +7573,8 @@ class bitget(Exchange, ImplicitAPI):
7083
7573
  await self.load_markets()
7084
7574
  currency = self.currency(code)
7085
7575
  market = self.market(symbol)
7086
- request = {
7087
- 'coin': currency['code'],
7576
+ request: dict = {
7577
+ 'coin': currency['id'],
7088
7578
  'repayAmount': self.currency_to_precision(code, amount),
7089
7579
  'symbol': market['id'],
7090
7580
  }
@@ -7109,7 +7599,9 @@ class bitget(Exchange, ImplicitAPI):
7109
7599
  async def repay_cross_margin(self, code: str, amount, params={}):
7110
7600
  """
7111
7601
  repay borrowed margin and interest
7112
- :see: https://www.bitget.com/api-doc/margin/cross/account/Cross-Repay
7602
+
7603
+ https://www.bitget.com/api-doc/margin/cross/account/Cross-Repay
7604
+
7113
7605
  :param str code: unified currency code of the currency to repay
7114
7606
  :param str amount: the amount to repay
7115
7607
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -7117,8 +7609,8 @@ class bitget(Exchange, ImplicitAPI):
7117
7609
  """
7118
7610
  await self.load_markets()
7119
7611
  currency = self.currency(code)
7120
- request = {
7121
- 'coin': currency['code'],
7612
+ request: dict = {
7613
+ 'coin': currency['id'],
7122
7614
  'repayAmount': self.currency_to_precision(code, amount),
7123
7615
  }
7124
7616
  response = await self.privateMarginPostV2MarginCrossedAccountRepay(self.extend(request, params))
@@ -7194,8 +7686,10 @@ class bitget(Exchange, ImplicitAPI):
7194
7686
  async def fetch_my_liquidations(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
7195
7687
  """
7196
7688
  retrieves the users liquidated positions
7197
- :see: https://www.bitget.com/api-doc/margin/cross/record/Get-Cross-Liquidation-Records
7198
- :see: https://www.bitget.com/api-doc/margin/isolated/record/Get-Isolated-Liquidation-Records
7689
+
7690
+ https://www.bitget.com/api-doc/margin/cross/record/Get-Cross-Liquidation-Records
7691
+ https://www.bitget.com/api-doc/margin/isolated/record/Get-Isolated-Liquidation-Records
7692
+
7199
7693
  :param str [symbol]: unified CCXT market symbol
7200
7694
  :param int [since]: the earliest time in ms to fetch liquidations for
7201
7695
  :param int [limit]: the maximum number of liquidation structures to retrieve
@@ -7217,7 +7711,7 @@ class bitget(Exchange, ImplicitAPI):
7217
7711
  type, params = self.handle_market_type_and_params('fetchMyLiquidations', market, params)
7218
7712
  if type != 'spot':
7219
7713
  raise NotSupported(self.id + ' fetchMyLiquidations() supports spot margin markets only')
7220
- request = {}
7714
+ request: dict = {}
7221
7715
  request, params = self.handle_until_option('endTime', request, params)
7222
7716
  if since is not None:
7223
7717
  request['startTime'] = since
@@ -7288,7 +7782,7 @@ class bitget(Exchange, ImplicitAPI):
7288
7782
  # }
7289
7783
  #
7290
7784
  data = self.safe_value(response, 'data', {})
7291
- liquidations = self.safe_value(data, 'resultList', [])
7785
+ liquidations = self.safe_list(data, 'resultList', [])
7292
7786
  return self.parse_liquidations(liquidations, market, since, limit)
7293
7787
 
7294
7788
  def parse_liquidation(self, liquidation, market: Market = None):
@@ -7339,17 +7833,19 @@ class bitget(Exchange, ImplicitAPI):
7339
7833
  'datetime': self.iso8601(timestamp),
7340
7834
  })
7341
7835
 
7342
- async def fetch_isolated_borrow_rate(self, symbol: str, params={}):
7836
+ async def fetch_isolated_borrow_rate(self, symbol: str, params={}) -> IsolatedBorrowRate:
7343
7837
  """
7344
7838
  fetch the rate of interest to borrow a currency for margin trading
7345
- :see: https://www.bitget.com/api-doc/margin/isolated/account/Isolated-Margin-Interest-Rate-And-Max-Borrowable-Amount
7839
+
7840
+ https://www.bitget.com/api-doc/margin/isolated/account/Isolated-Margin-Interest-Rate-And-Max-Borrowable-Amount
7841
+
7346
7842
  :param str symbol: unified market symbol
7347
7843
  :param dict [params]: extra parameters specific to the exchange API endpoint
7348
7844
  :returns dict: an `isolated borrow rate structure <https://docs.ccxt.com/#/?id=isolated-borrow-rate-structure>`
7349
7845
  """
7350
7846
  await self.load_markets()
7351
7847
  market = self.market(symbol)
7352
- request = {
7848
+ request: dict = {
7353
7849
  'symbol': market['id'],
7354
7850
  }
7355
7851
  response = await self.privateMarginGetV2MarginIsolatedInterestRateAndLimit(self.extend(request, params))
@@ -7400,7 +7896,7 @@ class bitget(Exchange, ImplicitAPI):
7400
7896
  first['timestamp'] = timestamp
7401
7897
  return self.parse_isolated_borrow_rate(first, market)
7402
7898
 
7403
- def parse_isolated_borrow_rate(self, info, market: Market = None):
7899
+ def parse_isolated_borrow_rate(self, info: dict, market: Market = None) -> IsolatedBorrowRate:
7404
7900
  #
7405
7901
  # {
7406
7902
  # "symbol": "BTCUSDT",
@@ -7452,10 +7948,12 @@ class bitget(Exchange, ImplicitAPI):
7452
7948
  'info': info,
7453
7949
  }
7454
7950
 
7455
- async def fetch_cross_borrow_rate(self, code: str, params={}):
7951
+ async def fetch_cross_borrow_rate(self, code: str, params={}) -> CrossBorrowRate:
7456
7952
  """
7457
7953
  fetch the rate of interest to borrow a currency for margin trading
7458
- :see: https://www.bitget.com/api-doc/margin/cross/account/Get-Cross-Margin-Interest-Rate-And-Borrowable
7954
+
7955
+ https://www.bitget.com/api-doc/margin/cross/account/Get-Cross-Margin-Interest-Rate-And-Borrowable
7956
+
7459
7957
  :param str code: unified currency code
7460
7958
  :param dict [params]: extra parameters specific to the exchange API endpoint
7461
7959
  :param str [params.symbol]: required for isolated margin
@@ -7463,8 +7961,8 @@ class bitget(Exchange, ImplicitAPI):
7463
7961
  """
7464
7962
  await self.load_markets()
7465
7963
  currency = self.currency(code)
7466
- request = {
7467
- 'coin': currency['code'],
7964
+ request: dict = {
7965
+ 'coin': currency['id'],
7468
7966
  }
7469
7967
  response = await self.privateMarginGetV2MarginCrossedInterestRateAndLimit(self.extend(request, params))
7470
7968
  #
@@ -7530,11 +8028,13 @@ class bitget(Exchange, ImplicitAPI):
7530
8028
  'info': info,
7531
8029
  }
7532
8030
 
7533
- async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
8031
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
7534
8032
  """
7535
8033
  fetch the interest owed by the user for borrowing currency for margin trading
7536
- :see: https://www.bitget.com/api-doc/margin/cross/record/Get-Cross-Interest-Records
7537
- :see: https://www.bitget.com/api-doc/margin/isolated/record/Get-Isolated-Interest-Records
8034
+
8035
+ https://www.bitget.com/api-doc/margin/cross/record/Get-Cross-Interest-Records
8036
+ https://www.bitget.com/api-doc/margin/isolated/record/Get-Isolated-Interest-Records
8037
+
7538
8038
  :param str [code]: unified currency code
7539
8039
  :param str [symbol]: unified market symbol when fetching interest in isolated markets
7540
8040
  :param int [since]: the earliest time in ms to fetch borrow interest for
@@ -7551,11 +8051,11 @@ class bitget(Exchange, ImplicitAPI):
7551
8051
  market = None
7552
8052
  if symbol is not None:
7553
8053
  market = self.market(symbol)
7554
- request = {}
8054
+ request: dict = {}
7555
8055
  currency = None
7556
8056
  if code is not None:
7557
8057
  currency = self.currency(code)
7558
- request['coin'] = currency['code']
8058
+ request['coin'] = currency['id']
7559
8059
  if since is not None:
7560
8060
  request['startTime'] = since
7561
8061
  else:
@@ -7627,7 +8127,7 @@ class bitget(Exchange, ImplicitAPI):
7627
8127
  interest = self.parse_borrow_interests(rows, market)
7628
8128
  return self.filter_by_currency_since_limit(interest, code, since, limit)
7629
8129
 
7630
- def parse_borrow_interest(self, info, market: Market = None):
8130
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
7631
8131
  #
7632
8132
  # isolated
7633
8133
  #
@@ -7661,21 +8161,23 @@ class bitget(Exchange, ImplicitAPI):
7661
8161
  marginMode = 'isolated' if (marketId is not None) else 'cross'
7662
8162
  timestamp = self.safe_integer(info, 'cTime')
7663
8163
  return {
8164
+ 'info': info,
7664
8165
  'symbol': self.safe_string(market, 'symbol'),
7665
- 'marginMode': marginMode,
7666
8166
  'currency': self.safe_currency_code(self.safe_string(info, 'interestCoin')),
7667
8167
  'interest': self.safe_number(info, 'interestAmount'),
7668
8168
  'interestRate': self.safe_number(info, 'dailyInterestRate'),
7669
8169
  'amountBorrowed': None,
8170
+ 'marginMode': marginMode,
7670
8171
  'timestamp': timestamp,
7671
8172
  'datetime': self.iso8601(timestamp),
7672
- 'info': info,
7673
8173
  }
7674
8174
 
7675
8175
  async def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
7676
8176
  """
7677
8177
  closes an open position for a market
7678
- :see: https://www.bitget.com/api-doc/contract/trade/Flash-Close-Position
8178
+
8179
+ https://www.bitget.com/api-doc/contract/trade/Flash-Close-Position
8180
+
7679
8181
  :param str symbol: unified CCXT market symbol
7680
8182
  :param str [side]: one-way mode: 'buy' or 'sell', hedge-mode: 'long' or 'short'
7681
8183
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -7691,7 +8193,7 @@ class bitget(Exchange, ImplicitAPI):
7691
8193
  market = self.market(symbol)
7692
8194
  productType = None
7693
8195
  productType, params = self.handle_product_type_and_params(market, params)
7694
- request = {
8196
+ request: dict = {
7695
8197
  'symbol': market['id'],
7696
8198
  'productType': productType,
7697
8199
  }
@@ -7716,13 +8218,15 @@ class bitget(Exchange, ImplicitAPI):
7716
8218
  # }
7717
8219
  #
7718
8220
  data = self.safe_value(response, 'data', {})
7719
- order = self.safe_value(data, 'successList', [])
8221
+ order = self.safe_list(data, 'successList', [])
7720
8222
  return self.parse_order(order[0], market)
7721
8223
 
7722
8224
  async def close_all_positions(self, params={}) -> List[Position]:
7723
8225
  """
7724
8226
  closes all open positions for a market type
7725
- :see: https://www.bitget.com/api-doc/contract/trade/Flash-Close-Position
8227
+
8228
+ https://www.bitget.com/api-doc/contract/trade/Flash-Close-Position
8229
+
7726
8230
  :param dict [params]: extra parameters specific to the exchange API endpoint
7727
8231
  :param str [params.productType]: 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES'
7728
8232
  :returns dict[]: A list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
@@ -7730,7 +8234,7 @@ class bitget(Exchange, ImplicitAPI):
7730
8234
  await self.load_markets()
7731
8235
  productType = None
7732
8236
  productType, params = self.handle_product_type_and_params(None, params)
7733
- request = {
8237
+ request: dict = {
7734
8238
  'productType': productType,
7735
8239
  }
7736
8240
  response = await self.privateMixPostV2MixOrderClosePositions(self.extend(request, params))
@@ -7752,13 +8256,15 @@ class bitget(Exchange, ImplicitAPI):
7752
8256
  # }
7753
8257
  #
7754
8258
  data = self.safe_value(response, 'data', {})
7755
- orderInfo = self.safe_value(data, 'successList', [])
8259
+ orderInfo = self.safe_list(data, 'successList', [])
7756
8260
  return self.parse_positions(orderInfo, None, params)
7757
8261
 
7758
8262
  async def fetch_margin_mode(self, symbol: str, params={}) -> MarginMode:
7759
8263
  """
7760
8264
  fetches the margin mode of a trading pair
7761
- :see: https://www.bitget.com/api-doc/contract/account/Get-Single-Account
8265
+
8266
+ https://www.bitget.com/api-doc/contract/account/Get-Single-Account
8267
+
7762
8268
  :param str symbol: unified symbol of the market to fetch the margin mode for
7763
8269
  :param dict [params]: extra parameters specific to the exchange API endpoint
7764
8270
  :returns dict: a `margin mode structure <https://docs.ccxt.com/#/?id=margin-mode-structure>`
@@ -7773,7 +8279,7 @@ class bitget(Exchange, ImplicitAPI):
7773
8279
  market = self.market(symbol)
7774
8280
  productType = None
7775
8281
  productType, params = self.handle_product_type_and_params(market, params)
7776
- request = {
8282
+ request: dict = {
7777
8283
  'symbol': market['id'],
7778
8284
  'marginCoin': market['settleId'],
7779
8285
  'productType': productType,
@@ -7810,7 +8316,7 @@ class bitget(Exchange, ImplicitAPI):
7810
8316
  data = self.safe_dict(response, 'data', {})
7811
8317
  return self.parse_margin_mode(data, market)
7812
8318
 
7813
- def parse_margin_mode(self, marginMode, market=None) -> MarginMode:
8319
+ def parse_margin_mode(self, marginMode: dict, market=None) -> MarginMode:
7814
8320
  marginType = self.safe_string(marginMode, 'marginMode')
7815
8321
  marginType = 'cross' if (marginType == 'crossed') else marginType
7816
8322
  return {
@@ -7819,12 +8325,455 @@ class bitget(Exchange, ImplicitAPI):
7819
8325
  'marginMode': marginType,
7820
8326
  }
7821
8327
 
7822
- def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
8328
+ async def fetch_positions_history(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
8329
+ """
8330
+ fetches historical positions
8331
+
8332
+ https://www.bitget.com/api-doc/contract/position/Get-History-Position
8333
+
8334
+ :param str[] [symbols]: unified contract symbols
8335
+ :param int [since]: timestamp in ms of the earliest position to fetch, default=3 months ago, max range for params["until"] - since is 3 months
8336
+ :param int [limit]: the maximum amount of records to fetch, default=20, max=100
8337
+ :param dict params: extra parameters specific to the exchange api endpoint
8338
+ :param int [params.until]: timestamp in ms of the latest position to fetch, max range for params["until"] - since is 3 months
8339
+
8340
+ EXCHANGE SPECIFIC PARAMETERS
8341
+ :param str [params.productType]: USDT-FUTURES(default), COIN-FUTURES, USDC-FUTURES, SUSDT-FUTURES, SCOIN-FUTURES, or SUSDC-FUTURES
8342
+ :returns dict[]: a list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
8343
+ """
8344
+ await self.load_markets()
8345
+ until = self.safe_integer(params, 'until')
8346
+ params = self.omit(params, 'until')
8347
+ request: dict = {}
8348
+ if symbols is not None:
8349
+ symbolsLength = len(symbols)
8350
+ if symbolsLength > 0:
8351
+ market = self.market(symbols[0])
8352
+ request['symbol'] = market['id']
8353
+ if since is not None:
8354
+ request['startTime'] = since
8355
+ if limit is not None:
8356
+ request['limit'] = limit
8357
+ if until is not None:
8358
+ request['endTime'] = until
8359
+ response = await self.privateMixGetV2MixPositionHistoryPosition(self.extend(request, params))
8360
+ #
8361
+ # {
8362
+ # code: '00000',
8363
+ # msg: 'success',
8364
+ # requestTime: '1712794148791',
8365
+ # data: {
8366
+ # list: [
8367
+ # {
8368
+ # symbol: 'XRPUSDT',
8369
+ # marginCoin: 'USDT',
8370
+ # holdSide: 'long',
8371
+ # openAvgPrice: '0.64967',
8372
+ # closeAvgPrice: '0.58799',
8373
+ # marginMode: 'isolated',
8374
+ # openTotalPos: '10',
8375
+ # closeTotalPos: '10',
8376
+ # pnl: '-0.62976205',
8377
+ # netProfit: '-0.65356802',
8378
+ # totalFunding: '-0.01638',
8379
+ # openFee: '-0.00389802',
8380
+ # closeFee: '-0.00352794',
8381
+ # ctime: '1709590322199',
8382
+ # utime: '1709667583395'
8383
+ # },
8384
+ # ...
8385
+ # ]
8386
+ # }
8387
+ # }
8388
+ #
8389
+ data = self.safe_dict(response, 'data')
8390
+ responseList = self.safe_list(data, 'list')
8391
+ positions = self.parse_positions(responseList, symbols, params)
8392
+ return self.filter_by_since_limit(positions, since, limit)
8393
+
8394
+ async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
8395
+ """
8396
+ fetch a quote for converting from one currency to another
8397
+
8398
+ https://www.bitget.com/api-doc/common/convert/Get-Quoted-Price
8399
+
8400
+ :param str fromCode: the currency that you want to sell and convert from
8401
+ :param str toCode: the currency that you want to buy and convert into
8402
+ :param float [amount]: how much you want to trade in units of the from currency
8403
+ :param dict [params]: extra parameters specific to the exchange API endpoint
8404
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
8405
+ """
8406
+ await self.load_markets()
8407
+ request: dict = {
8408
+ 'fromCoin': fromCode,
8409
+ 'toCoin': toCode,
8410
+ 'fromCoinSize': self.number_to_string(amount),
8411
+ }
8412
+ response = await self.privateConvertGetV2ConvertQuotedPrice(self.extend(request, params))
8413
+ #
8414
+ # {
8415
+ # "code": "00000",
8416
+ # "msg": "success",
8417
+ # "requestTime": 1712121940158,
8418
+ # "data": {
8419
+ # "fromCoin": "USDT",
8420
+ # "fromCoinSize": "5",
8421
+ # "cnvtPrice": "0.9993007892377704",
8422
+ # "toCoin": "USDC",
8423
+ # "toCoinSize": "4.99650394",
8424
+ # "traceId": "1159288930228187140",
8425
+ # "fee": "0"
8426
+ # }
8427
+ # }
8428
+ #
8429
+ data = self.safe_dict(response, 'data', {})
8430
+ fromCurrencyId = self.safe_string(data, 'fromCoin', fromCode)
8431
+ fromCurrency = self.currency(fromCurrencyId)
8432
+ toCurrencyId = self.safe_string(data, 'toCoin', toCode)
8433
+ toCurrency = self.currency(toCurrencyId)
8434
+ return self.parse_conversion(data, fromCurrency, toCurrency)
8435
+
8436
+ async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
8437
+ """
8438
+ convert from one currency to another
8439
+
8440
+ https://www.bitget.com/api-doc/common/convert/Trade
8441
+
8442
+ :param str id: the id of the trade that you want to make
8443
+ :param str fromCode: the currency that you want to sell and convert from
8444
+ :param str toCode: the currency that you want to buy and convert into
8445
+ :param float amount: how much you want to trade in units of the from currency
8446
+ :param dict [params]: extra parameters specific to the exchange API endpoint
8447
+ :param str params['price']: the price of the conversion, obtained from fetchConvertQuote()
8448
+ :param str params['toAmount']: the amount you want to trade in units of the toCurrency, obtained from fetchConvertQuote()
8449
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
8450
+ """
8451
+ await self.load_markets()
8452
+ price = self.safe_string_2(params, 'price', 'cnvtPrice')
8453
+ if price is None:
8454
+ raise ArgumentsRequired(self.id + ' createConvertTrade() requires a price parameter')
8455
+ toAmount = self.safe_string_2(params, 'toAmount', 'toCoinSize')
8456
+ if toAmount is None:
8457
+ raise ArgumentsRequired(self.id + ' createConvertTrade() requires a toAmount parameter')
8458
+ params = self.omit(params, ['price', 'toAmount'])
8459
+ request: dict = {
8460
+ 'traceId': id,
8461
+ 'fromCoin': fromCode,
8462
+ 'toCoin': toCode,
8463
+ 'fromCoinSize': self.number_to_string(amount),
8464
+ 'toCoinSize': toAmount,
8465
+ 'cnvtPrice': price,
8466
+ }
8467
+ response = await self.privateConvertPostV2ConvertTrade(self.extend(request, params))
8468
+ #
8469
+ # {
8470
+ # "code": "00000",
8471
+ # "msg": "success",
8472
+ # "requestTime": 1712123746203,
8473
+ # "data": {
8474
+ # "cnvtPrice": "0.99940076",
8475
+ # "toCoin": "USDC",
8476
+ # "toCoinSize": "4.99700379",
8477
+ # "ts": "1712123746217"
8478
+ # }
8479
+ # }
8480
+ #
8481
+ data = self.safe_dict(response, 'data', {})
8482
+ toCurrencyId = self.safe_string(data, 'toCoin', toCode)
8483
+ toCurrency = self.currency(toCurrencyId)
8484
+ return self.parse_conversion(data, None, toCurrency)
8485
+
8486
+ async def fetch_convert_trade_history(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Conversion]:
8487
+ """
8488
+ fetch the users history of conversion trades
8489
+
8490
+ https://www.bitget.com/api-doc/common/convert/Get-Convert-Record
8491
+
8492
+ :param str [code]: the unified currency code
8493
+ :param int [since]: the earliest time in ms to fetch conversions for
8494
+ :param int [limit]: the maximum number of conversion structures to retrieve
8495
+ :param dict [params]: extra parameters specific to the exchange API endpoint
8496
+ :returns dict[]: a list of `conversion structures <https://docs.ccxt.com/#/?id=conversion-structure>`
8497
+ """
8498
+ await self.load_markets()
8499
+ request: dict = {}
8500
+ msInDay = 86400000
8501
+ now = self.milliseconds()
8502
+ if since is not None:
8503
+ request['startTime'] = since
8504
+ else:
8505
+ request['startTime'] = now - msInDay
8506
+ endTime = self.safe_string_2(params, 'endTime', 'until')
8507
+ if endTime is not None:
8508
+ request['endTime'] = endTime
8509
+ else:
8510
+ request['endTime'] = now
8511
+ if limit is not None:
8512
+ request['limit'] = limit
8513
+ params = self.omit(params, 'until')
8514
+ response = await self.privateConvertGetV2ConvertConvertRecord(self.extend(request, params))
8515
+ #
8516
+ # {
8517
+ # "code": "00000",
8518
+ # "msg": "success",
8519
+ # "requestTime": 1712124371799,
8520
+ # "data": {
8521
+ # "dataList": [
8522
+ # {
8523
+ # "id": "1159296505255219205",
8524
+ # "fromCoin": "USDT",
8525
+ # "fromCoinSize": "5",
8526
+ # "cnvtPrice": "0.99940076",
8527
+ # "toCoin": "USDC",
8528
+ # "toCoinSize": "4.99700379",
8529
+ # "ts": "1712123746217",
8530
+ # "fee": "0"
8531
+ # }
8532
+ # ],
8533
+ # "endId": "1159296505255219205"
8534
+ # }
8535
+ # }
8536
+ #
8537
+ data = self.safe_dict(response, 'data', {})
8538
+ dataList = self.safe_list(data, 'dataList', [])
8539
+ return self.parse_conversions(dataList, code, 'fromCoin', 'toCoin', since, limit)
8540
+
8541
+ def parse_conversion(self, conversion: dict, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
8542
+ #
8543
+ # fetchConvertQuote
8544
+ #
8545
+ # {
8546
+ # "fromCoin": "USDT",
8547
+ # "fromCoinSize": "5",
8548
+ # "cnvtPrice": "0.9993007892377704",
8549
+ # "toCoin": "USDC",
8550
+ # "toCoinSize": "4.99650394",
8551
+ # "traceId": "1159288930228187140",
8552
+ # "fee": "0"
8553
+ # }
8554
+ #
8555
+ # createConvertTrade
8556
+ #
8557
+ # {
8558
+ # "cnvtPrice": "0.99940076",
8559
+ # "toCoin": "USDC",
8560
+ # "toCoinSize": "4.99700379",
8561
+ # "ts": "1712123746217"
8562
+ # }
8563
+ #
8564
+ # fetchConvertTradeHistory
8565
+ #
8566
+ # {
8567
+ # "id": "1159296505255219205",
8568
+ # "fromCoin": "USDT",
8569
+ # "fromCoinSize": "5",
8570
+ # "cnvtPrice": "0.99940076",
8571
+ # "toCoin": "USDC",
8572
+ # "toCoinSize": "4.99700379",
8573
+ # "ts": "1712123746217",
8574
+ # "fee": "0"
8575
+ # }
8576
+ #
8577
+ timestamp = self.safe_integer(conversion, 'ts')
8578
+ fromCoin = self.safe_string(conversion, 'fromCoin')
8579
+ fromCode = self.safe_currency_code(fromCoin, fromCurrency)
8580
+ to = self.safe_string(conversion, 'toCoin')
8581
+ toCode = self.safe_currency_code(to, toCurrency)
8582
+ return {
8583
+ 'info': conversion,
8584
+ 'timestamp': timestamp,
8585
+ 'datetime': self.iso8601(timestamp),
8586
+ 'id': self.safe_string_2(conversion, 'id', 'traceId'),
8587
+ 'fromCurrency': fromCode,
8588
+ 'fromAmount': self.safe_number(conversion, 'fromCoinSize'),
8589
+ 'toCurrency': toCode,
8590
+ 'toAmount': self.safe_number(conversion, 'toCoinSize'),
8591
+ 'price': self.safe_number(conversion, 'cnvtPrice'),
8592
+ 'fee': self.safe_number(conversion, 'fee'),
8593
+ }
8594
+
8595
+ async def fetch_convert_currencies(self, params={}) -> Currencies:
8596
+ """
8597
+ fetches all available currencies that can be converted
8598
+
8599
+ https://www.bitget.com/api-doc/common/convert/Get-Convert-Currencies
8600
+
8601
+ :param dict [params]: extra parameters specific to the exchange API endpoint
8602
+ :returns dict: an associative dictionary of currencies
8603
+ """
8604
+ await self.load_markets()
8605
+ response = await self.privateConvertGetV2ConvertCurrencies(params)
8606
+ #
8607
+ # {
8608
+ # "code": "00000",
8609
+ # "msg": "success",
8610
+ # "requestTime": 1712121755897,
8611
+ # "data": [
8612
+ # {
8613
+ # "coin": "BTC",
8614
+ # "available": "0.00009850",
8615
+ # "maxAmount": "0.756266",
8616
+ # "minAmount": "0.00001"
8617
+ # },
8618
+ # ]
8619
+ # }
8620
+ #
8621
+ result: dict = {}
8622
+ data = self.safe_list(response, 'data', [])
8623
+ for i in range(0, len(data)):
8624
+ entry = data[i]
8625
+ id = self.safe_string(entry, 'coin')
8626
+ code = self.safe_currency_code(id)
8627
+ result[code] = {
8628
+ 'info': entry,
8629
+ 'id': id,
8630
+ 'code': code,
8631
+ 'networks': None,
8632
+ 'type': None,
8633
+ 'name': None,
8634
+ 'active': None,
8635
+ 'deposit': None,
8636
+ 'withdraw': self.safe_number(entry, 'available'),
8637
+ 'fee': None,
8638
+ 'precision': None,
8639
+ 'limits': {
8640
+ 'amount': {
8641
+ 'min': self.safe_number(entry, 'minAmount'),
8642
+ 'max': self.safe_number(entry, 'maxAmount'),
8643
+ },
8644
+ 'withdraw': {
8645
+ 'min': None,
8646
+ 'max': None,
8647
+ },
8648
+ 'deposit': {
8649
+ 'min': None,
8650
+ 'max': None,
8651
+ },
8652
+ },
8653
+ 'created': None,
8654
+ }
8655
+ return result
8656
+
8657
+ async def fetch_funding_interval(self, symbol: str, params={}) -> FundingRate:
8658
+ """
8659
+ fetch the current funding rate interval
8660
+
8661
+ https://www.bitget.com/api-doc/contract/market/Get-Symbol-Next-Funding-Time
8662
+
8663
+ :param str symbol: unified market symbol
8664
+ :param dict [params]: extra parameters specific to the exchange API endpoint
8665
+ :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
8666
+ """
8667
+ await self.load_markets()
8668
+ sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
8669
+ market = None
8670
+ if sandboxMode:
8671
+ sandboxSymbol = self.convert_symbol_for_sandbox(symbol)
8672
+ market = self.market(sandboxSymbol)
8673
+ else:
8674
+ market = self.market(symbol)
8675
+ productType = None
8676
+ productType, params = self.handle_product_type_and_params(market, params)
8677
+ request: dict = {
8678
+ 'symbol': market['id'],
8679
+ 'productType': productType,
8680
+ }
8681
+ response = await self.publicMixGetV2MixMarketFundingTime(self.extend(request, params))
8682
+ #
8683
+ # {
8684
+ # "code": "00000",
8685
+ # "msg": "success",
8686
+ # "requestTime": 1727930153888,
8687
+ # "data": [
8688
+ # {
8689
+ # "symbol": "BTCUSDT",
8690
+ # "nextFundingTime": "1727942400000",
8691
+ # "ratePeriod": "8"
8692
+ # }
8693
+ # ]
8694
+ # }
8695
+ #
8696
+ data = self.safe_list(response, 'data', [])
8697
+ first = self.safe_dict(data, 0, {})
8698
+ return self.parse_funding_rate(first, market)
8699
+
8700
+ async def fetch_long_short_ratio_history(self, symbol: Str = None, timeframe: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LongShortRatio]:
8701
+ """
8702
+ fetches the long short ratio history for a unified market symbol
8703
+
8704
+ https://www.bitget.com/api-doc/common/apidata/Margin-Ls-Ratio
8705
+ https://www.bitget.com/api-doc/common/apidata/Account-Long-Short
8706
+
8707
+ :param str symbol: unified symbol of the market to fetch the long short ratio for
8708
+ :param str [timeframe]: the period for the ratio
8709
+ :param int [since]: the earliest time in ms to fetch ratios for
8710
+ :param int [limit]: the maximum number of long short ratio structures to retrieve
8711
+ :param dict [params]: extra parameters specific to the exchange API endpoint
8712
+ :returns dict[]: an array of `long short ratio structures <https://docs.ccxt.com/#/?id=long-short-ratio-structure>`
8713
+ """
8714
+ await self.load_markets()
8715
+ market = self.market(symbol)
8716
+ request: dict = {
8717
+ 'symbol': market['id'],
8718
+ }
8719
+ if timeframe is not None:
8720
+ request['period'] = timeframe
8721
+ response = None
8722
+ if market['swap'] or market['future']:
8723
+ response = await self.publicMixGetV2MixMarketAccountLongShort(self.extend(request, params))
8724
+ #
8725
+ # {
8726
+ # "code": "00000",
8727
+ # "msg": "success",
8728
+ # "requestTime": 1729321233281,
8729
+ # "data": [
8730
+ # {
8731
+ # "longAccountRatio": "0.58",
8732
+ # "shortAccountRatio": "0.42",
8733
+ # "longShortAccountRatio": "0.0138",
8734
+ # "ts": "1729312200000"
8735
+ # },
8736
+ # ]
8737
+ # }
8738
+ #
8739
+ else:
8740
+ response = await self.publicMarginGetV2MarginMarketLongShortRatio(self.extend(request, params))
8741
+ #
8742
+ # {
8743
+ # "code": "00000",
8744
+ # "msg": "success",
8745
+ # "requestTime": 1729306974712,
8746
+ # "data": [
8747
+ # {
8748
+ # "longShortRatio": "40.66",
8749
+ # "ts": "1729306800000"
8750
+ # },
8751
+ # ]
8752
+ # }
8753
+ #
8754
+ data = self.safe_list(response, 'data', [])
8755
+ return self.parse_long_short_ratio_history(data, market)
8756
+
8757
+ def parse_long_short_ratio(self, info: dict, market: Market = None) -> LongShortRatio:
8758
+ marketId = self.safe_string(info, 'symbol')
8759
+ timestamp = self.safe_integer_omit_zero(info, 'ts')
8760
+ return {
8761
+ 'info': info,
8762
+ 'symbol': self.safe_symbol(marketId, market, None, 'contract'),
8763
+ 'timestamp': timestamp,
8764
+ 'datetime': self.iso8601(timestamp),
8765
+ 'timeframe': None,
8766
+ 'longShortRatio': self.safe_number_2(info, 'longShortRatio', 'longShortAccountRatio'),
8767
+ }
8768
+
8769
+ def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
7823
8770
  if not response:
7824
8771
  return None # fallback to default error handler
7825
8772
  #
7826
8773
  # spot
7827
8774
  #
8775
+ # {"code":"00000","msg":"success","requestTime":1713294492511,"data":[...]}"
8776
+ #
7828
8777
  # {"status":"fail","err_code":"01001","err_msg":"系统异常,请稍后重试"}
7829
8778
  # {"status":"error","ts":1595594160149,"err_code":"invalid-parameter","err_msg":"invalid size, valid range: [1,2000]"}
7830
8779
  # {"status":"error","ts":1595684716042,"err_code":"invalid-parameter","err_msg":"illegal sign invalid"}
@@ -7846,13 +8795,13 @@ class bitget(Exchange, ImplicitAPI):
7846
8795
  # {"code":"40108","msg":"","requestTime":1595885064600,"data":null}
7847
8796
  # {"order_id":"513468410013679613","client_oid":null,"symbol":"ethusd","result":false,"err_code":"order_no_exist_error","err_msg":"订单不存在!"}
7848
8797
  #
7849
- message = self.safe_string(response, 'err_msg')
7850
- errorCode = self.safe_string_2(response, 'code', 'err_code')
8798
+ message = self.safe_string_2(response, 'err_msg', 'msg')
7851
8799
  feedback = self.id + ' ' + body
7852
- nonEmptyMessage = ((message is not None) and (message != ''))
8800
+ nonEmptyMessage = ((message is not None) and (message != '') and (message != 'success'))
7853
8801
  if nonEmptyMessage:
7854
8802
  self.throw_exactly_matched_exception(self.exceptions['exact'], message, feedback)
7855
8803
  self.throw_broadly_matched_exception(self.exceptions['broad'], message, feedback)
8804
+ errorCode = self.safe_string_2(response, 'code', 'err_code')
7856
8805
  nonZeroErrorCode = (errorCode is not None) and (errorCode != '00000')
7857
8806
  if nonZeroErrorCode:
7858
8807
  self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
@@ -7860,6 +8809,9 @@ class bitget(Exchange, ImplicitAPI):
7860
8809
  raise ExchangeError(feedback) # unknown message
7861
8810
  return None
7862
8811
 
8812
+ def nonce(self):
8813
+ return self.milliseconds() - self.options['timeDifference']
8814
+
7863
8815
  def sign(self, path, api=[], method='GET', params={}, headers=None, body=None):
7864
8816
  signed = api[0] == 'private'
7865
8817
  endpoint = api[1]
@@ -7875,7 +8827,7 @@ class bitget(Exchange, ImplicitAPI):
7875
8827
  url = url + '?' + self.urlencode(query)
7876
8828
  if signed:
7877
8829
  self.check_required_credentials()
7878
- timestamp = str(self.milliseconds())
8830
+ timestamp = str(self.nonce())
7879
8831
  auth = timestamp + method + payload
7880
8832
  if method == 'POST':
7881
8833
  body = self.json(params)