ccxt 4.2.76__py2.py3-none-any.whl → 4.4.48__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (546) hide show
  1. ccxt/__init__.py +36 -14
  2. ccxt/abstract/alpaca.py +4 -0
  3. ccxt/abstract/bigone.py +1 -1
  4. ccxt/abstract/binance.py +112 -48
  5. ccxt/abstract/binancecoinm.py +112 -48
  6. ccxt/abstract/binanceus.py +147 -83
  7. ccxt/abstract/binanceusdm.py +112 -48
  8. ccxt/abstract/bingx.py +133 -78
  9. ccxt/abstract/bitbank.py +5 -0
  10. ccxt/abstract/bitfinex.py +136 -65
  11. ccxt/abstract/bitfinex1.py +69 -0
  12. ccxt/abstract/bitflyer.py +1 -0
  13. ccxt/abstract/bitget.py +8 -1
  14. ccxt/abstract/bitmart.py +13 -1
  15. ccxt/abstract/bitopro.py +1 -0
  16. ccxt/abstract/bitpanda.py +0 -12
  17. ccxt/abstract/bitrue.py +3 -3
  18. ccxt/abstract/bitstamp.py +26 -3
  19. ccxt/abstract/blofin.py +24 -0
  20. ccxt/abstract/btcbox.py +1 -0
  21. ccxt/abstract/bybit.py +29 -14
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbase.py +6 -0
  24. ccxt/abstract/coinbaseadvanced.py +94 -0
  25. ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
  26. ccxt/abstract/coinbaseinternational.py +1 -1
  27. ccxt/abstract/coincatch.py +94 -0
  28. ccxt/abstract/coinex.py +233 -123
  29. ccxt/abstract/coinmetro.py +1 -0
  30. ccxt/abstract/cryptocom.py +14 -0
  31. ccxt/abstract/defx.py +69 -0
  32. ccxt/abstract/deribit.py +1 -0
  33. ccxt/abstract/digifinex.py +1 -0
  34. ccxt/abstract/ellipx.py +25 -0
  35. ccxt/abstract/gate.py +20 -0
  36. ccxt/abstract/gateio.py +20 -0
  37. ccxt/abstract/gemini.py +1 -0
  38. ccxt/abstract/hashkey.py +67 -0
  39. ccxt/abstract/hyperliquid.py +1 -1
  40. ccxt/abstract/independentreserve.py +6 -0
  41. ccxt/abstract/kraken.py +4 -3
  42. ccxt/abstract/krakenfutures.py +4 -0
  43. ccxt/abstract/kucoin.py +25 -0
  44. ccxt/abstract/kucoinfutures.py +35 -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 +3513 -1511
  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 +3105 -881
  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 +239 -50
  89. ccxt/async_support/bitget.py +1513 -563
  90. ccxt/async_support/bithumb.py +201 -67
  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 +403 -150
  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 +2326 -1255
  107. ccxt/async_support/cex.py +1409 -1329
  108. ccxt/async_support/coinbase.py +1455 -288
  109. ccxt/async_support/coinbaseadvanced.py +17 -0
  110. ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
  111. ccxt/async_support/coinbaseinternational.py +428 -88
  112. ccxt/async_support/coincatch.py +5152 -0
  113. ccxt/async_support/coincheck.py +121 -38
  114. ccxt/async_support/coinex.py +4020 -3339
  115. ccxt/async_support/coinlist.py +273 -116
  116. ccxt/async_support/coinmate.py +204 -97
  117. ccxt/async_support/coinmetro.py +203 -110
  118. ccxt/async_support/coinone.py +142 -68
  119. ccxt/async_support/coinsph.py +206 -89
  120. ccxt/async_support/coinspot.py +137 -62
  121. ccxt/async_support/cryptocom.py +515 -185
  122. ccxt/async_support/currencycom.py +203 -85
  123. ccxt/async_support/defx.py +2066 -0
  124. ccxt/async_support/delta.py +467 -158
  125. ccxt/async_support/deribit.py +558 -324
  126. ccxt/async_support/digifinex.py +340 -223
  127. ccxt/async_support/ellipx.py +1826 -0
  128. ccxt/async_support/exmo.py +259 -128
  129. ccxt/async_support/gate.py +1473 -464
  130. ccxt/async_support/gemini.py +206 -84
  131. ccxt/async_support/hashkey.py +4164 -0
  132. ccxt/async_support/hitbtc.py +334 -178
  133. ccxt/async_support/hollaex.py +134 -83
  134. ccxt/async_support/htx.py +1095 -563
  135. ccxt/async_support/huobijp.py +105 -56
  136. ccxt/async_support/hyperliquid.py +1634 -269
  137. ccxt/async_support/idex.py +148 -95
  138. ccxt/async_support/independentreserve.py +236 -31
  139. ccxt/async_support/indodax.py +165 -62
  140. ccxt/async_support/kraken.py +871 -354
  141. ccxt/async_support/krakenfutures.py +324 -100
  142. ccxt/async_support/kucoin.py +1050 -355
  143. ccxt/async_support/kucoinfutures.py +1004 -149
  144. ccxt/async_support/kuna.py +138 -106
  145. ccxt/async_support/latoken.py +135 -79
  146. ccxt/async_support/lbank.py +290 -113
  147. ccxt/async_support/luno.py +112 -62
  148. ccxt/async_support/lykke.py +104 -55
  149. ccxt/async_support/mercado.py +36 -29
  150. ccxt/async_support/mexc.py +995 -429
  151. ccxt/async_support/myokx.py +43 -0
  152. ccxt/async_support/ndax.py +163 -82
  153. ccxt/async_support/novadax.py +121 -75
  154. ccxt/async_support/oceanex.py +175 -59
  155. ccxt/async_support/okcoin.py +222 -163
  156. ccxt/async_support/okx.py +1777 -455
  157. ccxt/async_support/onetrading.py +132 -414
  158. ccxt/async_support/oxfun.py +2832 -0
  159. ccxt/async_support/p2b.py +79 -51
  160. ccxt/async_support/paradex.py +2017 -0
  161. ccxt/async_support/paymium.py +56 -32
  162. ccxt/async_support/phemex.py +572 -196
  163. ccxt/async_support/poloniex.py +218 -95
  164. ccxt/async_support/poloniexfutures.py +260 -92
  165. ccxt/async_support/probit.py +143 -110
  166. ccxt/async_support/timex.py +123 -70
  167. ccxt/async_support/tokocrypto.py +129 -93
  168. ccxt/async_support/tradeogre.py +39 -25
  169. ccxt/async_support/upbit.py +322 -113
  170. ccxt/async_support/vertex.py +2983 -0
  171. ccxt/async_support/wavesexchange.py +227 -173
  172. ccxt/async_support/wazirx.py +145 -65
  173. ccxt/async_support/whitebit.py +533 -138
  174. ccxt/async_support/woo.py +1155 -295
  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 +1729 -482
  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 +3513 -1511
  187. ccxt/binancecoinm.py +2 -1
  188. ccxt/binanceus.py +12 -1
  189. ccxt/binanceusdm.py +3 -1
  190. ccxt/bingx.py +3105 -881
  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 +239 -50
  197. ccxt/bitget.py +1513 -563
  198. ccxt/bithumb.py +200 -67
  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 +403 -150
  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 +2326 -1255
  215. ccxt/cex.py +1408 -1329
  216. ccxt/coinbase.py +1455 -288
  217. ccxt/coinbaseadvanced.py +17 -0
  218. ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
  219. ccxt/coinbaseinternational.py +428 -88
  220. ccxt/coincatch.py +5152 -0
  221. ccxt/coincheck.py +121 -38
  222. ccxt/coinex.py +4020 -3339
  223. ccxt/coinlist.py +273 -116
  224. ccxt/coinmate.py +204 -97
  225. ccxt/coinmetro.py +203 -110
  226. ccxt/coinone.py +142 -68
  227. ccxt/coinsph.py +206 -89
  228. ccxt/coinspot.py +137 -62
  229. ccxt/cryptocom.py +515 -185
  230. ccxt/currencycom.py +203 -85
  231. ccxt/defx.py +2065 -0
  232. ccxt/delta.py +467 -158
  233. ccxt/deribit.py +558 -324
  234. ccxt/digifinex.py +340 -223
  235. ccxt/ellipx.py +1826 -0
  236. ccxt/exmo.py +259 -128
  237. ccxt/gate.py +1473 -464
  238. ccxt/gemini.py +206 -84
  239. ccxt/hashkey.py +4164 -0
  240. ccxt/hitbtc.py +334 -178
  241. ccxt/hollaex.py +134 -83
  242. ccxt/htx.py +1095 -563
  243. ccxt/huobijp.py +105 -56
  244. ccxt/hyperliquid.py +1633 -269
  245. ccxt/idex.py +148 -95
  246. ccxt/independentreserve.py +235 -31
  247. ccxt/indodax.py +165 -62
  248. ccxt/kraken.py +871 -354
  249. ccxt/krakenfutures.py +324 -100
  250. ccxt/kucoin.py +1050 -355
  251. ccxt/kucoinfutures.py +1004 -149
  252. ccxt/kuna.py +138 -106
  253. ccxt/latoken.py +135 -79
  254. ccxt/lbank.py +290 -113
  255. ccxt/luno.py +112 -62
  256. ccxt/lykke.py +104 -55
  257. ccxt/mercado.py +36 -29
  258. ccxt/mexc.py +994 -429
  259. ccxt/myokx.py +43 -0
  260. ccxt/ndax.py +163 -82
  261. ccxt/novadax.py +121 -75
  262. ccxt/oceanex.py +175 -59
  263. ccxt/okcoin.py +222 -163
  264. ccxt/okx.py +1777 -455
  265. ccxt/onetrading.py +132 -414
  266. ccxt/oxfun.py +2831 -0
  267. ccxt/p2b.py +79 -51
  268. ccxt/paradex.py +2017 -0
  269. ccxt/paymium.py +56 -32
  270. ccxt/phemex.py +572 -196
  271. ccxt/poloniex.py +218 -95
  272. ccxt/poloniexfutures.py +260 -92
  273. ccxt/pro/__init__.py +29 -5
  274. ccxt/pro/alpaca.py +32 -17
  275. ccxt/pro/ascendex.py +63 -15
  276. ccxt/pro/bequant.py +4 -0
  277. ccxt/pro/binance.py +1596 -329
  278. ccxt/pro/binancecoinm.py +1 -0
  279. ccxt/pro/binanceus.py +2 -9
  280. ccxt/pro/binanceusdm.py +2 -0
  281. ccxt/pro/bingx.py +527 -134
  282. ccxt/pro/bitcoincom.py +4 -1
  283. ccxt/pro/bitfinex.py +731 -266
  284. ccxt/pro/bitfinex1.py +635 -0
  285. ccxt/pro/bitget.py +726 -357
  286. ccxt/pro/bithumb.py +380 -0
  287. ccxt/pro/bitmart.py +138 -39
  288. ccxt/pro/bitmex.py +199 -40
  289. ccxt/pro/bitopro.py +25 -13
  290. ccxt/pro/bitrue.py +31 -32
  291. ccxt/pro/bitstamp.py +7 -6
  292. ccxt/pro/bitvavo.py +204 -82
  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 +967 -661
  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 +168 -32
  309. ccxt/pro/exmo.py +253 -21
  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 +93 -34
  336. ccxt/pro/poloniex.py +129 -50
  337. ccxt/pro/poloniexfutures.py +53 -32
  338. ccxt/pro/probit.py +93 -86
  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 +486 -70
  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} +465 -407
  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} +465 -409
  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 +1155 -295
  490. ccxt/woofipro.py +2716 -0
  491. ccxt/xt.py +4627 -0
  492. ccxt/yobit.py +159 -92
  493. ccxt/zaif.py +80 -33
  494. ccxt/zonda.py +140 -69
  495. ccxt-4.4.48.dist-info/LICENSE.txt +21 -0
  496. ccxt-4.4.48.dist-info/METADATA +646 -0
  497. ccxt-4.4.48.dist-info/RECORD +669 -0
  498. {ccxt-4.2.76.dist-info → ccxt-4.4.48.dist-info}/WHEEL +1 -1
  499. ccxt/abstract/bitbay.py +0 -47
  500. ccxt/abstract/bitfinex2.py +0 -139
  501. ccxt/abstract/hitbtc3.py +0 -115
  502. ccxt/async_support/bitbay.py +0 -17
  503. ccxt/async_support/bitfinex2.py +0 -3496
  504. ccxt/async_support/flowbtc.py +0 -34
  505. ccxt/bitbay.py +0 -17
  506. ccxt/bitfinex2.py +0 -3496
  507. ccxt/flowbtc.py +0 -34
  508. ccxt/hitbtc3.py +0 -16
  509. ccxt/pro/bitfinex2.py +0 -1081
  510. ccxt/test/base/__init__.py +0 -28
  511. ccxt/test/base/test_account.py +0 -26
  512. ccxt/test/base/test_balance.py +0 -56
  513. ccxt/test/base/test_borrow_interest.py +0 -35
  514. ccxt/test/base/test_borrow_rate.py +0 -32
  515. ccxt/test/base/test_calculate_fee.py +0 -51
  516. ccxt/test/base/test_crypto.py +0 -127
  517. ccxt/test/base/test_currency.py +0 -76
  518. ccxt/test/base/test_datetime.py +0 -103
  519. ccxt/test/base/test_decimal_to_precision.py +0 -392
  520. ccxt/test/base/test_deep_extend.py +0 -68
  521. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  522. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  523. ccxt/test/base/test_funding_rate_history.py +0 -29
  524. ccxt/test/base/test_last_price.py +0 -32
  525. ccxt/test/base/test_ledger_entry.py +0 -45
  526. ccxt/test/base/test_ledger_item.py +0 -48
  527. ccxt/test/base/test_leverage_tier.py +0 -33
  528. ccxt/test/base/test_margin_mode.py +0 -24
  529. ccxt/test/base/test_margin_modification.py +0 -35
  530. ccxt/test/base/test_market.py +0 -190
  531. ccxt/test/base/test_number.py +0 -411
  532. ccxt/test/base/test_ohlcv.py +0 -32
  533. ccxt/test/base/test_open_interest.py +0 -32
  534. ccxt/test/base/test_order.py +0 -64
  535. ccxt/test/base/test_order_book.py +0 -63
  536. ccxt/test/base/test_position.py +0 -60
  537. ccxt/test/base/test_shared_methods.py +0 -345
  538. ccxt/test/base/test_status.py +0 -24
  539. ccxt/test/base/test_throttle.py +0 -126
  540. ccxt/test/base/test_ticker.py +0 -86
  541. ccxt/test/base/test_trade.py +0 -47
  542. ccxt/test/base/test_trading_fee.py +0 -26
  543. ccxt/test/base/test_transaction.py +0 -39
  544. ccxt-4.2.76.dist-info/METADATA +0 -626
  545. ccxt-4.2.76.dist-info/RECORD +0 -534
  546. {ccxt-4.2.76.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
@@ -7,16 +7,16 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.gate import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Balances, Currency, FundingHistory, Greeks, Int, Leverage, Leverages, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
+ from ccxt.base.types import Balances, BorrowInterest, Bool, Currencies, Currency, DepositAddress, FundingHistory, Greeks, Int, LedgerEntry, Leverage, Leverages, LeverageTier, LeverageTiers, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
+ from ccxt.base.errors import AuthenticationError
13
14
  from ccxt.base.errors import PermissionDenied
14
15
  from ccxt.base.errors import AccountNotEnabled
15
16
  from ccxt.base.errors import AccountSuspended
16
17
  from ccxt.base.errors import ArgumentsRequired
17
18
  from ccxt.base.errors import BadRequest
18
19
  from ccxt.base.errors import BadSymbol
19
- from ccxt.base.errors import BadResponse
20
20
  from ccxt.base.errors import InsufficientFunds
21
21
  from ccxt.base.errors import InvalidOrder
22
22
  from ccxt.base.errors import OrderNotFound
@@ -24,7 +24,7 @@ from ccxt.base.errors import OrderImmediatelyFillable
24
24
  from ccxt.base.errors import NotSupported
25
25
  from ccxt.base.errors import RateLimitExceeded
26
26
  from ccxt.base.errors import ExchangeNotAvailable
27
- from ccxt.base.errors import AuthenticationError
27
+ from ccxt.base.errors import BadResponse
28
28
  from ccxt.base.decimal_to_precision import TICK_SIZE
29
29
  from ccxt.base.precise import Precise
30
30
 
@@ -41,7 +41,7 @@ class gate(Exchange, ImplicitAPI):
41
41
  'certified': True,
42
42
  'pro': True,
43
43
  'urls': {
44
- 'logo': 'https://user-images.githubusercontent.com/1294454/31784029-0313c702-b509-11e7-9ccc-bc0da6a0e435.jpg',
44
+ 'logo': 'https://github.com/user-attachments/assets/64f988c5-07b6-4652-b5c1-679a6bf67c85',
45
45
  'doc': 'https://www.gate.io/docs/developers/apiv4/en/',
46
46
  'www': 'https://gate.io/',
47
47
  'api': {
@@ -68,6 +68,7 @@ class gate(Exchange, ImplicitAPI):
68
68
  'rebate': 'https://api.gateio.ws/api/v4',
69
69
  'earn': 'https://api.gateio.ws/api/v4',
70
70
  'account': 'https://api.gateio.ws/api/v4',
71
+ 'loan': 'https://api.gateio.ws/api/v4',
71
72
  },
72
73
  },
73
74
  'test': {
@@ -99,6 +100,8 @@ class gate(Exchange, ImplicitAPI):
99
100
  'borrowIsolatedMargin': True,
100
101
  'cancelAllOrders': True,
101
102
  'cancelOrder': True,
103
+ 'cancelOrders': True,
104
+ 'cancelOrdersForSymbols': True,
102
105
  'createMarketBuyOrderWithCost': True,
103
106
  'createMarketOrder': True,
104
107
  'createMarketOrderWithCost': False,
@@ -115,6 +118,7 @@ class gate(Exchange, ImplicitAPI):
115
118
  'createTriggerOrder': True,
116
119
  'editOrder': True,
117
120
  'fetchBalance': True,
121
+ 'fetchBorrowInterest': True,
118
122
  'fetchBorrowRateHistories': False,
119
123
  'fetchBorrowRateHistory': False,
120
124
  'fetchClosedOrders': True,
@@ -122,6 +126,8 @@ class gate(Exchange, ImplicitAPI):
122
126
  'fetchCrossBorrowRates': False,
123
127
  'fetchCurrencies': True,
124
128
  'fetchDepositAddress': True,
129
+ 'fetchDepositAddresses': False,
130
+ 'fetchDepositAddressesByNetwork': False,
125
131
  'fetchDeposits': True,
126
132
  'fetchDepositWithdrawFee': 'emulated',
127
133
  'fetchDepositWithdrawFees': True,
@@ -138,6 +144,7 @@ class gate(Exchange, ImplicitAPI):
138
144
  'fetchLeverages': True,
139
145
  'fetchLeverageTiers': True,
140
146
  'fetchLiquidations': True,
147
+ 'fetchMarginAdjustmentHistory': False,
141
148
  'fetchMarginMode': False,
142
149
  'fetchMarketLeverageTiers': True,
143
150
  'fetchMarkets': True,
@@ -150,16 +157,20 @@ class gate(Exchange, ImplicitAPI):
150
157
  'fetchOpenInterest': False,
151
158
  'fetchOpenInterestHistory': True,
152
159
  'fetchOpenOrders': True,
160
+ 'fetchOption': True,
161
+ 'fetchOptionChain': True,
153
162
  'fetchOrder': True,
154
163
  'fetchOrderBook': True,
155
164
  'fetchPosition': True,
165
+ 'fetchPositionHistory': 'emulated',
156
166
  'fetchPositionMode': False,
157
167
  'fetchPositions': True,
168
+ 'fetchPositionsHistory': True,
158
169
  'fetchPremiumIndexOHLCV': False,
159
170
  'fetchSettlementHistory': True,
160
171
  'fetchTicker': True,
161
172
  'fetchTickers': True,
162
- 'fetchTime': False,
173
+ 'fetchTime': True,
163
174
  'fetchTrades': True,
164
175
  'fetchTradingFee': True,
165
176
  'fetchTradingFees': True,
@@ -170,6 +181,7 @@ class gate(Exchange, ImplicitAPI):
170
181
  'reduceMargin': True,
171
182
  'repayCrossMargin': True,
172
183
  'repayIsolatedMargin': True,
184
+ 'sandbox': True,
173
185
  'setLeverage': True,
174
186
  'setMarginMode': False,
175
187
  'setPositionMode': True,
@@ -228,6 +240,7 @@ class gate(Exchange, ImplicitAPI):
228
240
  '{settle}/contract_stats': 1,
229
241
  '{settle}/index_constituents/{index}': 1,
230
242
  '{settle}/liq_orders': 1,
243
+ '{settle}/risk_limit_tiers': 1,
231
244
  },
232
245
  },
233
246
  'delivery': {
@@ -269,6 +282,7 @@ class gate(Exchange, ImplicitAPI):
269
282
  'withdrawals': {
270
283
  'post': {
271
284
  'withdrawals': 20, # 1r/s cost = 20 / 1 = 20
285
+ 'push': 1,
272
286
  },
273
287
  'delete': {
274
288
  'withdrawals/{withdrawal_id}': 1,
@@ -280,6 +294,7 @@ class gate(Exchange, ImplicitAPI):
280
294
  'withdrawals': 1,
281
295
  'deposits': 1,
282
296
  'sub_account_transfers': 1,
297
+ 'order_status': 1,
283
298
  'withdraw_status': 1,
284
299
  'sub_account_balances': 2.5,
285
300
  'sub_account_margin_balances': 2.5,
@@ -290,6 +305,7 @@ class gate(Exchange, ImplicitAPI):
290
305
  'total_balance': 2.5,
291
306
  'small_balance': 1,
292
307
  'small_balance_history': 1,
308
+ 'push': 1,
293
309
  },
294
310
  'post': {
295
311
  'transfers': 2.5, # 8r/s cost = 20 / 8 = 2.5
@@ -328,10 +344,21 @@ class gate(Exchange, ImplicitAPI):
328
344
  'loan_records': 20 / 15,
329
345
  'interest_records': 20 / 15,
330
346
  'estimate_rate': 20 / 15,
347
+ 'currency_discount_tiers': 20 / 15,
348
+ 'risk_units': 20 / 15,
349
+ 'unified_mode': 20 / 15,
350
+ 'loan_margin_tiers': 20 / 15,
351
+ 'leverage/user_currency_config': 20 / 15,
352
+ 'leverage/user_currency_setting': 20 / 15,
331
353
  },
332
354
  'post': {
333
355
  'account_mode': 20 / 15,
334
356
  'loans': 200 / 15, # 15r/10s cost = 20 / 1.5 = 13.33
357
+ 'portfolio_calculator': 20 / 15,
358
+ 'leverage/user_currency_setting': 20 / 15,
359
+ },
360
+ 'put': {
361
+ 'unified_mode': 20 / 15,
335
362
  },
336
363
  },
337
364
  'spot': {
@@ -508,9 +535,13 @@ class gate(Exchange, ImplicitAPI):
508
535
  'orders': 20 / 15,
509
536
  'orders/{order_id}': 20 / 15,
510
537
  'my_trades': 20 / 15,
538
+ 'mmp': 20 / 15,
511
539
  },
512
540
  'post': {
513
541
  'orders': 20 / 15,
542
+ 'countdown_cancel_all': 20 / 15,
543
+ 'mmp': 20 / 15,
544
+ 'mmp/reset': 20 / 15,
514
545
  },
515
546
  'delete': {
516
547
  'orders': 20 / 15,
@@ -554,6 +585,7 @@ class gate(Exchange, ImplicitAPI):
554
585
  'multi_collateral/currencies': 20 / 15,
555
586
  'multi_collateral/ltv': 20 / 15,
556
587
  'multi_collateral/fixed_rate': 20 / 15,
588
+ 'multi_collateral/current_rate': 20 / 15,
557
589
  },
558
590
  'post': {
559
591
  'collateral/orders': 20 / 15,
@@ -567,8 +599,10 @@ class gate(Exchange, ImplicitAPI):
567
599
  'account': {
568
600
  'get': {
569
601
  'detail': 20 / 15,
602
+ 'rate_limit': 20 / 15,
570
603
  'stp_groups': 20 / 15,
571
604
  'stp_groups/{stp_id}/users': 20 / 15,
605
+ 'stp_groups/debit_fee': 20 / 15,
572
606
  },
573
607
  'post': {
574
608
  'stp_groups': 20 / 15,
@@ -602,22 +636,25 @@ class gate(Exchange, ImplicitAPI):
602
636
  },
603
637
  # copied from gatev2
604
638
  'commonCurrencies': {
639
+ 'ORT': 'XREATORS',
640
+ 'ASS': 'ASSF',
605
641
  '88MPH': 'MPH',
606
- 'AXIS': 'Axis DeFi',
607
- 'BIFI': 'Bitcoin File',
608
- 'BOX': 'DefiBox',
609
- 'BYN': 'BeyondFi',
610
- 'EGG': 'Goose Finance',
611
- 'GTC': 'Game.com', # conflict with Gitcoin and Gastrocoin
612
- 'GTC_HT': 'Game.com HT',
613
- 'GTC_BSC': 'Game.com BSC',
614
- 'HIT': 'HitChain',
615
- 'MM': 'Million', # conflict with MilliMeter
616
- 'MPH': 'Morpher', # conflict with 88MPH
617
- 'POINT': 'GatePoint',
618
- 'RAI': 'Rai Reflex Index', # conflict with RAI Finance
619
- 'SBTC': 'Super Bitcoin',
620
- 'TNC': 'Trinity Network Credit',
642
+ 'AXIS': 'AXISDEFI',
643
+ 'BIFI': 'BITCOINFILE',
644
+ 'BOX': 'DEFIBOX',
645
+ 'BYN': 'BEYONDFI',
646
+ 'EGG': 'GOOSEFINANCE',
647
+ 'GTC': 'GAMECOM', # conflict with Gitcoin and Gastrocoin
648
+ 'GTC_HT': 'GAMECOM_HT',
649
+ 'GTC_BSC': 'GAMECOM_BSC',
650
+ 'HIT': 'HITCHAIN',
651
+ 'MM': 'MILLION', # conflict with MilliMeter
652
+ 'MPH': 'MORPHER', # conflict with 88MPH
653
+ 'POINT': 'GATEPOINT',
654
+ 'RAI': 'RAIREFLEXINDEX', # conflict with RAI Finance
655
+ 'RED': 'RedLang',
656
+ 'SBTC': 'SUPERBITCOIN',
657
+ 'TNC': 'TRINITYNETWORKCREDIT',
621
658
  'VAI': 'VAIOT',
622
659
  'TRAC': 'TRACO', # conflict with OriginTrail(TRAC)
623
660
  },
@@ -629,11 +666,17 @@ class gate(Exchange, ImplicitAPI):
629
666
  'X-Gate-Channel-Id': 'ccxt',
630
667
  },
631
668
  'options': {
669
+ 'timeDifference': 0, # the difference between system clock and exchange clock
670
+ 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
632
671
  'sandboxMode': False,
672
+ 'unifiedAccount': None,
633
673
  'createOrder': {
634
674
  'expiration': 86400, # for conditional orders
635
675
  },
676
+ 'createMarketBuyOrderRequiresPrice': True,
636
677
  'networks': {
678
+ 'LINEA': 'LINEAETH',
679
+ 'KON': 'KONET',
637
680
  'AVAXC': 'AVAX_C',
638
681
  'BEP20': 'BSC',
639
682
  'EOS': 'EOS',
@@ -646,6 +689,9 @@ class gate(Exchange, ImplicitAPI):
646
689
  'OPTIMISM': 'OPETH',
647
690
  'POLKADOT': 'DOTSM',
648
691
  'TRC20': 'TRX',
692
+ 'LUNA': 'LUNC',
693
+ 'BASE': 'BASEEVM',
694
+ 'BRC20': 'BTCBRC',
649
695
  },
650
696
  'timeInForce': {
651
697
  'GTC': 'gtc',
@@ -668,7 +714,6 @@ class gate(Exchange, ImplicitAPI):
668
714
  'option': 'options',
669
715
  'options': 'options',
670
716
  },
671
- 'defaultType': 'spot',
672
717
  'swap': {
673
718
  'fetchMarkets': {
674
719
  'settlementCurrencies': ['usdt', 'btc'],
@@ -680,6 +725,114 @@ class gate(Exchange, ImplicitAPI):
680
725
  },
681
726
  },
682
727
  },
728
+ 'features': {
729
+ 'default': {
730
+ 'sandbox': True,
731
+ 'createOrder': {
732
+ 'marginMode': True,
733
+ 'triggerPrice': True,
734
+ 'triggerDirection': True, # todo: implementation edit needed
735
+ 'triggerPriceType': None,
736
+ 'stopLossPrice': True,
737
+ 'takeProfitPrice': True,
738
+ 'attachedStopLossTakeProfit': None,
739
+ 'timeInForce': {
740
+ 'IOC': True,
741
+ 'FOK': True,
742
+ 'PO': True,
743
+ 'GTD': False,
744
+ },
745
+ 'hedged': False,
746
+ 'trailing': False,
747
+ 'iceberg': True, # todo implement
748
+ 'selfTradePrevention': True, # todo implement
749
+ 'leverage': False,
750
+ 'marketBuyByCost': True,
751
+ 'marketBuyRequiresPrice': True,
752
+ },
753
+ 'createOrders': {
754
+ 'max': 40, # NOTE! max 10 per symbol
755
+ },
756
+ 'fetchMyTrades': {
757
+ 'marginMode': True,
758
+ 'limit': 1000,
759
+ 'daysBack': None,
760
+ 'untilDays': 30,
761
+ },
762
+ 'fetchOrder': {
763
+ 'marginMode': False,
764
+ 'trigger': True,
765
+ 'trailing': False,
766
+ },
767
+ 'fetchOpenOrders': {
768
+ 'marginMode': True,
769
+ 'trigger': True,
770
+ 'trailing': False,
771
+ 'limit': 100,
772
+ },
773
+ 'fetchOrders': None,
774
+ 'fetchClosedOrders': {
775
+ 'marginMode': True,
776
+ 'trigger': True,
777
+ 'trailing': False,
778
+ 'limit': 100,
779
+ 'untilDays': 30,
780
+ 'daysBack': None,
781
+ 'daysBackCanceled': None,
782
+ },
783
+ 'fetchOHLCV': {
784
+ 'limit': 1000,
785
+ },
786
+ },
787
+ 'spot': {
788
+ 'extends': 'default',
789
+ },
790
+ 'forDerivatives': {
791
+ 'extends': 'spot',
792
+ 'createOrder': {
793
+ 'marginMode': False,
794
+ 'triggerPriceType': {
795
+ 'last': True,
796
+ 'mark': True,
797
+ 'index': True,
798
+ },
799
+ },
800
+ 'createOrders': {
801
+ 'max': 10,
802
+ },
803
+ 'fetchMyTrades': {
804
+ 'marginMode': False,
805
+ 'untilDays': None,
806
+ },
807
+ 'fetchOpenOrders': {
808
+ 'marginMode': False,
809
+ },
810
+ 'fetchClosedOrders': {
811
+ 'marginMode': False,
812
+ 'untilDays': None,
813
+ 'limit': 1000,
814
+ },
815
+ 'fetchOHLCV': {
816
+ 'limit': 1999,
817
+ },
818
+ },
819
+ 'swap': {
820
+ 'linear': {
821
+ 'extends': 'forDerivatives',
822
+ },
823
+ 'inverse': {
824
+ 'extends': 'forDerivatives',
825
+ },
826
+ },
827
+ 'future': {
828
+ 'linear': {
829
+ 'extends': 'forDerivatives',
830
+ },
831
+ 'inverse': {
832
+ 'extends': 'forDerivatives',
833
+ },
834
+ },
835
+ },
683
836
  'precisionMode': TICK_SIZE,
684
837
  'fees': {
685
838
  'trading': {
@@ -791,6 +944,7 @@ class gate(Exchange, ImplicitAPI):
791
944
  'NOT_ACCEPTABLE': BadRequest,
792
945
  'METHOD_NOT_ALLOWED': BadRequest,
793
946
  'NOT_FOUND': ExchangeError,
947
+ 'AUTHENTICATION_FAILED': AuthenticationError,
794
948
  'INVALID_CREDENTIALS': AuthenticationError,
795
949
  'INVALID_KEY': AuthenticationError,
796
950
  'IP_FORBIDDEN': AuthenticationError,
@@ -885,13 +1039,58 @@ class gate(Exchange, ImplicitAPI):
885
1039
  super(gate, self).set_sandbox_mode(enable)
886
1040
  self.options['sandboxMode'] = enable
887
1041
 
888
- def convert_expire_date(self, date):
889
- # parse YYMMDD to timestamp
890
- year = date[0:2]
891
- month = date[2:4]
892
- day = date[4:6]
893
- reconstructedDate = '20' + year + '-' + month + '-' + day + 'T00:00:00Z'
894
- return reconstructedDate
1042
+ async def load_unified_status(self, params={}):
1043
+ """
1044
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1045
+ returns unifiedAccount so the user can check if the unified account is enabled
1046
+
1047
+ https://www.gate.io/docs/developers/apiv4/#get-account-detail
1048
+
1049
+ :returns boolean: True or False if the enabled unified account is enabled or not and sets the unifiedAccount option if it is None
1050
+ """
1051
+ unifiedAccount = self.safe_bool(self.options, 'unifiedAccount')
1052
+ if unifiedAccount is None:
1053
+ try:
1054
+ #
1055
+ # {
1056
+ # "user_id": 10406147,
1057
+ # "ip_whitelist": [],
1058
+ # "currency_pairs": [],
1059
+ # "key": {
1060
+ # "mode": 1
1061
+ # },
1062
+ # "tier": 0,
1063
+ # "tier_expire_time": "0001-01-01T00:00:00Z",
1064
+ # "copy_trading_role": 0
1065
+ # }
1066
+ #
1067
+ response = await self.privateAccountGetDetail(params)
1068
+ result = self.safe_dict(response, 'key', {})
1069
+ self.options['unifiedAccount'] = self.safe_integer(result, 'mode') == 2
1070
+ except Exception as e:
1071
+ # if the request fails, the unifiedAccount is disabled
1072
+ self.options['unifiedAccount'] = False
1073
+ return self.options['unifiedAccount']
1074
+
1075
+ async def upgrade_unified_trade_account(self, params={}):
1076
+ return await self.privateUnifiedPutUnifiedMode(params)
1077
+
1078
+ async def fetch_time(self, params={}):
1079
+ """
1080
+ fetches the current integer timestamp in milliseconds from the exchange server
1081
+
1082
+ https://www.gate.io/docs/developers/apiv4/en/#get-server-current-time
1083
+
1084
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1085
+ :returns int: the current integer timestamp in milliseconds from the exchange server
1086
+ """
1087
+ response = await self.publicSpotGetTime(params)
1088
+ #
1089
+ # {
1090
+ # "server_time": 1731447921098
1091
+ # }
1092
+ #
1093
+ return self.safe_integer(response, 'server_time')
895
1094
 
896
1095
  def create_expired_option_market(self, symbol: str):
897
1096
  # support expired option contracts
@@ -956,24 +1155,28 @@ class gate(Exchange, ImplicitAPI):
956
1155
  'info': None,
957
1156
  }
958
1157
 
959
- def safe_market(self, marketId=None, market=None, delimiter=None, marketType=None):
1158
+ def safe_market(self, marketId: Str = None, market: Market = None, delimiter: Str = None, marketType: Str = None) -> MarketInterface:
960
1159
  isOption = (marketId is not None) and ((marketId.find('-C') > -1) or (marketId.find('-P') > -1))
961
1160
  if isOption and not (marketId in self.markets_by_id):
962
1161
  # handle expired option contracts
963
1162
  return self.create_expired_option_market(marketId)
964
1163
  return super(gate, self).safe_market(marketId, market, delimiter, marketType)
965
1164
 
966
- async def fetch_markets(self, params={}):
1165
+ async def fetch_markets(self, params={}) -> List[Market]:
967
1166
  """
968
1167
  retrieves data on all markets for gate
969
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-currency-pairs-supported # spot
970
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-supported-currency-pairs-supported-in-margin-trading # margin
971
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts # swap
972
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts-2 # future
973
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-the-contracts-with-specified-underlying-and-expiration-time # option
1168
+
1169
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-currency-pairs-supported # spot
1170
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-supported-currency-pairs-supported-in-margin-trading # margin
1171
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts # swap
1172
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts-2 # future
1173
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-the-contracts-with-specified-underlying-and-expiration-time # option
1174
+
974
1175
  :param dict [params]: extra parameters specific to the exchange API endpoint
975
1176
  :returns dict[]: an array of objects representing market data
976
1177
  """
1178
+ if self.options['adjustForTimeDifference']:
1179
+ await self.load_time_difference()
977
1180
  sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
978
1181
  rawPromises = [
979
1182
  self.fetch_contract_markets(params),
@@ -991,8 +1194,9 @@ class gate(Exchange, ImplicitAPI):
991
1194
  return self.array_concat(markets, optionMarkets)
992
1195
 
993
1196
  async def fetch_spot_markets(self, params={}):
994
- marginResponse = await self.publicMarginGetCurrencyPairs(params)
995
- spotMarketsResponse = await self.publicSpotGetCurrencyPairs(params)
1197
+ marginPromise = self.publicMarginGetCurrencyPairs(params)
1198
+ spotMarketsPromise = self.publicSpotGetCurrencyPairs(params)
1199
+ marginResponse, spotMarketsResponse = await asyncio.gather(*[marginPromise, spotMarketsPromise])
996
1200
  marginMarkets = self.index_by(marginResponse, 'id')
997
1201
  #
998
1202
  # Spot
@@ -1102,7 +1306,7 @@ class gate(Exchange, ImplicitAPI):
1102
1306
  futureSettlementCurrencies = self.get_settlement_currencies('future', 'fetchMarkets')
1103
1307
  for c in range(0, len(swapSettlementCurrencies)):
1104
1308
  settleId = swapSettlementCurrencies[c]
1105
- request = {
1309
+ request: dict = {
1106
1310
  'settle': settleId,
1107
1311
  }
1108
1312
  response = await self.publicFuturesGetSettleContracts(self.extend(request, params))
@@ -1111,7 +1315,7 @@ class gate(Exchange, ImplicitAPI):
1111
1315
  result.append(parsedMarket)
1112
1316
  for c in range(0, len(futureSettlementCurrencies)):
1113
1317
  settleId = futureSettlementCurrencies[c]
1114
- request = {
1318
+ request: dict = {
1115
1319
  'settle': settleId,
1116
1320
  }
1117
1321
  response = await self.publicDeliveryGetSettleContracts(self.extend(request, params))
@@ -1429,7 +1633,7 @@ class gate(Exchange, ImplicitAPI):
1429
1633
 
1430
1634
  def prepare_request(self, market=None, type=None, params={}):
1431
1635
  """
1432
- * @ignore
1636
+ @ignore
1433
1637
  Fills request params contract, settle, currency_pair, market and account where applicable
1434
1638
  :param dict market: CCXT market, required when type is None
1435
1639
  :param str type: 'spot', 'swap', or 'future', required when market is None
@@ -1437,7 +1641,7 @@ class gate(Exchange, ImplicitAPI):
1437
1641
  :returns: the api request object, and the new params object with non-needed parameters removed
1438
1642
  """
1439
1643
  # * Do not call for multi spot order methods like cancelAllOrders and fetchOpenOrders. Use multiOrderSpotPrepareRequest instead
1440
- request = {}
1644
+ request: dict = {}
1441
1645
  if market is not None:
1442
1646
  if market['contract']:
1443
1647
  request['contract'] = market['id']
@@ -1455,50 +1659,50 @@ class gate(Exchange, ImplicitAPI):
1455
1659
  request['settle'] = settle
1456
1660
  return [request, params]
1457
1661
 
1458
- def spot_order_prepare_request(self, market=None, stop=False, params={}):
1662
+ def spot_order_prepare_request(self, market=None, trigger=False, params={}):
1459
1663
  """
1460
- * @ignore
1664
+ @ignore
1461
1665
  Fills request params currency_pair, market and account where applicable for spot order methods like fetchOpenOrders, cancelAllOrders
1462
1666
  :param dict market: CCXT market
1463
- :param bool stop: True if for a stop order
1667
+ :param bool trigger: True if for a trigger order
1464
1668
  :param dict [params]: request parameters
1465
1669
  :returns: the api request object, and the new params object with non-needed parameters removed
1466
1670
  """
1467
- marginMode, query = self.get_margin_mode(stop, params)
1468
- request = {}
1469
- if not stop:
1671
+ marginMode, query = self.get_margin_mode(trigger, params)
1672
+ request: dict = {}
1673
+ if not trigger:
1470
1674
  if market is None:
1471
- raise ArgumentsRequired(self.id + ' spotOrderPrepareRequest() requires a market argument for non-stop orders')
1675
+ raise ArgumentsRequired(self.id + ' spotOrderPrepareRequest() requires a market argument for non-trigger orders')
1472
1676
  request['account'] = marginMode
1473
- request['currency_pair'] = market['id'] # Should always be set for non-stop
1677
+ request['currency_pair'] = market['id'] # Should always be set for non-trigger
1474
1678
  return [request, query]
1475
1679
 
1476
- def multi_order_spot_prepare_request(self, market=None, stop=False, params={}):
1680
+ def multi_order_spot_prepare_request(self, market=None, trigger=False, params={}):
1477
1681
  """
1478
- * @ignore
1682
+ @ignore
1479
1683
  Fills request params currency_pair, market and account where applicable for spot order methods like fetchOpenOrders, cancelAllOrders
1480
1684
  :param dict market: CCXT market
1481
- :param bool stop: True if for a stop order
1685
+ :param bool trigger: True if for a trigger order
1482
1686
  :param dict [params]: request parameters
1483
1687
  :returns: the api request object, and the new params object with non-needed parameters removed
1484
1688
  """
1485
- marginMode, query = self.get_margin_mode(stop, params)
1486
- request = {
1689
+ marginMode, query = self.get_margin_mode(trigger, params)
1690
+ request: dict = {
1487
1691
  'account': marginMode,
1488
1692
  }
1489
1693
  if market is not None:
1490
- if stop:
1491
- # gate spot and margin stop orders use the term market instead of currency_pair, and normal instead of spot. Neither parameter is used when fetching/cancelling a single order. They are used for creating a single stop order, but createOrder does not call self method
1694
+ if trigger:
1695
+ # gate spot and margin trigger orders use the term market instead of currency_pair, and normal instead of spot. Neither parameter is used when fetching/cancelling a single order. They are used for creating a single trigger order, but createOrder does not call self method
1492
1696
  request['market'] = market['id']
1493
1697
  else:
1494
1698
  request['currency_pair'] = market['id']
1495
1699
  return [request, query]
1496
1700
 
1497
- def get_margin_mode(self, stop, params):
1701
+ def get_margin_mode(self, trigger, params):
1498
1702
  """
1499
- * @ignore
1703
+ @ignore
1500
1704
  Gets the margin type for self api call
1501
- :param bool stop: True if for a stop order
1705
+ :param bool trigger: True if for a trigger order
1502
1706
  :param dict [params]: Request params
1503
1707
  :returns: The marginMode and the updated request params with marginMode removed, marginMode value is the value that can be read by the "account" property specified in gates api docs
1504
1708
  """
@@ -1511,12 +1715,16 @@ class gate(Exchange, ImplicitAPI):
1511
1715
  marginMode = 'margin'
1512
1716
  elif marginMode == '':
1513
1717
  marginMode = 'spot'
1514
- if stop:
1718
+ if trigger:
1515
1719
  if marginMode == 'spot':
1516
- # gate spot stop orders use the term normal instead of spot
1720
+ # gate spot trigger orders use the term normal instead of spot
1517
1721
  marginMode = 'normal'
1518
1722
  if marginMode == 'cross_margin':
1519
- raise BadRequest(self.id + ' getMarginMode() does not support stop orders for cross margin')
1723
+ raise BadRequest(self.id + ' getMarginMode() does not support trigger orders for cross margin')
1724
+ isUnifiedAccount = False
1725
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'getMarginMode', 'unifiedAccount')
1726
+ if isUnifiedAccount:
1727
+ marginMode = 'unified'
1520
1728
  return [marginMode, params]
1521
1729
 
1522
1730
  def get_settlement_currencies(self, type, method):
@@ -1525,10 +1733,12 @@ class gate(Exchange, ImplicitAPI):
1525
1733
  defaultSettle = ['usdt'] if (type == 'swap') else ['btc']
1526
1734
  return self.safe_value(fetchMarketsContractOptions, 'settlementCurrencies', defaultSettle)
1527
1735
 
1528
- async def fetch_currencies(self, params={}):
1736
+ async def fetch_currencies(self, params={}) -> Currencies:
1529
1737
  """
1530
1738
  fetches all available currencies on an exchange
1531
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-currencies-details
1739
+
1740
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-currencies-details
1741
+
1532
1742
  :param dict [params]: extra parameters specific to the exchange API endpoint
1533
1743
  :returns dict: an associative dictionary of currencies
1534
1744
  """
@@ -1536,6 +1746,8 @@ class gate(Exchange, ImplicitAPI):
1536
1746
  apiBackup = self.safe_value(self.urls, 'apiBackup')
1537
1747
  if apiBackup is not None:
1538
1748
  return None
1749
+ if self.check_required_credentials(False):
1750
+ await self.load_unified_status()
1539
1751
  response = await self.publicSpotGetCurrencies(params)
1540
1752
  #
1541
1753
  # {
@@ -1557,7 +1769,7 @@ class gate(Exchange, ImplicitAPI):
1557
1769
  # "chain":"ETH"
1558
1770
  # }
1559
1771
  #
1560
- result = {}
1772
+ result: dict = {}
1561
1773
  for i in range(0, len(response)):
1562
1774
  entry = response[i]
1563
1775
  currencyId = self.safe_string(entry, 'currency')
@@ -1634,10 +1846,12 @@ class gate(Exchange, ImplicitAPI):
1634
1846
  result[code]['withdraw'] = withdrawAvailable
1635
1847
  return result
1636
1848
 
1637
- async def fetch_funding_rate(self, symbol: str, params={}):
1849
+ async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
1638
1850
  """
1639
1851
  fetch the current funding rate
1640
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-a-single-contract
1852
+
1853
+ https://www.gate.io/docs/developers/apiv4/en/#get-a-single-contract
1854
+
1641
1855
  :param str symbol: unified market symbol
1642
1856
  :param dict [params]: extra parameters specific to the exchange API endpoint
1643
1857
  :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
@@ -1694,13 +1908,15 @@ class gate(Exchange, ImplicitAPI):
1694
1908
  #
1695
1909
  return self.parse_funding_rate(response)
1696
1910
 
1697
- async def fetch_funding_rates(self, symbols: Strings = None, params={}):
1911
+ async def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
1698
1912
  """
1699
1913
  fetch the funding rate for multiple markets
1700
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts
1914
+
1915
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts
1916
+
1701
1917
  :param str[]|None symbols: list of unified market symbols
1702
1918
  :param dict [params]: extra parameters specific to the exchange API endpoint
1703
- :returns dict: a dictionary of `funding rates structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexe by market symbols
1919
+ :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexed by market symbols
1704
1920
  """
1705
1921
  await self.load_markets()
1706
1922
  symbols = self.market_symbols(symbols)
@@ -1750,10 +1966,9 @@ class gate(Exchange, ImplicitAPI):
1750
1966
  # }
1751
1967
  # ]
1752
1968
  #
1753
- result = self.parse_funding_rates(response)
1754
- return self.filter_by_array(result, 'symbol', symbols)
1969
+ return self.parse_funding_rates(response, symbols)
1755
1970
 
1756
- def parse_funding_rate(self, contract, market: Market = None):
1971
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
1757
1972
  #
1758
1973
  # {
1759
1974
  # "name": "BTC_USDT",
@@ -1804,6 +2019,7 @@ class gate(Exchange, ImplicitAPI):
1804
2019
  fundingRate = self.safe_number(contract, 'funding_rate')
1805
2020
  fundingTime = self.safe_timestamp(contract, 'funding_next_apply')
1806
2021
  fundingRateIndicative = self.safe_number(contract, 'funding_rate_indicative')
2022
+ fundingInterval = Precise.string_mul('1000', self.safe_string(contract, 'funding_interval'))
1807
2023
  return {
1808
2024
  'info': contract,
1809
2025
  'symbol': symbol,
@@ -1822,19 +2038,30 @@ class gate(Exchange, ImplicitAPI):
1822
2038
  'previousFundingRate': None,
1823
2039
  'previousFundingTimestamp': None,
1824
2040
  'previousFundingDatetime': None,
2041
+ 'interval': self.parse_funding_interval(fundingInterval),
2042
+ }
2043
+
2044
+ def parse_funding_interval(self, interval):
2045
+ intervals: dict = {
2046
+ '3600000': '1h',
2047
+ '14400000': '4h',
2048
+ '28800000': '8h',
2049
+ '57600000': '16h',
2050
+ '86400000': '24h',
1825
2051
  }
2052
+ return self.safe_string(intervals, interval, interval)
1826
2053
 
1827
2054
  async def fetch_network_deposit_address(self, code: str, params={}):
1828
2055
  await self.load_markets()
1829
2056
  currency = self.currency(code)
1830
- request = {
1831
- 'currency': currency['id'],
2057
+ request: dict = {
2058
+ 'currency': currency['id'], # todo: currencies have network-junctions
1832
2059
  }
1833
2060
  response = await self.privateWalletGetDepositAddress(self.extend(request, params))
1834
2061
  addresses = self.safe_value(response, 'multichain_addresses')
1835
2062
  currencyId = self.safe_string(response, 'currency')
1836
2063
  code = self.safe_currency_code(currencyId)
1837
- result = {}
2064
+ result: dict = {}
1838
2065
  for i in range(0, len(addresses)):
1839
2066
  entry = addresses[i]
1840
2067
  #
@@ -1861,10 +2088,12 @@ class gate(Exchange, ImplicitAPI):
1861
2088
  }
1862
2089
  return result
1863
2090
 
1864
- async def fetch_deposit_address(self, code: str, params={}):
2091
+ async def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
1865
2092
  """
1866
2093
  fetch the deposit address for a currency associated with self account
1867
- :see: https://www.gate.io/docs/developers/apiv4/en/#generate-currency-deposit-address
2094
+
2095
+ https://www.gate.io/docs/developers/apiv4/en/#generate-currency-deposit-address
2096
+
1868
2097
  :param str code: unified currency code
1869
2098
  :param dict [params]: extra parameters specific to the exchange API endpoint
1870
2099
  :param str [params.network]: unified network code(not used directly by gate.io but used by ccxt to filter the response)
@@ -1874,8 +2103,8 @@ class gate(Exchange, ImplicitAPI):
1874
2103
  currency = self.currency(code)
1875
2104
  rawNetwork = self.safe_string_upper(params, 'network')
1876
2105
  params = self.omit(params, 'network')
1877
- request = {
1878
- 'currency': currency['id'],
2106
+ request: dict = {
2107
+ 'currency': currency['id'], # todo: currencies have network-junctions
1879
2108
  }
1880
2109
  response = await self.privateWalletGetDepositAddress(self.extend(request, params))
1881
2110
  #
@@ -1926,24 +2155,25 @@ class gate(Exchange, ImplicitAPI):
1926
2155
  self.check_address(address)
1927
2156
  return {
1928
2157
  'info': response,
1929
- 'code': code, # kept here for backward-compatibility, but will be removed soon
1930
2158
  'currency': code,
2159
+ 'network': network,
1931
2160
  'address': address,
1932
2161
  'tag': tag,
1933
- 'network': network,
1934
2162
  }
1935
2163
 
1936
- async def fetch_trading_fee(self, symbol: str, params={}):
2164
+ async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
1937
2165
  """
1938
2166
  fetch the trading fees for a market
1939
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-personal-trading-fee
2167
+
2168
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-personal-trading-fee
2169
+
1940
2170
  :param str symbol: unified market symbol
1941
2171
  :param dict [params]: extra parameters specific to the exchange API endpoint
1942
2172
  :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
1943
2173
  """
1944
2174
  await self.load_markets()
1945
2175
  market = self.market(symbol)
1946
- request = {
2176
+ request: dict = {
1947
2177
  'currency_pair': market['id'],
1948
2178
  }
1949
2179
  response = await self.privateWalletGetFee(self.extend(request, params))
@@ -1963,10 +2193,12 @@ class gate(Exchange, ImplicitAPI):
1963
2193
  #
1964
2194
  return self.parse_trading_fee(response, market)
1965
2195
 
1966
- async def fetch_trading_fees(self, params={}):
2196
+ async def fetch_trading_fees(self, params={}) -> TradingFees:
1967
2197
  """
1968
2198
  fetch the trading fees for multiple markets
1969
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-personal-trading-fee
2199
+
2200
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-personal-trading-fee
2201
+
1970
2202
  :param dict [params]: extra parameters specific to the exchange API endpoint
1971
2203
  :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
1972
2204
  """
@@ -1989,7 +2221,7 @@ class gate(Exchange, ImplicitAPI):
1989
2221
  return self.parse_trading_fees(response)
1990
2222
 
1991
2223
  def parse_trading_fees(self, response):
1992
- result = {}
2224
+ result: dict = {}
1993
2225
  for i in range(0, len(self.symbols)):
1994
2226
  symbol = self.symbols[i]
1995
2227
  market = self.market(symbol)
@@ -2022,13 +2254,17 @@ class gate(Exchange, ImplicitAPI):
2022
2254
  'symbol': self.safe_string(market, 'symbol'),
2023
2255
  'maker': self.safe_number(info, makerKey),
2024
2256
  'taker': self.safe_number(info, takerKey),
2257
+ 'percentage': None,
2258
+ 'tierBased': None,
2025
2259
  }
2026
2260
 
2027
- async def fetch_transaction_fees(self, codes: List[str] = None, params={}):
2261
+ async def fetch_transaction_fees(self, codes: Strings = None, params={}):
2028
2262
  """
2029
- * @deprecated
2263
+ @deprecated
2030
2264
  please use fetchDepositWithdrawFees instead
2031
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-withdrawal-status
2265
+
2266
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-withdrawal-status
2267
+
2032
2268
  :param str[]|None codes: list of unified currency codes
2033
2269
  :param dict [params]: extra parameters specific to the exchange API endpoint
2034
2270
  :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -2052,7 +2288,7 @@ class gate(Exchange, ImplicitAPI):
2052
2288
  # }
2053
2289
  # }
2054
2290
  #
2055
- result = {}
2291
+ result: dict = {}
2056
2292
  withdrawFees = {}
2057
2293
  for i in range(0, len(response)):
2058
2294
  withdrawFees = {}
@@ -2079,7 +2315,9 @@ class gate(Exchange, ImplicitAPI):
2079
2315
  async def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
2080
2316
  """
2081
2317
  fetch deposit and withdraw fees
2082
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-withdrawal-status
2318
+
2319
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-withdrawal-status
2320
+
2083
2321
  :param str[]|None codes: list of unified currency codes
2084
2322
  :param dict [params]: extra parameters specific to the exchange API endpoint
2085
2323
  :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -2126,7 +2364,7 @@ class gate(Exchange, ImplicitAPI):
2126
2364
  # }
2127
2365
  #
2128
2366
  withdrawFixOnChains = self.safe_value(fee, 'withdraw_fix_on_chains')
2129
- result = {
2367
+ result: dict = {
2130
2368
  'info': fee,
2131
2369
  'withdraw': {
2132
2370
  'fee': self.safe_number(fee, 'withdraw_fix'),
@@ -2142,7 +2380,8 @@ class gate(Exchange, ImplicitAPI):
2142
2380
  chainKeys = list(withdrawFixOnChains.keys())
2143
2381
  for i in range(0, len(chainKeys)):
2144
2382
  chainKey = chainKeys[i]
2145
- result['networks'][chainKey] = {
2383
+ networkCode = self.network_id_to_code(chainKey, self.safe_string(fee, 'currency'))
2384
+ result['networks'][networkCode] = {
2146
2385
  'withdraw': {
2147
2386
  'fee': self.parse_number(withdrawFixOnChains[chainKey]),
2148
2387
  'percentage': False,
@@ -2157,8 +2396,10 @@ class gate(Exchange, ImplicitAPI):
2157
2396
  async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2158
2397
  """
2159
2398
  fetch the history of funding payments paid and received on self account
2160
- :see: https://www.gate.io/docs/developers/apiv4/en/#query-account-book-2
2161
- :see: https://www.gate.io/docs/developers/apiv4/en/#query-account-book-3
2399
+
2400
+ https://www.gate.io/docs/developers/apiv4/en/#query-account-book-2
2401
+ https://www.gate.io/docs/developers/apiv4/en/#query-account-book-3
2402
+
2162
2403
  :param str symbol: unified market symbol
2163
2404
  :param int [since]: the earliest time in ms to fetch funding history for
2164
2405
  :param int [limit]: the maximum number of funding history structures to retrieve
@@ -2235,10 +2476,12 @@ class gate(Exchange, ImplicitAPI):
2235
2476
  async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
2236
2477
  """
2237
2478
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
2238
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-order-book
2239
- :see: https://www.gate.io/docs/developers/apiv4/en/#futures-order-book
2240
- :see: https://www.gate.io/docs/developers/apiv4/en/#futures-order-book-2
2241
- :see: https://www.gate.io/docs/developers/apiv4/en/#options-order-book
2479
+
2480
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-order-book
2481
+ https://www.gate.io/docs/developers/apiv4/en/#futures-order-book
2482
+ https://www.gate.io/docs/developers/apiv4/en/#futures-order-book-2
2483
+ https://www.gate.io/docs/developers/apiv4/en/#options-order-book
2484
+
2242
2485
  :param str symbol: unified symbol of the market to fetch the order book for
2243
2486
  :param int [limit]: the maximum amount of order book entries to return
2244
2487
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2247,7 +2490,7 @@ class gate(Exchange, ImplicitAPI):
2247
2490
  await self.load_markets()
2248
2491
  market = self.market(symbol)
2249
2492
  #
2250
- # request = {
2493
+ # request: Dict = {
2251
2494
  # 'currency_pair': market['id'],
2252
2495
  # 'interval': '0', # depth, 0 means no aggregation is applied, default to 0
2253
2496
  # 'limit': limit, # maximum number of order depth data in asks or bids
@@ -2346,10 +2589,12 @@ class gate(Exchange, ImplicitAPI):
2346
2589
  async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
2347
2590
  """
2348
2591
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
2349
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-details-of-a-specifc-order
2350
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-futures-tickers
2351
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-futures-tickers-2
2352
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-tickers-of-options-contracts
2592
+
2593
+ https://www.gate.io/docs/developers/apiv4/en/#get-details-of-a-specifc-order
2594
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-tickers
2595
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-tickers-2
2596
+ https://www.gate.io/docs/developers/apiv4/en/#list-tickers-of-options-contracts
2597
+
2353
2598
  :param str symbol: unified symbol of the market to fetch the ticker for
2354
2599
  :param dict [params]: extra parameters specific to the exchange API endpoint
2355
2600
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -2382,7 +2627,7 @@ class gate(Exchange, ImplicitAPI):
2382
2627
  ticker = self.safe_value(response, 0)
2383
2628
  return self.parse_ticker(ticker, market)
2384
2629
 
2385
- def parse_ticker(self, ticker, market: Market = None) -> Ticker:
2630
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
2386
2631
  #
2387
2632
  # SPOT
2388
2633
  #
@@ -2489,16 +2734,20 @@ class gate(Exchange, ImplicitAPI):
2489
2734
  'average': None,
2490
2735
  'baseVolume': baseVolume,
2491
2736
  'quoteVolume': quoteVolume,
2737
+ 'markPrice': self.safe_string(ticker, 'mark_price'),
2738
+ 'indexPrice': self.safe_string(ticker, 'index_price'),
2492
2739
  'info': ticker,
2493
2740
  }, market)
2494
2741
 
2495
2742
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
2496
2743
  """
2497
2744
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
2498
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-details-of-a-specifc-order
2499
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-futures-tickers
2500
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-futures-tickers-2
2501
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-tickers-of-options-contracts
2745
+
2746
+ https://www.gate.io/docs/developers/apiv4/en/#get-details-of-a-specifc-order
2747
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-tickers
2748
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-tickers-2
2749
+ https://www.gate.io/docs/developers/apiv4/en/#list-tickers-of-options-contracts
2750
+
2502
2751
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
2503
2752
  :param dict [params]: extra parameters specific to the exchange API endpoint
2504
2753
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -2545,10 +2794,15 @@ class gate(Exchange, ImplicitAPI):
2545
2794
  :param str [params.settle]: 'btc' or 'usdt' - settle currency for perpetual swap and future - default="usdt" for swap and "btc" for future
2546
2795
  :param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
2547
2796
  :param str [params.symbol]: margin only - unified ccxt symbol
2797
+ :param boolean [params.unifiedAccount]: default False, set to True for fetching the unified account balance
2798
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
2548
2799
  """
2549
2800
  await self.load_markets()
2801
+ await self.load_unified_status()
2550
2802
  symbol = self.safe_string(params, 'symbol')
2551
2803
  params = self.omit(params, 'symbol')
2804
+ isUnifiedAccount = False
2805
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'fetchBalance', 'unifiedAccount')
2552
2806
  type, query = self.handle_market_type_and_params('fetchBalance', None, params)
2553
2807
  request, requestParams = self.prepare_request(None, type, query)
2554
2808
  marginMode, requestQuery = self.get_margin_mode(False, requestParams)
@@ -2556,7 +2810,9 @@ class gate(Exchange, ImplicitAPI):
2556
2810
  market = self.market(symbol)
2557
2811
  request['currency_pair'] = market['id']
2558
2812
  response = None
2559
- if type == 'spot':
2813
+ if isUnifiedAccount:
2814
+ response = await self.privateUnifiedGetAccounts(self.extend(request, params))
2815
+ elif type == 'spot':
2560
2816
  if marginMode == 'spot':
2561
2817
  response = await self.privateSpotGetAccounts(self.extend(request, requestQuery))
2562
2818
  elif marginMode == 'margin':
@@ -2719,12 +2975,63 @@ class gate(Exchange, ImplicitAPI):
2719
2975
  # "orders_limit": 10
2720
2976
  # }
2721
2977
  #
2722
- result = {
2978
+ # unified
2979
+ #
2980
+ # {
2981
+ # "user_id": 10001,
2982
+ # "locked": False,
2983
+ # "balances": {
2984
+ # "ETH": {
2985
+ # "available": "0",
2986
+ # "freeze": "0",
2987
+ # "borrowed": "0.075393666654",
2988
+ # "negative_liab": "0",
2989
+ # "futures_pos_liab": "0",
2990
+ # "equity": "1016.1",
2991
+ # "total_freeze": "0",
2992
+ # "total_liab": "0"
2993
+ # },
2994
+ # "POINT": {
2995
+ # "available": "9999999999.017023138734",
2996
+ # "freeze": "0",
2997
+ # "borrowed": "0",
2998
+ # "negative_liab": "0",
2999
+ # "futures_pos_liab": "0",
3000
+ # "equity": "12016.1",
3001
+ # "total_freeze": "0",
3002
+ # "total_liab": "0"
3003
+ # },
3004
+ # "USDT": {
3005
+ # "available": "0.00000062023",
3006
+ # "freeze": "0",
3007
+ # "borrowed": "0",
3008
+ # "negative_liab": "0",
3009
+ # "futures_pos_liab": "0",
3010
+ # "equity": "16.1",
3011
+ # "total_freeze": "0",
3012
+ # "total_liab": "0"
3013
+ # }
3014
+ # },
3015
+ # "total": "230.94621713",
3016
+ # "borrowed": "161.66395521",
3017
+ # "total_initial_margin": "1025.0524665088",
3018
+ # "total_margin_balance": "3382495.944473949183",
3019
+ # "total_maintenance_margin": "205.01049330176",
3020
+ # "total_initial_margin_rate": "3299.827135672679",
3021
+ # "total_maintenance_margin_rate": "16499.135678363399",
3022
+ # "total_available_margin": "3381470.892007440383",
3023
+ # "unified_account_total": "3381470.892007440383",
3024
+ # "unified_account_total_liab": "0",
3025
+ # "unified_account_total_equity": "100016.1",
3026
+ # "leverage": "2"
3027
+ # }
3028
+ #
3029
+ result: dict = {
2723
3030
  'info': response,
2724
3031
  }
2725
3032
  isolated = marginMode == 'margin'
2726
3033
  data = response
2727
- if 'balances' in data: # True for cross_margin
3034
+ if 'balances' in data: # True for cross_margin and unified
2728
3035
  flatBalances = []
2729
3036
  balances = self.safe_value(data, 'balances', [])
2730
3037
  # inject currency and create an artificial balance object
@@ -2745,7 +3052,7 @@ class gate(Exchange, ImplicitAPI):
2745
3052
  quote = self.safe_value(entry, 'quote', {})
2746
3053
  baseCode = self.safe_currency_code(self.safe_string(base, 'currency'))
2747
3054
  quoteCode = self.safe_currency_code(self.safe_string(quote, 'currency'))
2748
- subResult = {}
3055
+ subResult: dict = {}
2749
3056
  subResult[baseCode] = self.parse_balance_helper(base)
2750
3057
  subResult[quoteCode] = self.parse_balance_helper(quote)
2751
3058
  result[symbolInner] = self.safe_balance(subResult)
@@ -2758,10 +3065,12 @@ class gate(Exchange, ImplicitAPI):
2758
3065
  async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
2759
3066
  """
2760
3067
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
2761
- :see: https://www.gate.io/docs/developers/apiv4/en/#market-candlesticks # spot
2762
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-futures-candlesticks # swap
2763
- :see: https://www.gate.io/docs/developers/apiv4/en/#market-candlesticks # future
2764
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-options-candlesticks # option
3068
+
3069
+ https://www.gate.io/docs/developers/apiv4/en/#market-candlesticks # spot
3070
+ https://www.gate.io/docs/developers/apiv4/en/#get-futures-candlesticks # swap
3071
+ https://www.gate.io/docs/developers/apiv4/en/#market-candlesticks # future
3072
+ https://www.gate.io/docs/developers/apiv4/en/#get-options-candlesticks # option
3073
+
2765
3074
  :param str symbol: unified symbol of the market to fetch OHLCV data for
2766
3075
  :param str timeframe: the length of time each candle represents
2767
3076
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -2781,7 +3090,7 @@ class gate(Exchange, ImplicitAPI):
2781
3090
  if market['option']:
2782
3091
  return await self.fetch_option_ohlcv(symbol, timeframe, since, limit, params)
2783
3092
  price = self.safe_string(params, 'price')
2784
- request = {}
3093
+ request: dict = {}
2785
3094
  request, params = self.prepare_request(market, None, params)
2786
3095
  request['interval'] = self.safe_string(self.timeframes, timeframe, timeframe)
2787
3096
  maxLimit = 1999 if market['contract'] else 1000
@@ -2807,7 +3116,6 @@ class gate(Exchange, ImplicitAPI):
2807
3116
  request['limit'] = limit
2808
3117
  response = None
2809
3118
  if market['contract']:
2810
- maxLimit = 1999
2811
3119
  isMark = (price == 'mark')
2812
3120
  isIndex = (price == 'index')
2813
3121
  if isMark or isIndex:
@@ -2825,7 +3133,7 @@ class gate(Exchange, ImplicitAPI):
2825
3133
  # separated option logic because the from, to and limit parameters weren't functioning
2826
3134
  await self.load_markets()
2827
3135
  market = self.market(symbol)
2828
- request = {}
3136
+ request: dict = {}
2829
3137
  request, params = self.prepare_request(market, None, params)
2830
3138
  request['interval'] = self.safe_string(self.timeframes, timeframe, timeframe)
2831
3139
  response = await self.publicOptionsGetCandlesticks(self.extend(request, params))
@@ -2834,23 +3142,38 @@ class gate(Exchange, ImplicitAPI):
2834
3142
  async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2835
3143
  """
2836
3144
  fetches historical funding rate prices
2837
- :see: https://www.gate.io/docs/developers/apiv4/en/#funding-rate-history
3145
+
3146
+ https://www.gate.io/docs/developers/apiv4/en/#funding-rate-history
3147
+
2838
3148
  :param str symbol: unified symbol of the market to fetch the funding rate history for
2839
3149
  :param int [since]: timestamp in ms of the earliest funding rate to fetch
2840
3150
  :param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
2841
3151
  :param dict [params]: extra parameters specific to the exchange API endpoint
3152
+ :param int [params.until]: timestamp in ms of the latest funding rate to fetch
3153
+ :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)
2842
3154
  :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>`
2843
3155
  """
2844
3156
  if symbol is None:
2845
3157
  raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
2846
3158
  await self.load_markets()
3159
+ paginate = False
3160
+ paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
3161
+ if paginate:
3162
+ return await self.fetch_paginated_call_deterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params)
2847
3163
  market = self.market(symbol)
2848
3164
  if not market['swap']:
2849
3165
  raise BadSymbol(self.id + ' fetchFundingRateHistory() supports swap contracts only')
2850
- request, query = self.prepare_request(market, None, params)
3166
+ request: dict = {}
3167
+ request, params = self.prepare_request(market, None, params)
2851
3168
  if limit is not None:
2852
3169
  request['limit'] = limit
2853
- response = await self.publicFuturesGetSettleFundingRate(self.extend(request, query))
3170
+ if since is not None:
3171
+ request['from'] = self.parse_to_int(since / 1000)
3172
+ until = self.safe_integer(params, 'until')
3173
+ if until is not None:
3174
+ params = self.omit(params, 'until')
3175
+ request['to'] = self.parse_to_int(until / 1000)
3176
+ response = await self.publicFuturesGetSettleFundingRate(self.extend(request, params))
2854
3177
  #
2855
3178
  # {
2856
3179
  # "r": "0.00063521",
@@ -2919,10 +3242,12 @@ class gate(Exchange, ImplicitAPI):
2919
3242
  async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
2920
3243
  """
2921
3244
  get the list of most recent trades for a particular symbol
2922
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-market-trades
2923
- :see: https://www.gate.io/docs/developers/apiv4/en/#futures-trading-history
2924
- :see: https://www.gate.io/docs/developers/apiv4/en/#futures-trading-history-2
2925
- :see: https://www.gate.io/docs/developers/apiv4/en/#options-trade-history
3245
+
3246
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-market-trades
3247
+ https://www.gate.io/docs/developers/apiv4/en/#futures-trading-history
3248
+ https://www.gate.io/docs/developers/apiv4/en/#futures-trading-history-2
3249
+ https://www.gate.io/docs/developers/apiv4/en/#options-trade-history
3250
+
2926
3251
  :param str symbol: unified symbol of the market to fetch trades for
2927
3252
  :param int [since]: timestamp in ms of the earliest trade to fetch
2928
3253
  :param int [limit]: the maximum amount of trades to fetch
@@ -2940,7 +3265,7 @@ class gate(Exchange, ImplicitAPI):
2940
3265
  #
2941
3266
  # spot
2942
3267
  #
2943
- # request = {
3268
+ # request: Dict = {
2944
3269
  # 'currency_pair': market['id'],
2945
3270
  # 'limit': limit, # maximum number of records to be returned in a single list
2946
3271
  # 'last_id': 'id', # specify list staring point using the id of last record in previous list-query results
@@ -2949,7 +3274,7 @@ class gate(Exchange, ImplicitAPI):
2949
3274
  #
2950
3275
  # swap, future
2951
3276
  #
2952
- # request = {
3277
+ # request: Dict = {
2953
3278
  # 'settle': market['settleId'],
2954
3279
  # 'contract': market['id'],
2955
3280
  # 'limit': limit, # maximum number of records to be returned in a single list
@@ -3023,10 +3348,12 @@ class gate(Exchange, ImplicitAPI):
3023
3348
  async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3024
3349
  """
3025
3350
  fetch all the trades made from a single order
3026
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history
3027
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-2
3028
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-3
3029
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-4
3351
+
3352
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history
3353
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-2
3354
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-3
3355
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-4
3356
+
3030
3357
  :param str id: order id
3031
3358
  :param str symbol: unified market symbol
3032
3359
  :param int [since]: the earliest time in ms to fetch trades for
@@ -3062,10 +3389,12 @@ class gate(Exchange, ImplicitAPI):
3062
3389
  async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3063
3390
  """
3064
3391
  Fetch personal trading history
3065
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history
3066
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-2
3067
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-3
3068
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-4
3392
+
3393
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history
3394
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-2
3395
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-3
3396
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-4
3397
+
3069
3398
  :param str symbol: unified market symbol
3070
3399
  :param int [since]: the earliest time in ms to fetch trades for
3071
3400
  :param int [limit]: the maximum number of trades structures to retrieve
@@ -3079,20 +3408,22 @@ class gate(Exchange, ImplicitAPI):
3079
3408
  :param int [params.offset]: *contract only* list offset, starting from 0
3080
3409
  :param str [params.last_id]: *contract only* specify list staring point using the id of last record in previous list-query results
3081
3410
  :param int [params.count_total]: *contract only* whether to return total number matched, default to 0(no return)
3082
- :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
3411
+ :param bool [params.unifiedAccount]: set to True for fetching trades in a unified account
3412
+ :param bool [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)
3083
3413
  :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
3084
3414
  """
3085
3415
  await self.load_markets()
3416
+ await self.load_unified_status()
3086
3417
  paginate = False
3087
3418
  paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
3088
3419
  if paginate:
3089
3420
  return await self.fetch_paginated_call_dynamic('fetchMyTrades', symbol, since, limit, params)
3090
3421
  type = None
3091
3422
  marginMode = None
3092
- request = {}
3423
+ request: dict = {}
3093
3424
  market = self.market(symbol) if (symbol is not None) else None
3094
- until = self.safe_integer_2(params, 'until', 'till')
3095
- params = self.omit(params, ['until', 'till'])
3425
+ until = self.safe_integer(params, 'until')
3426
+ params = self.omit(params, ['until'])
3096
3427
  type, params = self.handle_market_type_and_params('fetchMyTrades', market, params)
3097
3428
  contract = (type == 'swap') or (type == 'future') or (type == 'option')
3098
3429
  if contract:
@@ -3101,7 +3432,7 @@ class gate(Exchange, ImplicitAPI):
3101
3432
  params = self.omit(params, 'order_id')
3102
3433
  else:
3103
3434
  if market is not None:
3104
- request['currency_pair'] = market['id'] # Should always be set for non-stop
3435
+ request['currency_pair'] = market['id'] # Should always be set for non-trigger
3105
3436
  marginMode, params = self.get_margin_mode(False, params)
3106
3437
  request['account'] = marginMode
3107
3438
  if limit is not None:
@@ -3187,7 +3518,7 @@ class gate(Exchange, ImplicitAPI):
3187
3518
  #
3188
3519
  return self.parse_trades(response, market, since, limit)
3189
3520
 
3190
- def parse_trade(self, trade, market: Market = None) -> Trade:
3521
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
3191
3522
  #
3192
3523
  # public
3193
3524
  #
@@ -3289,8 +3620,8 @@ class gate(Exchange, ImplicitAPI):
3289
3620
  side = self.safe_string_2(trade, 'side', 'type', contractSide)
3290
3621
  orderId = self.safe_string(trade, 'order_id')
3291
3622
  feeAmount = self.safe_string(trade, 'fee')
3292
- gtFee = self.safe_string(trade, 'gt_fee')
3293
- pointFee = self.safe_string(trade, 'point_fee')
3623
+ gtFee = self.omit_zero(self.safe_string(trade, 'gt_fee'))
3624
+ pointFee = self.omit_zero(self.safe_string(trade, 'point_fee'))
3294
3625
  fees = []
3295
3626
  if feeAmount is not None:
3296
3627
  feeCurrencyId = self.safe_string(trade, 'fee_currency')
@@ -3332,12 +3663,14 @@ class gate(Exchange, ImplicitAPI):
3332
3663
  async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
3333
3664
  """
3334
3665
  fetch all deposits made to an account
3335
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-deposit-records
3666
+
3667
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-deposit-records
3668
+
3336
3669
  :param str code: unified currency code
3337
3670
  :param int [since]: the earliest time in ms to fetch deposits for
3338
3671
  :param int [limit]: the maximum number of deposits structures to retrieve
3339
- :param int [params.until]: end time in ms
3340
3672
  :param dict [params]: extra parameters specific to the exchange API endpoint
3673
+ :param int [params.until]: end time in ms
3341
3674
  :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
3342
3675
  :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
3343
3676
  """
@@ -3346,11 +3679,11 @@ class gate(Exchange, ImplicitAPI):
3346
3679
  paginate, params = self.handle_option_and_params(params, 'fetchDeposits', 'paginate')
3347
3680
  if paginate:
3348
3681
  return await self.fetch_paginated_call_dynamic('fetchDeposits', code, since, limit, params)
3349
- request = {}
3682
+ request: dict = {}
3350
3683
  currency = None
3351
3684
  if code is not None:
3352
3685
  currency = self.currency(code)
3353
- request['currency'] = currency['id']
3686
+ request['currency'] = currency['id'] # todo: currencies have network-junctions
3354
3687
  if limit is not None:
3355
3688
  request['limit'] = limit
3356
3689
  if since is not None:
@@ -3364,7 +3697,9 @@ class gate(Exchange, ImplicitAPI):
3364
3697
  async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
3365
3698
  """
3366
3699
  fetch all withdrawals made from an account
3367
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-withdrawal-records
3700
+
3701
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-withdrawal-records
3702
+
3368
3703
  :param str code: unified currency code
3369
3704
  :param int [since]: the earliest time in ms to fetch withdrawals for
3370
3705
  :param int [limit]: the maximum number of withdrawals structures to retrieve
@@ -3378,11 +3713,11 @@ class gate(Exchange, ImplicitAPI):
3378
3713
  paginate, params = self.handle_option_and_params(params, 'fetchWithdrawals', 'paginate')
3379
3714
  if paginate:
3380
3715
  return await self.fetch_paginated_call_dynamic('fetchWithdrawals', code, since, limit, params)
3381
- request = {}
3716
+ request: dict = {}
3382
3717
  currency = None
3383
3718
  if code is not None:
3384
3719
  currency = self.currency(code)
3385
- request['currency'] = currency['id']
3720
+ request['currency'] = currency['id'] # todo: currencies have network-junctions
3386
3721
  if limit is not None:
3387
3722
  request['limit'] = limit
3388
3723
  if since is not None:
@@ -3393,10 +3728,12 @@ class gate(Exchange, ImplicitAPI):
3393
3728
  response = await self.privateWalletGetWithdrawals(self.extend(request, params))
3394
3729
  return self.parse_transactions(response, currency)
3395
3730
 
3396
- async def withdraw(self, code: str, amount: float, address, tag=None, params={}):
3731
+ async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
3397
3732
  """
3398
3733
  make a withdrawal
3399
- :see: https://www.gate.io/docs/developers/apiv4/en/#withdraw
3734
+
3735
+ https://www.gate.io/docs/developers/apiv4/en/#withdraw
3736
+
3400
3737
  :param str code: unified currency code
3401
3738
  :param float amount: the amount to withdraw
3402
3739
  :param str address: the address to withdraw to
@@ -3408,8 +3745,8 @@ class gate(Exchange, ImplicitAPI):
3408
3745
  self.check_address(address)
3409
3746
  await self.load_markets()
3410
3747
  currency = self.currency(code)
3411
- request = {
3412
- 'currency': currency['id'],
3748
+ request: dict = {
3749
+ 'currency': currency['id'], # todo: currencies have network-junctions
3413
3750
  'address': address,
3414
3751
  'amount': self.currency_to_precision(code, amount),
3415
3752
  }
@@ -3422,7 +3759,7 @@ class gate(Exchange, ImplicitAPI):
3422
3759
  request['chain'] = network
3423
3760
  params = self.omit(params, 'network')
3424
3761
  else:
3425
- request['chain'] = currency['id']
3762
+ request['chain'] = currency['id'] # todo: currencies have network-junctions
3426
3763
  response = await self.privateWithdrawalsPostWithdrawals(self.extend(request, params))
3427
3764
  #
3428
3765
  # {
@@ -3435,8 +3772,8 @@ class gate(Exchange, ImplicitAPI):
3435
3772
  #
3436
3773
  return self.parse_transaction(response, currency)
3437
3774
 
3438
- def parse_transaction_status(self, status):
3439
- statuses = {
3775
+ def parse_transaction_status(self, status: Str):
3776
+ statuses: dict = {
3440
3777
  'PEND': 'pending',
3441
3778
  'REQUEST': 'pending',
3442
3779
  'DMOVE': 'pending',
@@ -3454,40 +3791,69 @@ class gate(Exchange, ImplicitAPI):
3454
3791
  return self.safe_string(statuses, status, status)
3455
3792
 
3456
3793
  def parse_transaction_type(self, type):
3457
- types = {
3794
+ types: dict = {
3458
3795
  'd': 'deposit',
3459
3796
  'w': 'withdrawal',
3460
3797
  }
3461
3798
  return self.safe_string(types, type, type)
3462
3799
 
3463
- def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
3800
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
3464
3801
  #
3465
- # deposits
3802
+ # fetchDeposits
3466
3803
  #
3467
- # {
3468
- # "id": "d33361395",
3469
- # "currency": "USDT_TRX",
3470
- # "address": "TErdnxenuLtXfnMafLbfappYdHtnXQ5U4z",
3471
- # "amount": "100",
3472
- # "txid": "ae9374de34e558562fe18cbb1bf9ab4d9eb8aa7669d65541c9fa2a532c1474a0",
3473
- # "timestamp": "1626345819",
3474
- # "status": "DONE",
3475
- # "memo": ""
3476
- # }
3804
+ # {
3805
+ # "id": "d33361395",
3806
+ # "currency": "USDT_TRX",
3807
+ # "address": "TErdnxenuLtXfnMafLbfappYdHtnXQ5U4z",
3808
+ # "amount": "100",
3809
+ # "txid": "ae9374de34e558562fe18cbb1bf9ab4d9eb8aa7669d65541c9fa2a532c1474a0",
3810
+ # "timestamp": "1626345819",
3811
+ # "status": "DONE",
3812
+ # "memo": ""
3813
+ # }
3477
3814
  #
3478
3815
  # withdraw
3479
3816
  #
3480
- # {
3481
- # "id": "w13389675",
3482
- # "currency": "USDT",
3483
- # "amount": "50",
3484
- # "address": "TUu2rLFrmzUodiWfYki7QCNtv1akL682p1",
3485
- # "memo": null
3486
- # }
3817
+ # {
3818
+ # "id":"w64413318",
3819
+ # "currency":"usdt",
3820
+ # "amount":"10150",
3821
+ # "address":"0x0ab891497116f7f5532a4c2f4f7b1784488628e1",
3822
+ # "memo":null,
3823
+ # "status":"REQUEST",
3824
+ # "chain":"eth",
3825
+ # "withdraw_order_id":"",
3826
+ # "fee_amount":"4.15000000"
3827
+ # }
3828
+ #
3829
+ # fetchWithdrawals
3830
+ #
3831
+ # {
3832
+ # "id": "210496",
3833
+ # "timestamp": "1542000000",
3834
+ # "withdraw_order_id": "order_123456",
3835
+ # "currency": "USDT",
3836
+ # "address": "1HkxtBAMrA3tP5ENnYY2CZortjZvFDH5Cs",
3837
+ # "txid": "128988928203223323290",
3838
+ # "block_number": "41575382",
3839
+ # "amount": "222.61",
3840
+ # "fee": "0.01",
3841
+ # "memo": "",
3842
+ # "status": "DONE",
3843
+ # "chain": "TRX"
3844
+ # }
3845
+ #
3846
+ # {
3847
+ # "id": "w13389675",
3848
+ # "currency": "USDT",
3849
+ # "amount": "50",
3850
+ # "address": "TUu2rLFrmzUodiWfYki7QCNtv1akL682p1",
3851
+ # "memo": null
3852
+ # }
3487
3853
  #
3488
3854
  # {
3489
3855
  # "currency":"usdt",
3490
- # "address":"0x01b0A9b7b4CdE774AF0f3E47CB4f1c2CCdBa0806",
3856
+ # "address":"0x01c0A9b7b4CdE774AF0f3E47CB4f1c2CCdBa0806",
3491
3857
  # "amount":"1880",
3492
3858
  # "chain":"eth"
3493
3859
  # }
@@ -3502,7 +3868,7 @@ class gate(Exchange, ImplicitAPI):
3502
3868
  amountString = Precise.string_abs(amountString)
3503
3869
  else:
3504
3870
  type = self.parse_transaction_type(id[0])
3505
- feeCostString = self.safe_string(transaction, 'fee')
3871
+ feeCostString = self.safe_string_2(transaction, 'fee', 'fee_amount')
3506
3872
  if type == 'withdrawal':
3507
3873
  amountString = Precise.string_sub(amountString, feeCostString)
3508
3874
  networkId = self.safe_string_upper(transaction, 'chain')
@@ -3543,20 +3909,22 @@ class gate(Exchange, ImplicitAPI):
3543
3909
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
3544
3910
  """
3545
3911
  Create an order on the exchange
3546
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-an-order
3547
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-a-price-triggered-order
3548
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order
3549
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-a-price-triggered-order-2
3550
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order-2
3551
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-a-price-triggered-order-3
3552
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-an-options-order
3912
+
3913
+ https://www.gate.io/docs/developers/apiv4/en/#create-an-order
3914
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-price-triggered-order
3915
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order
3916
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-price-triggered-order-2
3917
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order-2
3918
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-price-triggered-order-3
3919
+ https://www.gate.io/docs/developers/apiv4/en/#create-an-options-order
3920
+
3553
3921
  :param str symbol: Unified CCXT market symbol
3554
3922
  :param str type: 'limit' or 'market' *"market" is contract only*
3555
3923
  :param str side: 'buy' or 'sell'
3556
3924
  :param float amount: the amount of currency to trade
3557
- :param float [price]: *ignored in "market" orders* the price at which the order is to be fullfilled at in units of the quote currency
3925
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
3558
3926
  :param dict [params]: extra parameters specific to the exchange API endpoint
3559
- :param float [params.stopPrice]: The price at which a trigger order is triggered at
3927
+ :param float [params.triggerPrice]: The price at which a trigger order is triggered at
3560
3928
  :param str [params.timeInForce]: "GTC", "IOC", or "PO"
3561
3929
  :param float [params.stopLossPrice]: The price at which a stop loss order is triggered at
3562
3930
  :param float [params.takeProfitPrice]: The price at which a take profit order is triggered at
@@ -3571,9 +3939,11 @@ class gate(Exchange, ImplicitAPI):
3571
3939
  :param bool [params.auto_size]: *contract only* Set side to close dual-mode position, close_long closes the long side, while close_short the short one, size also needs to be set to 0
3572
3940
  :param int [params.price_type]: *contract only* 0 latest deal price, 1 mark price, 2 index price
3573
3941
  :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
3942
+ :param bool [params.unifiedAccount]: set to True for creating an order in the unified account
3574
3943
  :returns dict|None: `An order structure <https://docs.ccxt.com/#/?id=order-structure>`
3575
3944
  """
3576
3945
  await self.load_markets()
3946
+ await self.load_unified_status()
3577
3947
  market = self.market(symbol)
3578
3948
  trigger = self.safe_value(params, 'trigger')
3579
3949
  triggerPrice = self.safe_value_2(params, 'triggerPrice', 'stopPrice')
@@ -3581,8 +3951,8 @@ class gate(Exchange, ImplicitAPI):
3581
3951
  takeProfitPrice = self.safe_value(params, 'takeProfitPrice')
3582
3952
  isStopLossOrder = stopLossPrice is not None
3583
3953
  isTakeProfitOrder = takeProfitPrice is not None
3584
- isStopOrder = isStopLossOrder or isTakeProfitOrder
3585
- nonTriggerOrder = not isStopOrder and (trigger is None)
3954
+ isTpsl = isStopLossOrder or isTakeProfitOrder
3955
+ nonTriggerOrder = not isTpsl and (trigger is None)
3586
3956
  orderRequest = self.create_order_request(symbol, type, side, amount, price, params)
3587
3957
  response = None
3588
3958
  if market['spot'] or market['margin']:
@@ -3668,17 +4038,14 @@ class gate(Exchange, ImplicitAPI):
3668
4038
  #
3669
4039
  return self.parse_order(response, market)
3670
4040
 
3671
- async def create_orders(self, orders: List[OrderRequest], params={}):
3672
- """
3673
- create a list of trade orders
3674
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-2
3675
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-a-batch-of-orders
3676
- :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
3677
- :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3678
- """
3679
- await self.load_markets()
4041
+ def create_orders_request(self, orders: List[OrderRequest], params={}):
3680
4042
  ordersRequests = []
3681
4043
  orderSymbols = []
4044
+ ordersLength = len(orders)
4045
+ if ordersLength == 0:
4046
+ raise BadRequest(self.id + ' createOrders() requires at least one order')
4047
+ if ordersLength > 10:
4048
+ raise BadRequest(self.id + ' createOrders() accepts a maximum of 10 orders at a time')
3682
4049
  for i in range(0, len(orders)):
3683
4050
  rawOrder = orders[i]
3684
4051
  marketId = self.safe_string(rawOrder, 'symbol')
@@ -3699,6 +4066,25 @@ class gate(Exchange, ImplicitAPI):
3699
4066
  market = self.market(symbols[0])
3700
4067
  if market['future'] or market['option']:
3701
4068
  raise NotSupported(self.id + ' createOrders() does not support futures or options markets')
4069
+ return ordersRequests
4070
+
4071
+ async def create_orders(self, orders: List[OrderRequest], params={}):
4072
+ """
4073
+ create a list of trade orders
4074
+
4075
+ https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-2
4076
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-batch-of-orders
4077
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-batch-of-futures-orders
4078
+
4079
+ :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
4080
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4081
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4082
+ """
4083
+ await self.load_markets()
4084
+ await self.load_unified_status()
4085
+ ordersRequests = self.create_orders_request(orders, params)
4086
+ firstOrder = orders[0]
4087
+ market = self.market(firstOrder['symbol'])
3702
4088
  response = None
3703
4089
  if market['spot']:
3704
4090
  response = await self.privateSpotPostBatchOrders(ordersRequests)
@@ -3715,7 +4101,7 @@ class gate(Exchange, ImplicitAPI):
3715
4101
  takeProfitPrice = self.safe_value(params, 'takeProfitPrice')
3716
4102
  isStopLossOrder = stopLossPrice is not None
3717
4103
  isTakeProfitOrder = takeProfitPrice is not None
3718
- isStopOrder = isStopLossOrder or isTakeProfitOrder
4104
+ isTpsl = isStopLossOrder or isTakeProfitOrder
3719
4105
  if isStopLossOrder and isTakeProfitOrder:
3720
4106
  raise ExchangeError(self.id + ' createOrder() stopLossPrice and takeProfitPrice cannot both be defined')
3721
4107
  reduceOnly = self.safe_value(params, 'reduceOnly')
@@ -3751,7 +4137,7 @@ class gate(Exchange, ImplicitAPI):
3751
4137
  signedAmount = Precise.string_neg(amountToPrecision) if (side == 'sell') else amountToPrecision
3752
4138
  amount = int(signedAmount)
3753
4139
  request = None
3754
- nonTriggerOrder = not isStopOrder and (trigger is None)
4140
+ nonTriggerOrder = not isTpsl and (trigger is None)
3755
4141
  if nonTriggerOrder:
3756
4142
  if contract:
3757
4143
  # contract order
@@ -3768,9 +4154,9 @@ class gate(Exchange, ImplicitAPI):
3768
4154
  if not market['option']:
3769
4155
  request['settle'] = market['settleId'] # filled in prepareRequest above
3770
4156
  if isMarketOrder:
3771
- request['price'] = price # set to 0 for market orders
4157
+ request['price'] = '0' # set to 0 for market orders
3772
4158
  else:
3773
- request['price'] = self.price_to_precision(symbol, price)
4159
+ request['price'] = '0' if (price == 0) else self.price_to_precision(symbol, price)
3774
4160
  if reduceOnly is not None:
3775
4161
  request['reduce_only'] = reduceOnly
3776
4162
  if timeInForce is not None:
@@ -3783,7 +4169,7 @@ class gate(Exchange, ImplicitAPI):
3783
4169
  # 'text': clientOrderId, # 't-abcdef1234567890',
3784
4170
  'currency_pair': market['id'], # filled in prepareRequest above
3785
4171
  'type': type,
3786
- 'account': marginMode, # 'spot', 'margin', 'cross_margin'
4172
+ 'account': marginMode, # spot, margin, cross_margin, unified
3787
4173
  'side': side,
3788
4174
  # 'time_in_force': 'gtc', # gtc, ioc, poc PendingOrCancelled == postOnly order
3789
4175
  # 'iceberg': 0, # amount to display for the iceberg order, null or 0 for normal orders, set to -1 to hide the order completely
@@ -3841,7 +4227,7 @@ class gate(Exchange, ImplicitAPI):
3841
4227
  'initial': {
3842
4228
  'contract': market['id'],
3843
4229
  'size': amount, # positive = buy, negative = sell, set to 0 to close the position
3844
- 'price': self.price_to_precision(symbol, price), # set to 0 to use market price
4230
+ # 'price': '0' if (price == 0) else self.price_to_precision(symbol, price), # set to 0 to use market price
3845
4231
  # 'close': False, # set to True if trying to close the position
3846
4232
  # 'tif': 'gtc', # gtc, ioc, if using market price, only ioc is supported
3847
4233
  # 'text': clientOrderId, # web, api, app
@@ -3849,6 +4235,10 @@ class gate(Exchange, ImplicitAPI):
3849
4235
  },
3850
4236
  'settle': market['settleId'],
3851
4237
  }
4238
+ if type == 'market':
4239
+ request['initial']['price'] = '0'
4240
+ else:
4241
+ request['initial']['price'] = '0' if (price == 0) else self.price_to_precision(symbol, price)
3852
4242
  if trigger is None:
3853
4243
  rule = None
3854
4244
  triggerOrderPrice = None
@@ -3916,57 +4306,82 @@ class gate(Exchange, ImplicitAPI):
3916
4306
  async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
3917
4307
  """
3918
4308
  create a market buy order by providing the symbol and cost
3919
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-an-order
4309
+
4310
+ https://www.gate.io/docs/developers/apiv4/en/#create-an-order
4311
+
3920
4312
  :param str symbol: unified symbol of the market to create an order in
3921
4313
  :param float cost: how much you want to trade in units of the quote currency
3922
4314
  :param dict [params]: extra parameters specific to the exchange API endpoint
4315
+ :param bool [params.unifiedAccount]: set to True for creating a unified account order
3923
4316
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3924
4317
  """
3925
4318
  await self.load_markets()
4319
+ await self.load_unified_status()
3926
4320
  market = self.market(symbol)
3927
4321
  if not market['spot']:
3928
4322
  raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
3929
4323
  params['createMarketBuyOrderRequiresPrice'] = False
3930
4324
  return await self.create_order(symbol, 'market', 'buy', cost, None, params)
3931
4325
 
3932
- async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
3933
- """
3934
- edit a trade order, gate currently only supports the modification of the price or amount fields
3935
- :see: https://www.gate.io/docs/developers/apiv4/en/#amend-an-order
3936
- :see: https://www.gate.io/docs/developers/apiv4/en/#amend-an-order-2
3937
- :param str id: order id
3938
- :param str symbol: unified symbol of the market to create an order in
3939
- :param str type: 'market' or 'limit'
3940
- :param str side: 'buy' or 'sell'
3941
- :param float amount: how much of the currency you want to trade in units of the base currency
3942
- :param float [price]: the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
3943
- :param dict [params]: extra parameters specific to the exchange API endpoint
3944
- :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3945
- """
3946
- await self.load_markets()
4326
+ def edit_order_request(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
3947
4327
  market = self.market(symbol)
3948
- marketType, query = self.handle_market_type_and_params('editOrder', market, params)
4328
+ marketType = None
4329
+ marketType, params = self.handle_market_type_and_params('editOrder', market, params)
3949
4330
  account = self.convert_type_to_account(marketType)
4331
+ isUnifiedAccount = False
4332
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'editOrder', 'unifiedAccount')
4333
+ if isUnifiedAccount:
4334
+ account = 'unified'
3950
4335
  isLimitOrder = (type == 'limit')
3951
4336
  if account == 'spot':
3952
4337
  if not isLimitOrder:
3953
4338
  # exchange doesn't have market orders for spot
3954
4339
  raise InvalidOrder(self.id + ' editOrder() does not support ' + type + ' orders for ' + marketType + ' markets')
3955
- request = {
3956
- 'order_id': id,
4340
+ request: dict = {
4341
+ 'order_id': str(id),
3957
4342
  'currency_pair': market['id'],
3958
4343
  'account': account,
3959
4344
  }
3960
4345
  if amount is not None:
3961
- request['amount'] = self.amount_to_precision(symbol, amount)
4346
+ if market['spot']:
4347
+ request['amount'] = self.amount_to_precision(symbol, amount)
4348
+ else:
4349
+ if side == 'sell':
4350
+ request['size'] = self.parse_to_numeric(Precise.string_neg(self.amount_to_precision(symbol, amount)))
4351
+ else:
4352
+ request['size'] = self.parse_to_numeric(self.amount_to_precision(symbol, amount))
3962
4353
  if price is not None:
3963
4354
  request['price'] = self.price_to_precision(symbol, price)
4355
+ if not market['spot']:
4356
+ request['settle'] = market['settleId']
4357
+ return self.extend(request, params)
4358
+
4359
+ async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
4360
+ """
4361
+ edit a trade order, gate currently only supports the modification of the price or amount fields
4362
+
4363
+ https://www.gate.io/docs/developers/apiv4/en/#amend-an-order
4364
+ https://www.gate.io/docs/developers/apiv4/en/#amend-an-order-2
4365
+
4366
+ :param str id: order id
4367
+ :param str symbol: unified symbol of the market to create an order in
4368
+ :param str type: 'market' or 'limit'
4369
+ :param str side: 'buy' or 'sell'
4370
+ :param float amount: how much of the currency you want to trade in units of the base currency
4371
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
4372
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4373
+ :param bool [params.unifiedAccount]: set to True for editing an order in a unified account
4374
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4375
+ """
4376
+ await self.load_markets()
4377
+ await self.load_unified_status()
4378
+ market = self.market(symbol)
4379
+ extendedRequest = self.edit_order_request(id, symbol, type, side, amount, price, params)
3964
4380
  response = None
3965
4381
  if market['spot']:
3966
- response = await self.privateSpotPatchOrdersOrderId(self.extend(request, query))
4382
+ response = await self.privateSpotPatchOrdersOrderId(extendedRequest)
3967
4383
  else:
3968
- request['settle'] = market['settleId']
3969
- response = await self.privateFuturesPutSettleOrdersOrderId(self.extend(request, query))
4384
+ response = await self.privateFuturesPutSettleOrdersOrderId(extendedRequest)
3970
4385
  #
3971
4386
  # {
3972
4387
  # "id": "243233276443",
@@ -4000,8 +4415,8 @@ class gate(Exchange, ImplicitAPI):
4000
4415
  #
4001
4416
  return self.parse_order(response, market)
4002
4417
 
4003
- def parse_order_status(self, status):
4004
- statuses = {
4418
+ def parse_order_status(self, status: Str):
4419
+ statuses: dict = {
4005
4420
  'open': 'open',
4006
4421
  '_new': 'open',
4007
4422
  'filled': 'closed',
@@ -4016,7 +4431,7 @@ class gate(Exchange, ImplicitAPI):
4016
4431
  }
4017
4432
  return self.safe_string(statuses, status, status)
4018
4433
 
4019
- def parse_order(self, order, market: Market = None) -> Order:
4434
+ def parse_order(self, order: dict, market: Market = None) -> Order:
4020
4435
  #
4021
4436
  # SPOT
4022
4437
  # createOrder/cancelOrder/fetchOrder/editOrder
@@ -4158,6 +4573,8 @@ class gate(Exchange, ImplicitAPI):
4158
4573
  # "message": "Not enough balance"
4159
4574
  # }
4160
4575
  #
4576
+ # {"user_id":10406147,"id":"id","succeeded":false,"message":"INVALID_PROTOCOL","label":"INVALID_PROTOCOL"}
4577
+ #
4161
4578
  succeeded = self.safe_bool(order, 'succeeded', True)
4162
4579
  if not succeeded:
4163
4580
  # cancelOrders response
@@ -4165,6 +4582,7 @@ class gate(Exchange, ImplicitAPI):
4165
4582
  'clientOrderId': self.safe_string(order, 'text'),
4166
4583
  'info': order,
4167
4584
  'status': 'rejected',
4585
+ 'id': self.safe_string(order, 'id'),
4168
4586
  })
4169
4587
  put = self.safe_value_2(order, 'put', 'initial', {})
4170
4588
  trigger = self.safe_value(order, 'trigger', {})
@@ -4209,19 +4627,19 @@ class gate(Exchange, ImplicitAPI):
4209
4627
  # Everything below self(above return) is related to fees
4210
4628
  fees = []
4211
4629
  gtFee = self.safe_string(order, 'gt_fee')
4212
- if gtFee:
4630
+ if gtFee is not None:
4213
4631
  fees.append({
4214
4632
  'currency': 'GT',
4215
4633
  'cost': gtFee,
4216
4634
  })
4217
4635
  fee = self.safe_string(order, 'fee')
4218
- if fee:
4636
+ if fee is not None:
4219
4637
  fees.append({
4220
4638
  'currency': self.safe_currency_code(self.safe_string(order, 'fee_currency')),
4221
4639
  'cost': fee,
4222
4640
  })
4223
4641
  rebate = self.safe_string(order, 'rebated_fee')
4224
- if rebate:
4642
+ if rebate is not None:
4225
4643
  fees.append({
4226
4644
  'currency': self.safe_currency_code(self.safe_string(order, 'rebated_fee_currency')),
4227
4645
  'cost': Precise.string_neg(rebate),
@@ -4254,7 +4672,6 @@ class gate(Exchange, ImplicitAPI):
4254
4672
  'reduceOnly': self.safe_value(order, 'is_reduce_only'),
4255
4673
  'side': side,
4256
4674
  'price': price,
4257
- 'stopPrice': triggerPrice,
4258
4675
  'triggerPrice': triggerPrice,
4259
4676
  'average': average,
4260
4677
  'amount': Precise.string_abs(amount),
@@ -4267,50 +4684,62 @@ class gate(Exchange, ImplicitAPI):
4267
4684
  'info': order,
4268
4685
  }, market)
4269
4686
 
4687
+ def fetch_order_request(self, id: str, symbol: Str = None, params={}):
4688
+ market = None if (symbol is None) else self.market(symbol)
4689
+ trigger = self.safe_bool_n(params, ['trigger', 'is_stop_order', 'stop'], False)
4690
+ params = self.omit(params, ['is_stop_order', 'stop', 'trigger'])
4691
+ clientOrderId = self.safe_string_2(params, 'text', 'clientOrderId')
4692
+ orderId = id
4693
+ if clientOrderId is not None:
4694
+ params = self.omit(params, ['text', 'clientOrderId'])
4695
+ if clientOrderId[0] != 't':
4696
+ clientOrderId = 't-' + clientOrderId
4697
+ orderId = clientOrderId
4698
+ type, query = self.handle_market_type_and_params('fetchOrder', market, params)
4699
+ contract = (type == 'swap') or (type == 'future') or (type == 'option')
4700
+ request, requestParams = self.prepare_request(market, type, query) if contract else self.spot_order_prepare_request(market, trigger, query)
4701
+ request['order_id'] = str(orderId)
4702
+ return [request, requestParams]
4703
+
4270
4704
  async def fetch_order(self, id: str, symbol: Str = None, params={}):
4271
4705
  """
4272
4706
  Retrieves information on an order
4273
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order
4274
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-2
4275
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-3
4276
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-4
4707
+
4708
+ https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order
4709
+ https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-2
4710
+ https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-3
4711
+ https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-4
4712
+
4277
4713
  :param str id: Order id
4278
4714
  :param str symbol: Unified market symbol, *required for spot and margin*
4279
4715
  :param dict [params]: Parameters specified by the exchange api
4280
- :param bool [params.stop]: True if the order being fetched is a trigger order
4716
+ :param bool [params.trigger]: True if the order being fetched is a trigger order
4281
4717
  :param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
4282
4718
  :param str [params.type]: 'spot', 'swap', or 'future', if not provided self.options['defaultMarginMode'] is used
4283
4719
  :param str [params.settle]: 'btc' or 'usdt' - settle currency for perpetual swap and future - market settle currency is used if symbol is not None, default="usdt" for swap and "btc" for future
4720
+ :param bool [params.unifiedAccount]: set to True for fetching a unified account order
4284
4721
  :returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4285
4722
  """
4286
4723
  await self.load_markets()
4287
- stop = self.safe_value_2(params, 'is_stop_order', 'stop', False)
4288
- params = self.omit(params, ['is_stop_order', 'stop'])
4289
- clientOrderId = self.safe_string_2(params, 'text', 'clientOrderId')
4290
- orderId = id
4291
- if clientOrderId is not None:
4292
- params = self.omit(params, ['text', 'clientOrderId'])
4293
- if clientOrderId[0] != 't':
4294
- clientOrderId = 't-' + clientOrderId
4295
- orderId = clientOrderId
4724
+ await self.load_unified_status()
4296
4725
  market = None if (symbol is None) else self.market(symbol)
4297
- type, query = self.handle_market_type_and_params('fetchOrder', market, params)
4298
- contract = (type == 'swap') or (type == 'future') or (type == 'option')
4299
- request, requestParams = self.prepare_request(market, type, query) if contract else self.spot_order_prepare_request(market, stop, query)
4300
- request['order_id'] = orderId
4726
+ result = self.handle_market_type_and_params('fetchOrder', market, params)
4727
+ type = self.safe_string(result, 0)
4728
+ trigger = self.safe_bool_n(params, ['trigger', 'is_stop_order', 'stop'], False)
4729
+ request, requestParams = self.fetch_order_request(id, symbol, params)
4301
4730
  response = None
4302
4731
  if type == 'spot' or type == 'margin':
4303
- if stop:
4732
+ if trigger:
4304
4733
  response = await self.privateSpotGetPriceOrdersOrderId(self.extend(request, requestParams))
4305
4734
  else:
4306
4735
  response = await self.privateSpotGetOrdersOrderId(self.extend(request, requestParams))
4307
4736
  elif type == 'swap':
4308
- if stop:
4737
+ if trigger:
4309
4738
  response = await self.privateFuturesGetSettlePriceOrdersOrderId(self.extend(request, requestParams))
4310
4739
  else:
4311
4740
  response = await self.privateFuturesGetSettleOrdersOrderId(self.extend(request, requestParams))
4312
4741
  elif type == 'future':
4313
- if stop:
4742
+ if trigger:
4314
4743
  response = await self.privateDeliveryGetSettlePriceOrdersOrderId(self.extend(request, requestParams))
4315
4744
  else:
4316
4745
  response = await self.privateDeliveryGetSettleOrdersOrderId(self.extend(request, requestParams))
@@ -4323,14 +4752,18 @@ class gate(Exchange, ImplicitAPI):
4323
4752
  async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
4324
4753
  """
4325
4754
  fetch all unfilled currently open orders
4326
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-open-orders
4755
+
4756
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-open-orders
4757
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-running-auto-order-list
4758
+
4327
4759
  :param str symbol: unified market symbol
4328
4760
  :param int [since]: the earliest time in ms to fetch open orders for
4329
4761
  :param int [limit]: the maximum number of open orders structures to retrieve
4330
4762
  :param dict [params]: extra parameters specific to the exchange API endpoint
4331
- :param bool [params.stop]: True for fetching stop orders
4763
+ :param bool [params.trigger]: True for fetching trigger orders
4332
4764
  :param str [params.type]: spot, margin, swap or future, if not provided self.options['defaultType'] is used
4333
4765
  :param str [params.marginMode]: 'cross' or 'isolated' - marginMode for type='margin', if not provided self.options['defaultMarginMode'] is used
4766
+ :param bool [params.unifiedAccount]: set to True for fetching unified account orders
4334
4767
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4335
4768
  """
4336
4769
  return await self.fetch_orders_by_status('open', symbol, since, limit, params)
@@ -4338,58 +4771,115 @@ class gate(Exchange, ImplicitAPI):
4338
4771
  async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
4339
4772
  """
4340
4773
  fetches information on multiple closed orders made by the user
4341
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-orders
4342
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-running-auto-order-list
4343
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-futures-orders
4344
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-auto-orders
4345
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-futures-orders-2
4346
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-auto-orders-2
4347
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-options-orders
4774
+
4775
+ https://www.gate.io/docs/developers/apiv4/en/#list-orders
4776
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-running-auto-order-list
4777
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-orders
4778
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-auto-orders
4779
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-orders-2
4780
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-auto-orders-2
4781
+ https://www.gate.io/docs/developers/apiv4/en/#list-options-orders
4782
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-orders-by-time-range
4783
+
4348
4784
  :param str symbol: unified market symbol of the market orders were made in
4349
4785
  :param int [since]: the earliest time in ms to fetch orders for
4350
4786
  :param int [limit]: the maximum number of order structures to retrieve
4351
4787
  :param dict [params]: extra parameters specific to the exchange API endpoint
4352
- :param bool [params.stop]: True for fetching stop orders
4788
+ :param bool [params.trigger]: True for fetching trigger orders
4353
4789
  :param str [params.type]: spot, swap or future, if not provided self.options['defaultType'] is used
4354
4790
  :param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
4791
+ :param boolean [params.historical]: *swap only* True for using historical endpoint
4792
+ :param bool [params.unifiedAccount]: set to True for fetching unified account orders
4355
4793
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4356
4794
  """
4357
- return await self.fetch_orders_by_status('finished', symbol, since, limit, params)
4358
-
4359
- async def fetch_orders_by_status(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4360
4795
  await self.load_markets()
4796
+ await self.load_unified_status()
4797
+ until = self.safe_integer(params, 'until')
4361
4798
  market = None
4362
4799
  if symbol is not None:
4363
4800
  market = self.market(symbol)
4364
4801
  symbol = market['symbol']
4365
- stop = self.safe_value(params, 'stop')
4366
- params = self.omit(params, 'stop')
4367
- type, query = self.handle_market_type_and_params('fetchOrdersByStatus', market, params)
4368
- spot = (type == 'spot') or (type == 'margin')
4369
- request, requestParams = self.multi_order_spot_prepare_request(market, stop, query) if spot else self.prepare_request(market, type, query)
4370
- if status == 'closed':
4371
- status = 'finished'
4372
- request['status'] = status
4373
- if limit is not None:
4374
- request['limit'] = limit
4375
- if since is not None and spot:
4802
+ res = self.handle_market_type_and_params('fetchClosedOrders', market, params)
4803
+ type = self.safe_string(res, 0)
4804
+ useHistorical = False
4805
+ useHistorical, params = self.handle_option_and_params(params, 'fetchClosedOrders', 'historical', False)
4806
+ if not useHistorical and ((since is None and until is None) or (type != 'swap')):
4807
+ return await self.fetch_orders_by_status('finished', symbol, since, limit, params)
4808
+ params = self.omit(params, 'type')
4809
+ request = {}
4810
+ request, params = self.prepare_request(market, type, params)
4811
+ if since is not None:
4376
4812
  request['from'] = self.parse_to_int(since / 1000)
4377
- openSpotOrders = spot and (status == 'open') and not stop
4813
+ if until is not None:
4814
+ params = self.omit(params, 'until')
4815
+ request['to'] = self.parse_to_int(until / 1000)
4816
+ if limit is not None:
4817
+ request['limit'] = limit
4818
+ response = await self.privateFuturesGetSettleOrdersTimerange(self.extend(request, params))
4819
+ return self.parse_orders(response, market, since, limit)
4820
+
4821
+ def prepare_orders_by_status_request(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4822
+ market = None
4823
+ if symbol is not None:
4824
+ market = self.market(symbol)
4825
+ symbol = market['symbol']
4826
+ trigger: Bool = None
4827
+ trigger, params = self.handle_param_bool_2(params, 'trigger', 'stop')
4828
+ type: Str = None
4829
+ type, params = self.handle_market_type_and_params('fetchOrdersByStatus', market, params)
4830
+ spot = (type == 'spot') or (type == 'margin')
4831
+ request: dict = {}
4832
+ request, params = self.multi_order_spot_prepare_request(market, trigger, params) if spot else self.prepare_request(market, type, params)
4833
+ if spot and trigger:
4834
+ request = self.omit(request, 'account')
4835
+ if status == 'closed':
4836
+ status = 'finished'
4837
+ request['status'] = status
4838
+ if limit is not None:
4839
+ request['limit'] = limit
4840
+ if spot:
4841
+ if since is not None:
4842
+ request['from'] = self.parse_to_int(since / 1000)
4843
+ until = self.safe_integer(params, 'until')
4844
+ if until is not None:
4845
+ params = self.omit(params, 'until')
4846
+ request['to'] = self.parse_to_int(until / 1000)
4847
+ lastId, finalParams = self.handle_param_string_2(params, 'lastId', 'last_id')
4848
+ if lastId is not None:
4849
+ request['last_id'] = lastId
4850
+ return [request, finalParams]
4851
+
4852
+ async def fetch_orders_by_status(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4853
+ await self.load_markets()
4854
+ await self.load_unified_status()
4855
+ market = None
4856
+ if symbol is not None:
4857
+ market = self.market(symbol)
4858
+ symbol = market['symbol']
4859
+ # don't omit here, omits done in prepareOrdersByStatusRequest
4860
+ trigger: Bool = self.safe_bool_2(params, 'trigger', 'stop')
4861
+ res = self.handle_market_type_and_params('fetchOrdersByStatus', market, params)
4862
+ type = self.safe_string(res, 0)
4863
+ request, requestParams = self.prepare_orders_by_status_request(status, symbol, since, limit, params)
4864
+ spot = (type == 'spot') or (type == 'margin')
4865
+ openStatus = (status == 'open')
4866
+ openSpotOrders = spot and openStatus and not trigger
4378
4867
  response = None
4379
- if type == 'spot' or type == 'margin':
4380
- if openSpotOrders:
4381
- response = await self.privateSpotGetOpenOrders(self.extend(request, requestParams))
4382
- elif stop:
4383
- response = await self.privateSpotGetPriceOrders(self.extend(request, requestParams))
4868
+ if spot:
4869
+ if not trigger:
4870
+ if openStatus:
4871
+ response = await self.privateSpotGetOpenOrders(self.extend(request, requestParams))
4872
+ else:
4873
+ response = await self.privateSpotGetOrders(self.extend(request, requestParams))
4384
4874
  else:
4385
- response = await self.privateSpotGetOrders(self.extend(request, requestParams))
4875
+ response = await self.privateSpotGetPriceOrders(self.extend(request, requestParams))
4386
4876
  elif type == 'swap':
4387
- if stop:
4877
+ if trigger:
4388
4878
  response = await self.privateFuturesGetSettlePriceOrders(self.extend(request, requestParams))
4389
4879
  else:
4390
4880
  response = await self.privateFuturesGetSettleOrders(self.extend(request, requestParams))
4391
4881
  elif type == 'future':
4392
- if stop:
4882
+ if trigger:
4393
4883
  response = await self.privateDeliveryGetSettlePriceOrders(self.extend(request, requestParams))
4394
4884
  else:
4395
4885
  response = await self.privateDeliveryGetSettleOrders(self.extend(request, requestParams))
@@ -4469,7 +4959,7 @@ class gate(Exchange, ImplicitAPI):
4469
4959
  # }
4470
4960
  # ]
4471
4961
  #
4472
- # spot stop
4962
+ # spot trigger
4473
4963
  #
4474
4964
  # [
4475
4965
  # {
@@ -4555,36 +5045,40 @@ class gate(Exchange, ImplicitAPI):
4555
5045
  async def cancel_order(self, id: str, symbol: Str = None, params={}):
4556
5046
  """
4557
5047
  Cancels an open order
4558
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order
4559
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order-2
4560
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order-3
4561
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order-4
5048
+
5049
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order
5050
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order-2
5051
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order-3
5052
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order-4
5053
+
4562
5054
  :param str id: Order id
4563
5055
  :param str symbol: Unified market symbol
4564
5056
  :param dict [params]: Parameters specified by the exchange api
4565
- :param bool [params.stop]: True if the order to be cancelled is a trigger order
5057
+ :param bool [params.trigger]: True if the order to be cancelled is a trigger order
5058
+ :param bool [params.unifiedAccount]: set to True for canceling unified account orders
4566
5059
  :returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4567
5060
  """
4568
5061
  await self.load_markets()
5062
+ await self.load_unified_status()
4569
5063
  market = None if (symbol is None) else self.market(symbol)
4570
- stop = self.safe_value_2(params, 'is_stop_order', 'stop', False)
4571
- params = self.omit(params, ['is_stop_order', 'stop'])
5064
+ trigger = self.safe_bool_n(params, ['is_stop_order', 'stop', 'trigger'], False)
5065
+ params = self.omit(params, ['is_stop_order', 'stop', 'trigger'])
4572
5066
  type, query = self.handle_market_type_and_params('cancelOrder', market, params)
4573
- request, requestParams = self.spot_order_prepare_request(market, stop, query) if (type == 'spot' or type == 'margin') else self.prepare_request(market, type, query)
5067
+ request, requestParams = self.spot_order_prepare_request(market, trigger, query) if (type == 'spot' or type == 'margin') else self.prepare_request(market, type, query)
4574
5068
  request['order_id'] = id
4575
5069
  response = None
4576
5070
  if type == 'spot' or type == 'margin':
4577
- if stop:
5071
+ if trigger:
4578
5072
  response = await self.privateSpotDeletePriceOrdersOrderId(self.extend(request, requestParams))
4579
5073
  else:
4580
5074
  response = await self.privateSpotDeleteOrdersOrderId(self.extend(request, requestParams))
4581
5075
  elif type == 'swap':
4582
- if stop:
5076
+ if trigger:
4583
5077
  response = await self.privateFuturesDeleteSettlePriceOrdersOrderId(self.extend(request, requestParams))
4584
5078
  else:
4585
5079
  response = await self.privateFuturesDeleteSettleOrdersOrderId(self.extend(request, requestParams))
4586
5080
  elif type == 'future':
4587
- if stop:
5081
+ if trigger:
4588
5082
  response = await self.privateDeliveryDeleteSettlePriceOrdersOrderId(self.extend(request, requestParams))
4589
5083
  else:
4590
5084
  response = await self.privateDeliveryDeleteSettleOrdersOrderId(self.extend(request, requestParams))
@@ -4675,36 +5169,122 @@ class gate(Exchange, ImplicitAPI):
4675
5169
  #
4676
5170
  return self.parse_order(response, market)
4677
5171
 
5172
+ async def cancel_orders(self, ids: List[str], symbol: Str = None, params={}):
5173
+ """
5174
+ cancel multiple orders
5175
+
5176
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-batch-of-orders-with-an-id-list
5177
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-batch-of-orders-with-an-id-list-2
5178
+
5179
+ :param str[] ids: order ids
5180
+ :param str symbol: unified symbol of the market the order was made in
5181
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5182
+ :param bool [params.unifiedAccount]: set to True for canceling unified account orders
5183
+ :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
5184
+ """
5185
+ await self.load_markets()
5186
+ await self.load_unified_status()
5187
+ market = None
5188
+ if symbol is not None:
5189
+ market = self.market(symbol)
5190
+ type = None
5191
+ defaultSettle = 'usdt' if (market is None) else market['settle']
5192
+ settle = self.safe_string_lower(params, 'settle', defaultSettle)
5193
+ type, params = self.handle_market_type_and_params('cancelOrders', market, params)
5194
+ isSpot = (type == 'spot')
5195
+ if isSpot and (symbol is None):
5196
+ raise ArgumentsRequired(self.id + ' cancelOrders requires a symbol argument for spot markets')
5197
+ if isSpot:
5198
+ ordersRequests = []
5199
+ for i in range(0, len(ids)):
5200
+ id = ids[i]
5201
+ orderItem: dict = {
5202
+ 'id': id,
5203
+ 'symbol': symbol,
5204
+ }
5205
+ ordersRequests.append(orderItem)
5206
+ return await self.cancel_orders_for_symbols(ordersRequests, params)
5207
+ request = {
5208
+ 'settle': settle,
5209
+ }
5210
+ finalList = [request] # hacky but needs to be done here
5211
+ for i in range(0, len(ids)):
5212
+ finalList.append(ids[i])
5213
+ response = await self.privateFuturesPostSettleBatchCancelOrders(finalList)
5214
+ return self.parse_orders(response)
5215
+
5216
+ async def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
5217
+ """
5218
+ cancel multiple orders for multiple symbols
5219
+
5220
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-batch-of-orders-with-an-id-list
5221
+
5222
+ :param CancellationRequest[] orders: list of order ids with symbol, example [{"id": "a", "symbol": "BTC/USDT"}, {"id": "b", "symbol": "ETH/USDT"}]
5223
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5224
+ :param str[] [params.clientOrderIds]: client order ids
5225
+ :param bool [params.unifiedAccount]: set to True for canceling unified account orders
5226
+ :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
5227
+ """
5228
+ await self.load_markets()
5229
+ await self.load_unified_status()
5230
+ ordersRequests = []
5231
+ for i in range(0, len(orders)):
5232
+ order = orders[i]
5233
+ symbol = self.safe_string(order, 'symbol')
5234
+ market = self.market(symbol)
5235
+ if not market['spot']:
5236
+ raise NotSupported(self.id + ' cancelOrdersForSymbols() supports only spot markets')
5237
+ id = self.safe_string(order, 'id')
5238
+ orderItem: dict = {
5239
+ 'id': id,
5240
+ 'currency_pair': market['id'],
5241
+ }
5242
+ ordersRequests.append(orderItem)
5243
+ response = await self.privateSpotPostCancelBatchOrders(ordersRequests)
5244
+ #
5245
+ # [
5246
+ # {
5247
+ # "currency_pair": "BTC_USDT",
5248
+ # "id": "123456"
5249
+ # }
5250
+ # ]
5251
+ #
5252
+ return self.parse_orders(response)
5253
+
4678
5254
  async def cancel_all_orders(self, symbol: Str = None, params={}):
4679
5255
  """
4680
5256
  cancel all open orders
4681
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-in-specified-currency-pair
4682
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-matched
4683
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-matched-2
4684
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-matched-3
5257
+
5258
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-in-specified-currency-pair
5259
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-matched
5260
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-matched-2
5261
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-matched-3
5262
+
4685
5263
  :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
4686
5264
  :param dict [params]: extra parameters specific to the exchange API endpoint
5265
+ :param bool [params.unifiedAccount]: set to True for canceling unified account orders
4687
5266
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4688
5267
  """
4689
5268
  await self.load_markets()
5269
+ await self.load_unified_status()
4690
5270
  market = None if (symbol is None) else self.market(symbol)
4691
- stop = self.safe_value(params, 'stop')
4692
- params = self.omit(params, 'stop')
5271
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
5272
+ params = self.omit(params, ['stop', 'trigger'])
4693
5273
  type, query = self.handle_market_type_and_params('cancelAllOrders', market, params)
4694
- request, requestParams = self.multi_order_spot_prepare_request(market, stop, query) if (type == 'spot') else self.prepare_request(market, type, query)
5274
+ request, requestParams = self.multi_order_spot_prepare_request(market, trigger, query) if (type == 'spot') else self.prepare_request(market, type, query)
4695
5275
  response = None
4696
5276
  if type == 'spot' or type == 'margin':
4697
- if stop:
5277
+ if trigger:
4698
5278
  response = await self.privateSpotDeletePriceOrders(self.extend(request, requestParams))
4699
5279
  else:
4700
5280
  response = await self.privateSpotDeleteOrders(self.extend(request, requestParams))
4701
5281
  elif type == 'swap':
4702
- if stop:
5282
+ if trigger:
4703
5283
  response = await self.privateFuturesDeleteSettlePriceOrders(self.extend(request, requestParams))
4704
5284
  else:
4705
5285
  response = await self.privateFuturesDeleteSettleOrders(self.extend(request, requestParams))
4706
5286
  elif type == 'future':
4707
- if stop:
5287
+ if trigger:
4708
5288
  response = await self.privateDeliveryDeleteSettlePriceOrders(self.extend(request, requestParams))
4709
5289
  else:
4710
5290
  response = await self.privateDeliveryDeleteSettleOrders(self.extend(request, requestParams))
@@ -4745,7 +5325,9 @@ class gate(Exchange, ImplicitAPI):
4745
5325
  async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
4746
5326
  """
4747
5327
  transfer currency internally between wallets on the same account
4748
- :see: https://www.gate.io/docs/developers/apiv4/en/#transfer-between-trading-accounts
5328
+
5329
+ https://www.gate.io/docs/developers/apiv4/en/#transfer-between-trading-accounts
5330
+
4749
5331
  :param str code: unified currency code for currency being transferred
4750
5332
  :param float amount: the amount of currency to transfer
4751
5333
  :param str fromAccount: the account to transfer currency from
@@ -4759,8 +5341,8 @@ class gate(Exchange, ImplicitAPI):
4759
5341
  fromId = self.convert_type_to_account(fromAccount)
4760
5342
  toId = self.convert_type_to_account(toAccount)
4761
5343
  truncated = self.currency_to_precision(code, amount)
4762
- request = {
4763
- 'currency': currency['id'],
5344
+ request: dict = {
5345
+ 'currency': currency['id'], # todo: currencies have network-junctions
4764
5346
  'amount': truncated,
4765
5347
  }
4766
5348
  if not (fromId in self.options['accountsByType']):
@@ -4781,7 +5363,7 @@ class gate(Exchange, ImplicitAPI):
4781
5363
  request['currency_pair'] = market['id']
4782
5364
  params = self.omit(params, 'symbol')
4783
5365
  if (toId == 'futures') or (toId == 'delivery') or (fromId == 'futures') or (fromId == 'delivery'):
4784
- request['settle'] = currency['id']
5366
+ request['settle'] = currency['id'] # todo: currencies have network-junctions
4785
5367
  response = await self.privateWalletPostTransfers(self.extend(request, params))
4786
5368
  #
4787
5369
  # according to the docs(however actual response seems to be an empty string '')
@@ -4796,7 +5378,7 @@ class gate(Exchange, ImplicitAPI):
4796
5378
  #
4797
5379
  return self.parse_transfer(response, currency)
4798
5380
 
4799
- def parse_transfer(self, transfer, currency: Currency = None):
5381
+ def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
4800
5382
  #
4801
5383
  # {
4802
5384
  # "currency": "BTC",
@@ -4821,8 +5403,10 @@ class gate(Exchange, ImplicitAPI):
4821
5403
  async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
4822
5404
  """
4823
5405
  set the level of leverage for a market
4824
- :see: https://www.gate.io/docs/developers/apiv4/en/#update-position-leverage
4825
- :see: https://www.gate.io/docs/developers/apiv4/en/#update-position-leverage-2
5406
+
5407
+ https://www.gate.io/docs/developers/apiv4/en/#update-position-leverage
5408
+ https://www.gate.io/docs/developers/apiv4/en/#update-position-leverage-2
5409
+
4826
5410
  :param float leverage: the rate of leverage
4827
5411
  :param str symbol: unified market symbol
4828
5412
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -4885,7 +5469,7 @@ class gate(Exchange, ImplicitAPI):
4885
5469
  #
4886
5470
  return response
4887
5471
 
4888
- def parse_position(self, position, market: Market = None):
5472
+ def parse_position(self, position: dict, market: Market = None):
4889
5473
  #
4890
5474
  # swap and future
4891
5475
  #
@@ -4942,37 +5526,61 @@ class gate(Exchange, ImplicitAPI):
4942
5526
  # "pending_orders": 0
4943
5527
  # }
4944
5528
  #
5529
+ # fetchPositionsHistory(swap and future)
5530
+ #
5531
+ # {
5532
+ # "contract": "SLERF_USDT", # Futures contract
5533
+ # "text": "web", # Text of close order
5534
+ # "long_price": "0.766306", # When 'side' is 'long,' it indicates the opening average price; when 'side' is 'short,' it indicates the closing average price.
5535
+ # "pnl": "-23.41702352", # PNL
5536
+ # "pnl_pnl": "-22.7187", # Position P/L
5537
+ # "pnl_fee": "-0.06527125", # Transaction Fees
5538
+ # "pnl_fund": "-0.63305227", # Funding Fees
5539
+ # "accum_size": "100",
5540
+ # "time": 1711279263, # Position close time
5541
+ # "short_price": "0.539119", # When 'side' is 'long,' it indicates the opening average price; when 'side' is 'short,' it indicates the closing average price
5542
+ # "side": "long", # Position side, long or short
5543
+ # "max_size": "100", # Max Trade Size
5544
+ # "first_open_time": 1711037985 # First Open Time
5545
+ # }
5546
+ #
4945
5547
  contract = self.safe_string(position, 'contract')
4946
5548
  market = self.safe_market(contract, market, '_', 'contract')
4947
- size = self.safe_string(position, 'size')
4948
- side = None
4949
- if Precise.string_gt(size, '0'):
4950
- side = 'long'
4951
- elif Precise.string_lt(size, '0'):
4952
- side = 'short'
5549
+ size = self.safe_string_2(position, 'size', 'accum_size')
5550
+ side = self.safe_string(position, 'side')
5551
+ if side is None:
5552
+ if Precise.string_gt(size, '0'):
5553
+ side = 'long'
5554
+ elif Precise.string_lt(size, '0'):
5555
+ side = 'short'
4953
5556
  maintenanceRate = self.safe_string(position, 'maintenance_rate')
4954
5557
  notional = self.safe_string(position, 'value')
4955
5558
  leverage = self.safe_string(position, 'leverage')
4956
5559
  marginMode = None
4957
- if leverage == '0':
4958
- marginMode = 'cross'
4959
- else:
4960
- marginMode = 'isolated'
4961
- unrealisedPnl = self.safe_string(position, 'unrealised_pnl')
5560
+ if leverage is not None:
5561
+ if leverage == '0':
5562
+ marginMode = 'cross'
5563
+ else:
5564
+ marginMode = 'isolated'
4962
5565
  # Initial Position Margin = ( Position Value / Leverage ) + Close Position Fee
4963
5566
  # *The default leverage under the full position is the highest leverage in the market.
4964
5567
  # *Trading fee is charged Fee Rate(0.075%).
4965
- takerFee = '0.00075'
4966
- feePaid = Precise.string_mul(takerFee, notional)
4967
- initialMarginString = Precise.string_add(Precise.string_div(notional, leverage), feePaid)
4968
- timestamp = self.safe_timestamp(position, 'open_time')
5568
+ feePaid = self.safe_string(position, 'pnl_fee')
5569
+ initialMarginString = None
5570
+ if feePaid is None:
5571
+ takerFee = '0.00075'
5572
+ feePaid = Precise.string_mul(takerFee, notional)
5573
+ initialMarginString = Precise.string_add(Precise.string_div(notional, leverage), feePaid)
5574
+ timestamp = self.safe_timestamp_2(position, 'open_time', 'first_open_time')
5575
+ if timestamp == 0:
5576
+ timestamp = None
4969
5577
  return self.safe_position({
4970
5578
  'info': position,
4971
5579
  'id': None,
4972
5580
  'symbol': self.safe_string(market, 'symbol'),
4973
5581
  'timestamp': timestamp,
4974
5582
  'datetime': self.iso8601(timestamp),
4975
- 'lastUpdateTimestamp': self.safe_timestamp(position, 'update_time'),
5583
+ 'lastUpdateTimestamp': self.safe_timestamp_2(position, 'update_time', 'time'),
4976
5584
  'initialMargin': self.parse_number(initialMarginString),
4977
5585
  'initialMarginPercentage': self.parse_number(Precise.string_div(initialMarginString, notional)),
4978
5586
  'maintenanceMargin': self.parse_number(Precise.string_mul(maintenanceRate, notional)),
@@ -4980,11 +5588,10 @@ class gate(Exchange, ImplicitAPI):
4980
5588
  'entryPrice': self.safe_number(position, 'entry_price'),
4981
5589
  'notional': self.parse_number(notional),
4982
5590
  'leverage': self.safe_number(position, 'leverage'),
4983
- 'unrealizedPnl': self.parse_number(unrealisedPnl),
4984
- 'realizedPnl': self.safe_number(position, 'realised_pnl'),
5591
+ 'unrealizedPnl': self.safe_number(position, 'unrealised_pnl'),
5592
+ 'realizedPnl': self.safe_number_2(position, 'realised_pnl', 'pnl'),
4985
5593
  'contracts': self.parse_number(Precise.string_abs(size)),
4986
- 'contractSize': self.safe_value(market, 'contractSize'),
4987
- # 'realisedPnl': position['realised_pnl'],
5594
+ 'contractSize': self.safe_number(market, 'contractSize'),
4988
5595
  'marginRatio': None,
4989
5596
  'liquidationPrice': self.safe_number(position, 'liq_price'),
4990
5597
  'markPrice': self.safe_number(position, 'mark_price'),
@@ -5000,9 +5607,11 @@ class gate(Exchange, ImplicitAPI):
5000
5607
  async def fetch_position(self, symbol: str, params={}):
5001
5608
  """
5002
5609
  fetch data on an open contract position
5003
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-single-position
5004
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-single-position-2
5005
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-specified-contract-position
5610
+
5611
+ https://www.gate.io/docs/developers/apiv4/en/#get-single-position
5612
+ https://www.gate.io/docs/developers/apiv4/en/#get-single-position-2
5613
+ https://www.gate.io/docs/developers/apiv4/en/#get-specified-contract-position
5614
+
5006
5615
  :param str symbol: unified market symbol of the market the position is held in
5007
5616
  :param dict [params]: extra parameters specific to the exchange API endpoint
5008
5617
  :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
@@ -5011,7 +5620,7 @@ class gate(Exchange, ImplicitAPI):
5011
5620
  market = self.market(symbol)
5012
5621
  if not market['contract']:
5013
5622
  raise BadRequest(self.id + ' fetchPosition() supports contract markets only')
5014
- request = {}
5623
+ request: dict = {}
5015
5624
  request, params = self.prepare_request(market, market['type'], params)
5016
5625
  extendedRequest = self.extend(request, params)
5017
5626
  response = None
@@ -5082,9 +5691,11 @@ class gate(Exchange, ImplicitAPI):
5082
5691
  async def fetch_positions(self, symbols: Strings = None, params={}):
5083
5692
  """
5084
5693
  fetch all open positions
5085
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-positions-of-a-user
5086
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-positions-of-a-user-2
5087
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-user-s-positions-of-specified-underlying
5694
+
5695
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-positions-of-a-user
5696
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-positions-of-a-user-2
5697
+ https://www.gate.io/docs/developers/apiv4/en/#list-user-s-positions-of-specified-underlying
5698
+
5088
5699
  :param str[]|None symbols: Not used by gate, but parsed internally by CCXT
5089
5700
  :param dict [params]: extra parameters specific to the exchange API endpoint
5090
5701
  :param str [params.settle]: 'btc' or 'usdt' - settle currency for perpetual swap and future - default="usdt" for swap and "btc" for future
@@ -5099,7 +5710,7 @@ class gate(Exchange, ImplicitAPI):
5099
5710
  if symbolsLength > 0:
5100
5711
  market = self.market(symbols[0])
5101
5712
  type = None
5102
- request = {}
5713
+ request: dict = {}
5103
5714
  type, params = self.handle_market_type_and_params('fetchPositions', market, params)
5104
5715
  if (type is None) or (type == 'spot'):
5105
5716
  type = 'swap' # default to swap
@@ -5179,11 +5790,13 @@ class gate(Exchange, ImplicitAPI):
5179
5790
  #
5180
5791
  return self.parse_positions(response, symbols)
5181
5792
 
5182
- async def fetch_leverage_tiers(self, symbols: Strings = None, params={}):
5793
+ async def fetch_leverage_tiers(self, symbols: Strings = None, params={}) -> LeverageTiers:
5183
5794
  """
5184
5795
  retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
5185
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts
5186
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts-2
5796
+
5797
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts
5798
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts-2
5799
+
5187
5800
  :param str[] [symbols]: list of unified market symbols
5188
5801
  :param dict [params]: extra parameters specific to the exchange API endpoint
5189
5802
  :returns dict: a dictionary of `leverage tiers structures <https://docs.ccxt.com/#/?id=leverage-tiers-structure>`, indexed by market symbols
@@ -5294,10 +5907,12 @@ class gate(Exchange, ImplicitAPI):
5294
5907
  #
5295
5908
  return self.parse_leverage_tiers(response, symbols, 'name')
5296
5909
 
5297
- async def fetch_market_leverage_tiers(self, symbol: str, params={}):
5910
+ async def fetch_market_leverage_tiers(self, symbol: str, params={}) -> List[LeverageTier]:
5298
5911
  """
5299
5912
  retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes for a single market
5300
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-risk-limit-tiers
5913
+
5914
+ https://www.gate.io/docs/developers/apiv4/en/#list-risk-limit-tiers
5915
+
5301
5916
  :param str symbol: unified market symbol
5302
5917
  :param dict [params]: extra parameters specific to the exchange API endpoint
5303
5918
  :returns dict: a `leverage tiers structure <https://docs.ccxt.com/#/?id=leverage-tiers-structure>`
@@ -5322,7 +5937,8 @@ class gate(Exchange, ImplicitAPI):
5322
5937
  #
5323
5938
  return self.parse_market_leverage_tiers(response, market)
5324
5939
 
5325
- def parse_emulated_leverage_tiers(self, info, market=None):
5940
+ def parse_emulated_leverage_tiers(self, info, market=None) -> List[LeverageTier]:
5941
+ marketId = self.safe_string(info, 'name')
5326
5942
  maintenanceMarginUnit = self.safe_string(info, 'maintenance_rate') # '0.005',
5327
5943
  leverageMax = self.safe_string(info, 'leverage_max') # '100',
5328
5944
  riskLimitStep = self.safe_string(info, 'risk_limit_step') # '1000000',
@@ -5336,6 +5952,7 @@ class gate(Exchange, ImplicitAPI):
5336
5952
  cap = Precise.string_add(floor, riskLimitStep)
5337
5953
  tiers.append({
5338
5954
  'tier': self.parse_number(Precise.string_div(cap, riskLimitStep)),
5955
+ 'symbol': self.safe_symbol(marketId, market, None, 'contract'),
5339
5956
  'currency': self.safe_string(market, 'settle'),
5340
5957
  'minNotional': self.parse_number(floor),
5341
5958
  'maxNotional': self.parse_number(cap),
@@ -5348,7 +5965,7 @@ class gate(Exchange, ImplicitAPI):
5348
5965
  floor = cap
5349
5966
  return tiers
5350
5967
 
5351
- def parse_market_leverage_tiers(self, info, market: Market = None):
5968
+ def parse_market_leverage_tiers(self, info, market: Market = None) -> List[LeverageTier]:
5352
5969
  #
5353
5970
  # [
5354
5971
  # {
@@ -5369,6 +5986,7 @@ class gate(Exchange, ImplicitAPI):
5369
5986
  maxNotional = self.safe_number(item, 'risk_limit')
5370
5987
  tiers.append({
5371
5988
  'tier': self.sum(i, 1),
5989
+ 'symbol': market['symbol'],
5372
5990
  'currency': market['base'],
5373
5991
  'minNotional': minNotional,
5374
5992
  'maxNotional': maxNotional,
@@ -5382,7 +6000,9 @@ class gate(Exchange, ImplicitAPI):
5382
6000
  async def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
5383
6001
  """
5384
6002
  repay borrowed margin and interest
5385
- :see: https://www.gate.io/docs/apiv4/en/#repay-a-loan
6003
+
6004
+ https://www.gate.io/docs/apiv4/en/#repay-a-loan
6005
+
5386
6006
  :param str symbol: unified market symbol
5387
6007
  :param str code: unified currency code of the currency to repay
5388
6008
  :param float amount: the amount to repay
@@ -5393,8 +6013,8 @@ class gate(Exchange, ImplicitAPI):
5393
6013
  """
5394
6014
  await self.load_markets()
5395
6015
  currency = self.currency(code)
5396
- request = {
5397
- 'currency': currency['id'].upper(),
6016
+ request: dict = {
6017
+ 'currency': currency['id'].upper(), # todo: currencies have network-junctions
5398
6018
  'amount': self.currency_to_precision(code, amount),
5399
6019
  }
5400
6020
  market = self.market(symbol)
@@ -5409,56 +6029,69 @@ class gate(Exchange, ImplicitAPI):
5409
6029
  async def repay_cross_margin(self, code: str, amount, params={}):
5410
6030
  """
5411
6031
  repay cross margin borrowed margin and interest
5412
- :see: https://www.gate.io/docs/developers/apiv4/en/#cross-margin-repayments
6032
+
6033
+ https://www.gate.io/docs/developers/apiv4/en/#cross-margin-repayments
6034
+ https://www.gate.io/docs/developers/apiv4/en/#borrow-or-repay
6035
+
5413
6036
  :param str code: unified currency code of the currency to repay
5414
6037
  :param float amount: the amount to repay
5415
- :param str symbol: unified market symbol, required for isolated margin
5416
6038
  :param dict [params]: extra parameters specific to the exchange API endpoint
5417
6039
  :param str [params.mode]: 'all' or 'partial' payment mode, extra parameter required for isolated margin
5418
6040
  :param str [params.id]: '34267567' loan id, extra parameter required for isolated margin
6041
+ :param boolean [params.unifiedAccount]: set to True for repaying in the unified account
5419
6042
  :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
5420
6043
  """
5421
6044
  await self.load_markets()
6045
+ await self.load_unified_status()
5422
6046
  currency = self.currency(code)
5423
- request = {
5424
- 'currency': currency['id'].upper(),
6047
+ request: dict = {
6048
+ 'currency': currency['id'].upper(), # todo: currencies have network-junctions
5425
6049
  'amount': self.currency_to_precision(code, amount),
5426
6050
  }
5427
- response = await self.privateMarginPostCrossRepayments(self.extend(request, params))
5428
- #
5429
- # [
5430
- # {
5431
- # "id": "17",
5432
- # "create_time": 1620381696159,
5433
- # "update_time": 1620381696159,
5434
- # "currency": "EOS",
5435
- # "amount": "110.553635",
5436
- # "text": "web",
5437
- # "status": 2,
5438
- # "repaid": "110.506649705159",
5439
- # "repaid_interest": "0.046985294841",
5440
- # "unpaid_interest": "0.0000074393366667"
5441
- # }
5442
- # ]
5443
- #
5444
- response = self.safe_value(response, 0)
6051
+ isUnifiedAccount = False
6052
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'repayCrossMargin', 'unifiedAccount')
6053
+ response = None
6054
+ if isUnifiedAccount:
6055
+ request['type'] = 'repay'
6056
+ response = await self.privateUnifiedPostLoans(self.extend(request, params))
6057
+ else:
6058
+ response = await self.privateMarginPostCrossRepayments(self.extend(request, params))
6059
+ response = self.safe_dict(response, 0)
6060
+ #
6061
+ # [
6062
+ # {
6063
+ # "id": "17",
6064
+ # "create_time": 1620381696159,
6065
+ # "update_time": 1620381696159,
6066
+ # "currency": "EOS",
6067
+ # "amount": "110.553635",
6068
+ # "text": "web",
6069
+ # "status": 2,
6070
+ # "repaid": "110.506649705159",
6071
+ # "repaid_interest": "0.046985294841",
6072
+ # "unpaid_interest": "0.0000074393366667"
6073
+ # }
6074
+ # ]
6075
+ #
5445
6076
  return self.parse_margin_loan(response, currency)
5446
6077
 
5447
6078
  async def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
5448
6079
  """
5449
6080
  create a loan to borrow margin
5450
- :see: https://www.gate.io/docs/developers/apiv4/en/#marginuni
6081
+
6082
+ https://www.gate.io/docs/developers/apiv4/en/#marginuni
6083
+
6084
+ :param str symbol: unified market symbol, required for isolated margin
5451
6085
  :param str code: unified currency code of the currency to borrow
5452
6086
  :param float amount: the amount to borrow
5453
- :param str symbol: unified market symbol, required for isolated margin
5454
6087
  :param dict [params]: extra parameters specific to the exchange API endpoint
5455
6088
  :param str [params.rate]: '0.0002' or '0.002' extra parameter required for isolated margin
5456
6089
  :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
5457
6090
  """
5458
6091
  await self.load_markets()
5459
6092
  currency = self.currency(code)
5460
- request = {
5461
- 'currency': currency['id'].upper(),
6093
+ request: dict = {
6094
+ 'currency': currency['id'].upper(), # todo: currencies have network-junctions
5462
6095
  'amount': self.currency_to_precision(code, amount),
5463
6096
  }
5464
6097
  response = None
@@ -5490,35 +6123,46 @@ class gate(Exchange, ImplicitAPI):
5490
6123
  async def borrow_cross_margin(self, code: str, amount: float, params={}):
5491
6124
  """
5492
6125
  create a loan to borrow margin
5493
- :see: https://www.gate.io/docs/apiv4/en/#create-a-cross-margin-borrow-loan
6126
+
6127
+ https://www.gate.io/docs/apiv4/en/#create-a-cross-margin-borrow-loan
6128
+ https://www.gate.io/docs/developers/apiv4/en/#borrow-or-repay
6129
+
5494
6130
  :param str code: unified currency code of the currency to borrow
5495
6131
  :param float amount: the amount to borrow
5496
- :param str symbol: unified market symbol, required for isolated margin
5497
6132
  :param dict [params]: extra parameters specific to the exchange API endpoint
5498
6133
  :param str [params.rate]: '0.0002' or '0.002' extra parameter required for isolated margin
6134
+ :param boolean [params.unifiedAccount]: set to True for borrowing in the unified account
5499
6135
  :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
5500
6136
  """
5501
6137
  await self.load_markets()
6138
+ await self.load_unified_status()
5502
6139
  currency = self.currency(code)
5503
- request = {
5504
- 'currency': currency['id'].upper(),
6140
+ request: dict = {
6141
+ 'currency': currency['id'].upper(), # todo: currencies have network-junctions
5505
6142
  'amount': self.currency_to_precision(code, amount),
5506
6143
  }
5507
- response = await self.privateMarginPostCrossLoans(self.extend(request, params))
5508
- #
5509
- # {
5510
- # "id": "17",
5511
- # "create_time": 1620381696159,
5512
- # "update_time": 1620381696159,
5513
- # "currency": "EOS",
5514
- # "amount": "110.553635",
5515
- # "text": "web",
5516
- # "status": 2,
5517
- # "repaid": "110.506649705159",
5518
- # "repaid_interest": "0.046985294841",
5519
- # "unpaid_interest": "0.0000074393366667"
5520
- # }
5521
- #
6144
+ isUnifiedAccount = False
6145
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'borrowCrossMargin', 'unifiedAccount')
6146
+ response = None
6147
+ if isUnifiedAccount:
6148
+ request['type'] = 'borrow'
6149
+ response = await self.privateUnifiedPostLoans(self.extend(request, params))
6150
+ else:
6151
+ response = await self.privateMarginPostCrossLoans(self.extend(request, params))
6152
+ #
6153
+ # {
6154
+ # "id": "17",
6155
+ # "create_time": 1620381696159,
6156
+ # "update_time": 1620381696159,
6157
+ # "currency": "EOS",
6158
+ # "amount": "110.553635",
6159
+ # "text": "web",
6160
+ # "status": 2,
6161
+ # "repaid": "110.506649705159",
6162
+ # "repaid_interest": "0.046985294841",
6163
+ # "unpaid_interest": "0.0000074393366667"
6164
+ # }
6165
+ #
5522
6166
  return self.parse_margin_loan(response, currency)
5523
6167
 
5524
6168
  def parse_margin_loan(self, info, currency: Currency = None):
@@ -5574,11 +6218,91 @@ class gate(Exchange, ImplicitAPI):
5574
6218
  'info': info,
5575
6219
  }
5576
6220
 
6221
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
6222
+ """
6223
+ fetch the interest owed by the user for borrowing currency for margin trading
6224
+
6225
+ https://www.gate.io/docs/developers/apiv4/en/#list-interest-records
6226
+ https://www.gate.io/docs/developers/apiv4/en/#interest-records-for-the-cross-margin-account
6227
+ https://www.gate.io/docs/developers/apiv4/en/#list-interest-records-2
6228
+
6229
+ :param str [code]: unified currency code
6230
+ :param str [symbol]: unified market symbol when fetching interest in isolated markets
6231
+ :param int [since]: the earliest time in ms to fetch borrow interest for
6232
+ :param int [limit]: the maximum number of structures to retrieve
6233
+ :param dict [params]: extra parameters specific to the exchange API endpoint
6234
+ :param boolean [params.unifiedAccount]: set to True for fetching borrow interest in the unified account
6235
+ :returns dict[]: a list of `borrow interest structures <https://docs.ccxt.com/#/?id=borrow-interest-structure>`
6236
+ """
6237
+ await self.load_markets()
6238
+ await self.load_unified_status()
6239
+ isUnifiedAccount = False
6240
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'fetchBorrowInterest', 'unifiedAccount')
6241
+ request: dict = {}
6242
+ request, params = self.handle_until_option('to', request, params)
6243
+ currency = None
6244
+ if code is not None:
6245
+ currency = self.currency(code)
6246
+ request['currency'] = currency['id']
6247
+ market = None
6248
+ if symbol is not None:
6249
+ market = self.market(symbol)
6250
+ if since is not None:
6251
+ request['from'] = since
6252
+ if limit is not None:
6253
+ request['limit'] = limit
6254
+ response = None
6255
+ marginMode = None
6256
+ marginMode, params = self.handle_margin_mode_and_params('fetchBorrowInterest', params, 'cross')
6257
+ if isUnifiedAccount:
6258
+ response = await self.privateUnifiedGetInterestRecords(self.extend(request, params))
6259
+ elif marginMode == 'isolated':
6260
+ if market is not None:
6261
+ request['currency_pair'] = market['id']
6262
+ response = await self.privateMarginGetUniInterestRecords(self.extend(request, params))
6263
+ elif marginMode == 'cross':
6264
+ response = await self.privateMarginGetCrossInterestRecords(self.extend(request, params))
6265
+ interest = self.parse_borrow_interests(response, market)
6266
+ return self.filter_by_currency_since_limit(interest, code, since, limit)
6267
+
6268
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
6269
+ marketId = self.safe_string(info, 'currency_pair')
6270
+ market = self.safe_market(marketId, market)
6271
+ marginMode = 'isolated' if (marketId is not None) else 'cross'
6272
+ timestamp = self.safe_integer(info, 'create_time')
6273
+ return {
6274
+ 'info': info,
6275
+ 'symbol': self.safe_string(market, 'symbol'),
6276
+ 'currency': self.safe_currency_code(self.safe_string(info, 'currency')),
6277
+ 'interest': self.safe_number(info, 'interest'),
6278
+ 'interestRate': self.safe_number(info, 'actual_rate'),
6279
+ 'amountBorrowed': None,
6280
+ 'marginMode': marginMode,
6281
+ 'timestamp': timestamp,
6282
+ 'datetime': self.iso8601(timestamp),
6283
+ }
6284
+
6285
+ def nonce(self):
6286
+ return self.milliseconds() - self.options['timeDifference']
6287
+
5577
6288
  def sign(self, path, api=[], method='GET', params={}, headers=None, body=None):
5578
6289
  authentication = api[0] # public, private
5579
6290
  type = api[1] # spot, margin, future, delivery
5580
6291
  query = self.omit(params, self.extract_params(path))
5581
- if isinstance(params, list):
6292
+ containsSettle = path.find('settle') > -1
6293
+ if containsSettle and path.endswith('batch_cancel_orders'): # weird check to prevent $settle in php and converting {settle} to array(settle)
6294
+ # special case where we need to extract the settle from the path
6295
+ # but the body is an array of strings
6296
+ settle = self.safe_dict(params, 0)
6297
+ path = self.implode_params(path, settle)
6298
+ # remove the first element from params
6299
+ newParams = []
6300
+ anyParams = params
6301
+ for i in range(1, len(anyParams)):
6302
+ newParams.append(params[i])
6303
+ params = newParams
6304
+ query = newParams
6305
+ elif isinstance(params, list):
5582
6306
  # endpoints like createOrders use an array instead of an object
5583
6307
  # so we infer the settle from one of the elements
5584
6308
  # they have to be all the same so relying on the first one is fine
@@ -5620,7 +6344,8 @@ class gate(Exchange, ImplicitAPI):
5620
6344
  body = self.json(query)
5621
6345
  bodyPayload = '' if (body is None) else body
5622
6346
  bodySignature = self.hash(self.encode(bodyPayload), 'sha512')
5623
- timestamp = self.seconds()
6347
+ nonce = self.nonce()
6348
+ timestamp = self.parse_to_int(nonce / 1000)
5624
6349
  timestampString = str(timestamp)
5625
6350
  signaturePath = '/api/' + self.version + entirePath
5626
6351
  payloadArray = [method.upper(), signaturePath, queryString, bodySignature, timestampString]
@@ -5649,7 +6374,7 @@ class gate(Exchange, ImplicitAPI):
5649
6374
  raise NotSupported(self.id + ' modifyMarginHelper() not support self market type')
5650
6375
  return self.parse_margin_modification(response, market)
5651
6376
 
5652
- def parse_margin_modification(self, data, market: Market = None):
6377
+ def parse_margin_modification(self, data: dict, market: Market = None) -> MarginModification:
5653
6378
  #
5654
6379
  # {
5655
6380
  # "value": "11.9257",
@@ -5682,18 +6407,24 @@ class gate(Exchange, ImplicitAPI):
5682
6407
  total = self.safe_number(data, 'margin')
5683
6408
  return {
5684
6409
  'info': data,
5685
- 'amount': None,
5686
- 'code': self.safe_value(market, 'quote'),
5687
6410
  'symbol': market['symbol'],
6411
+ 'type': None,
6412
+ 'marginMode': 'isolated',
6413
+ 'amount': None,
5688
6414
  'total': total,
6415
+ 'code': self.safe_value(market, 'quote'),
5689
6416
  'status': 'ok',
6417
+ 'timestamp': None,
6418
+ 'datetime': None,
5690
6419
  }
5691
6420
 
5692
- async def reduce_margin(self, symbol: str, amount, params={}):
6421
+ async def reduce_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
5693
6422
  """
5694
6423
  remove margin from a position
5695
- :see: https://www.gate.io/docs/developers/apiv4/en/#update-position-margin
5696
- :see: https://www.gate.io/docs/developers/apiv4/en/#update-position-margin-2
6424
+
6425
+ https://www.gate.io/docs/developers/apiv4/en/#update-position-margin
6426
+ https://www.gate.io/docs/developers/apiv4/en/#update-position-margin-2
6427
+
5697
6428
  :param str symbol: unified market symbol
5698
6429
  :param float amount: the amount of margin to remove
5699
6430
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -5701,11 +6432,13 @@ class gate(Exchange, ImplicitAPI):
5701
6432
  """
5702
6433
  return await self.modify_margin_helper(symbol, -amount, params)
5703
6434
 
5704
- async def add_margin(self, symbol: str, amount, params={}):
6435
+ async def add_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
5705
6436
  """
5706
6437
  add margin
5707
- :see: https://www.gate.io/docs/developers/apiv4/en/#update-position-margin
5708
- :see: https://www.gate.io/docs/developers/apiv4/en/#update-position-margin-2
6438
+
6439
+ https://www.gate.io/docs/developers/apiv4/en/#update-position-margin
6440
+ https://www.gate.io/docs/developers/apiv4/en/#update-position-margin-2
6441
+
5709
6442
  :param str symbol: unified market symbol
5710
6443
  :param float amount: amount of margin to add
5711
6444
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -5716,7 +6449,9 @@ class gate(Exchange, ImplicitAPI):
5716
6449
  async def fetch_open_interest_history(self, symbol: str, timeframe='5m', since: Int = None, limit: Int = None, params={}):
5717
6450
  """
5718
6451
  Retrieves the open interest of a currency
5719
- :see: https://www.gate.io/docs/developers/apiv4/en/#futures-stats
6452
+
6453
+ https://www.gate.io/docs/developers/apiv4/en/#futures-stats
6454
+
5720
6455
  :param str symbol: Unified CCXT market symbol
5721
6456
  :param str timeframe: "5m", "15m", "30m", "1h", "4h", "1d"
5722
6457
  :param int [since]: the time(ms) of the earliest record to retrieve unix timestamp
@@ -5733,7 +6468,7 @@ class gate(Exchange, ImplicitAPI):
5733
6468
  market = self.market(symbol)
5734
6469
  if not market['swap']:
5735
6470
  raise BadRequest(self.id + ' fetchOpenInterest() supports swap markets only')
5736
- request = {
6471
+ request: dict = {
5737
6472
  'contract': market['id'],
5738
6473
  'settle': market['settleId'],
5739
6474
  'interval': self.safe_string(self.timeframes, timeframe, timeframe),
@@ -5764,7 +6499,7 @@ class gate(Exchange, ImplicitAPI):
5764
6499
  # ...
5765
6500
  # ]
5766
6501
  #
5767
- return self.parse_open_interests(response, market, since, limit)
6502
+ return self.parse_open_interests_history(response, market, since, limit)
5768
6503
 
5769
6504
  def parse_open_interest(self, interest, market: Market = None):
5770
6505
  #
@@ -5798,7 +6533,9 @@ class gate(Exchange, ImplicitAPI):
5798
6533
  async def fetch_settlement_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5799
6534
  """
5800
6535
  fetches historical settlement records
5801
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-settlement-history-2
6536
+
6537
+ https://www.gate.io/docs/developers/apiv4/en/#list-settlement-history-2
6538
+
5802
6539
  :param str symbol: unified market symbol of the settlement history, required on gate
5803
6540
  :param int [since]: timestamp in ms
5804
6541
  :param int [limit]: number of records
@@ -5815,7 +6552,7 @@ class gate(Exchange, ImplicitAPI):
5815
6552
  raise NotSupported(self.id + ' fetchSettlementHistory() supports option markets only')
5816
6553
  marketId = market['id']
5817
6554
  optionParts = marketId.split('-')
5818
- request = {
6555
+ request: dict = {
5819
6556
  'underlying': self.safe_string(optionParts, 0),
5820
6557
  }
5821
6558
  if since is not None:
@@ -5842,7 +6579,9 @@ class gate(Exchange, ImplicitAPI):
5842
6579
  async def fetch_my_settlement_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5843
6580
  """
5844
6581
  fetches historical settlement records of the user
5845
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-my-options-settlements
6582
+
6583
+ https://www.gate.io/docs/developers/apiv4/en/#list-my-options-settlements
6584
+
5846
6585
  :param str symbol: unified market symbol of the settlement history
5847
6586
  :param int [since]: timestamp in ms
5848
6587
  :param int [limit]: number of records
@@ -5859,7 +6598,7 @@ class gate(Exchange, ImplicitAPI):
5859
6598
  raise NotSupported(self.id + ' fetchMySettlementHistory() supports option markets only')
5860
6599
  marketId = market['id']
5861
6600
  optionParts = marketId.split('-')
5862
- request = {
6601
+ request: dict = {
5863
6602
  'underlying': self.safe_string(optionParts, 0),
5864
6603
  'contract': marketId,
5865
6604
  }
@@ -5962,21 +6701,23 @@ class gate(Exchange, ImplicitAPI):
5962
6701
  result.append(self.parse_settlement(settlements[i], market))
5963
6702
  return result
5964
6703
 
5965
- async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
6704
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
5966
6705
  """
5967
6706
  fetch the history of changes, actions done by the user or operations that altered the balance of the user
5968
- :see: https://www.gate.io/docs/developers/apiv4/en/#query-account-book
5969
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-margin-account-balance-change-history
5970
- :see: https://www.gate.io/docs/developers/apiv4/en/#query-account-book-2
5971
- :see: https://www.gate.io/docs/developers/apiv4/en/#query-account-book-3
5972
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-account-changing-history
5973
- :param str code: unified currency code
6707
+
6708
+ https://www.gate.io/docs/developers/apiv4/en/#query-account-book
6709
+ https://www.gate.io/docs/developers/apiv4/en/#list-margin-account-balance-change-history
6710
+ https://www.gate.io/docs/developers/apiv4/en/#query-account-book-2
6711
+ https://www.gate.io/docs/developers/apiv4/en/#query-account-book-3
6712
+ https://www.gate.io/docs/developers/apiv4/en/#list-account-changing-history
6713
+
6714
+ :param str [code]: unified currency code
5974
6715
  :param int [since]: timestamp in ms of the earliest ledger entry
5975
6716
  :param int [limit]: max number of ledger entries to return
5976
6717
  :param dict [params]: extra parameters specific to the exchange API endpoint
5977
6718
  :param int [params.until]: end time in ms
5978
- :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
5979
- :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
6719
+ :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)
6720
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
5980
6721
  """
5981
6722
  await self.load_markets()
5982
6723
  paginate = False
@@ -5986,12 +6727,12 @@ class gate(Exchange, ImplicitAPI):
5986
6727
  type = None
5987
6728
  currency = None
5988
6729
  response = None
5989
- request = {}
6730
+ request: dict = {}
5990
6731
  type, params = self.handle_market_type_and_params('fetchLedger', None, params)
5991
6732
  if (type == 'spot') or (type == 'margin'):
5992
6733
  if code is not None:
5993
6734
  currency = self.currency(code)
5994
- request['currency'] = currency['id']
6735
+ request['currency'] = currency['id'] # todo: currencies have network-junctions
5995
6736
  if (type == 'swap') or (type == 'future'):
5996
6737
  defaultSettle = 'usdt' if (type == 'swap') else 'btc'
5997
6738
  settle = self.safe_string_lower(params, 'settle', defaultSettle)
@@ -6066,7 +6807,7 @@ class gate(Exchange, ImplicitAPI):
6066
6807
  #
6067
6808
  return self.parse_ledger(response, currency, since, limit)
6068
6809
 
6069
- def parse_ledger_entry(self, item, currency: Currency = None):
6810
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
6070
6811
  #
6071
6812
  # spot
6072
6813
  #
@@ -6119,6 +6860,7 @@ class gate(Exchange, ImplicitAPI):
6119
6860
  else:
6120
6861
  direction = 'in'
6121
6862
  currencyId = self.safe_string(item, 'currency')
6863
+ currency = self.safe_currency(currencyId, currency)
6122
6864
  type = self.safe_string(item, 'type')
6123
6865
  rawTimestamp = self.safe_string(item, 'time')
6124
6866
  timestamp = None
@@ -6129,7 +6871,8 @@ class gate(Exchange, ImplicitAPI):
6129
6871
  balanceString = self.safe_string(item, 'balance')
6130
6872
  changeString = self.safe_string(item, 'change')
6131
6873
  before = self.parse_number(Precise.string_sub(balanceString, changeString))
6132
- return {
6874
+ return self.safe_ledger_entry({
6875
+ 'info': item,
6133
6876
  'id': self.safe_string(item, 'id'),
6134
6877
  'direction': direction,
6135
6878
  'account': None,
@@ -6144,11 +6887,10 @@ class gate(Exchange, ImplicitAPI):
6144
6887
  'after': self.safe_number(item, 'balance'),
6145
6888
  'status': None,
6146
6889
  'fee': None,
6147
- 'info': item,
6148
- }
6890
+ }, currency)
6149
6891
 
6150
6892
  def parse_ledger_entry_type(self, type):
6151
- ledgerType = {
6893
+ ledgerType: dict = {
6152
6894
  'deposit': 'deposit',
6153
6895
  'withdraw': 'withdrawal',
6154
6896
  'sub_account_transfer': 'transfer',
@@ -6193,7 +6935,9 @@ class gate(Exchange, ImplicitAPI):
6193
6935
  async def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
6194
6936
  """
6195
6937
  set dual/hedged mode to True or False for a swap market, make sure all positions are closed and no orders are open before setting dual mode
6196
- :see: https://www.gate.io/docs/developers/apiv4/en/#enable-or-disable-dual-mode
6938
+
6939
+ https://www.gate.io/docs/developers/apiv4/en/#enable-or-disable-dual-mode
6940
+
6197
6941
  :param bool hedged: set to True to enable dual mode
6198
6942
  :param str|None symbol: if passed, dual mode is set for all markets with the same settle currency
6199
6943
  :param dict params: extra parameters specific to the exchange API endpoint
@@ -6208,7 +6952,9 @@ class gate(Exchange, ImplicitAPI):
6208
6952
  async def fetch_underlying_assets(self, params={}):
6209
6953
  """
6210
6954
  fetches the market ids of underlying assets for a specific contract market type
6211
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-underlyings
6955
+
6956
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-underlyings
6957
+
6212
6958
  :param dict [params]: exchange specific params
6213
6959
  :param str [params.type]: the contract market type, 'option', 'swap' or 'future', the default is 'option'
6214
6960
  :returns dict[]: a list of `underlying assets <https://docs.ccxt.com/#/?id=underlying-assets-structure>`
@@ -6241,7 +6987,9 @@ class gate(Exchange, ImplicitAPI):
6241
6987
  async def fetch_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}):
6242
6988
  """
6243
6989
  retrieves the public liquidations of a trading pair
6244
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-liquidation-history
6990
+
6991
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-liquidation-history
6992
+
6245
6993
  :param str symbol: unified CCXT market symbol
6246
6994
  :param int [since]: the earliest time in ms to fetch liquidations for
6247
6995
  :param int [limit]: the maximum number of liquidation structures to retrieve
@@ -6253,7 +7001,7 @@ class gate(Exchange, ImplicitAPI):
6253
7001
  market = self.market(symbol)
6254
7002
  if not market['swap']:
6255
7003
  raise NotSupported(self.id + ' fetchLiquidations() supports swap markets only')
6256
- request = {
7004
+ request: dict = {
6257
7005
  'settle': market['settleId'],
6258
7006
  'contract': market['id'],
6259
7007
  }
@@ -6280,9 +7028,11 @@ class gate(Exchange, ImplicitAPI):
6280
7028
  async def fetch_my_liquidations(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6281
7029
  """
6282
7030
  retrieves the users liquidated positions
6283
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-liquidation-history
6284
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-liquidation-history-2
6285
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-user-s-liquidation-history-of-specified-underlying
7031
+
7032
+ https://www.gate.io/docs/developers/apiv4/en/#list-liquidation-history
7033
+ https://www.gate.io/docs/developers/apiv4/en/#list-liquidation-history-2
7034
+ https://www.gate.io/docs/developers/apiv4/en/#list-user-s-liquidation-history-of-specified-underlying
7035
+
6286
7036
  :param str symbol: unified CCXT market symbol
6287
7037
  :param int [since]: the earliest time in ms to fetch liquidations for
6288
7038
  :param int [limit]: the maximum number of liquidation structures to retrieve
@@ -6293,7 +7043,7 @@ class gate(Exchange, ImplicitAPI):
6293
7043
  raise ArgumentsRequired(self.id + ' fetchMyLiquidations() requires a symbol argument')
6294
7044
  await self.load_markets()
6295
7045
  market = self.market(symbol)
6296
- request = {
7046
+ request: dict = {
6297
7047
  'contract': market['id'],
6298
7048
  }
6299
7049
  response = None
@@ -6415,14 +7165,16 @@ class gate(Exchange, ImplicitAPI):
6415
7165
  async def fetch_greeks(self, symbol: str, params={}) -> Greeks:
6416
7166
  """
6417
7167
  fetches an option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract
6418
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-tickers-of-options-contracts
7168
+
7169
+ https://www.gate.io/docs/developers/apiv4/en/#list-tickers-of-options-contracts
7170
+
6419
7171
  :param str symbol: unified symbol of the market to fetch greeks for
6420
7172
  :param dict [params]: extra parameters specific to the exchange API endpoint
6421
7173
  :returns dict: a `greeks structure <https://docs.ccxt.com/#/?id=greeks-structure>`
6422
7174
  """
6423
7175
  await self.load_markets()
6424
7176
  market = self.market(symbol)
6425
- request = {
7177
+ request: dict = {
6426
7178
  'underlying': market['info']['underlying'],
6427
7179
  }
6428
7180
  response = await self.publicOptionsGetTickers(self.extend(request, params))
@@ -6456,7 +7208,7 @@ class gate(Exchange, ImplicitAPI):
6456
7208
  return self.parse_greeks(entry, market)
6457
7209
  return None
6458
7210
 
6459
- def parse_greeks(self, greeks, market: Market = None):
7211
+ def parse_greeks(self, greeks: dict, market: Market = None) -> Greeks:
6460
7212
  #
6461
7213
  # {
6462
7214
  # "vega": "1.78992",
@@ -6504,15 +7256,17 @@ class gate(Exchange, ImplicitAPI):
6504
7256
  async def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
6505
7257
  """
6506
7258
  closes open positions for a market
6507
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order
6508
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order-2
6509
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-an-options-order
7259
+
7260
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order
7261
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order-2
7262
+ https://www.gate.io/docs/developers/apiv4/en/#create-an-options-order
7263
+
6510
7264
  :param str symbol: Unified CCXT market symbol
6511
7265
  :param str side: 'buy' or 'sell'
6512
7266
  :param dict [params]: extra parameters specific to the okx api endpoint
6513
7267
  :returns dict[]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
6514
7268
  """
6515
- request = {
7269
+ request: dict = {
6516
7270
  'close': True,
6517
7271
  }
6518
7272
  params = self.extend(request, params)
@@ -6523,9 +7277,11 @@ class gate(Exchange, ImplicitAPI):
6523
7277
  async def fetch_leverage(self, symbol: str, params={}) -> Leverage:
6524
7278
  """
6525
7279
  fetch the set leverage for a market
6526
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-unified-account-information
6527
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-detail-of-lending-market
6528
- :see: https://www.gate.io/docs/developers/apiv4/en/#query-one-single-margin-currency-pair-deprecated
7280
+
7281
+ https://www.gate.io/docs/developers/apiv4/en/#get-unified-account-information
7282
+ https://www.gate.io/docs/developers/apiv4/en/#get-detail-of-lending-market
7283
+ https://www.gate.io/docs/developers/apiv4/en/#query-one-single-margin-currency-pair-deprecated
7284
+
6529
7285
  :param str symbol: unified market symbol
6530
7286
  :param dict [params]: extra parameters specific to the exchange API endpoint
6531
7287
  :param boolean [params.unified]: default False, set to True for fetching the unified accounts leverage
@@ -6536,7 +7292,7 @@ class gate(Exchange, ImplicitAPI):
6536
7292
  if symbol is not None:
6537
7293
  # unified account does not require a symbol
6538
7294
  market = self.market(symbol)
6539
- request = {}
7295
+ request: dict = {}
6540
7296
  response = None
6541
7297
  isUnified = self.safe_bool(params, 'unified')
6542
7298
  params = self.omit(params, 'unified')
@@ -6622,11 +7378,13 @@ class gate(Exchange, ImplicitAPI):
6622
7378
  raise NotSupported(self.id + ' fetchLeverage() does not support ' + market['type'] + ' markets')
6623
7379
  return self.parse_leverage(response, market)
6624
7380
 
6625
- async def fetch_leverages(self, symbols: List[str] = None, params={}) -> Leverages:
7381
+ async def fetch_leverages(self, symbols: Strings = None, params={}) -> Leverages:
6626
7382
  """
6627
7383
  fetch the set leverage for all leverage markets, only spot margin is supported on gate
6628
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-lending-markets
6629
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-supported-currency-pairs-supported-in-margin-trading-deprecated
7384
+
7385
+ https://www.gate.io/docs/developers/apiv4/en/#list-lending-markets
7386
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-supported-currency-pairs-supported-in-margin-trading-deprecated
7387
+
6630
7388
  :param str[] symbols: a list of unified market symbols
6631
7389
  :param dict [params]: extra parameters specific to the exchange API endpoint
6632
7390
  :param boolean [params.unified]: default False, set to True for fetching unified account leverages
@@ -6669,7 +7427,7 @@ class gate(Exchange, ImplicitAPI):
6669
7427
  #
6670
7428
  return self.parse_leverages(response, symbols, marketIdRequest, 'spot')
6671
7429
 
6672
- def parse_leverage(self, leverage, market=None) -> Leverage:
7430
+ def parse_leverage(self, leverage: dict, market: Market = None) -> Leverage:
6673
7431
  marketId = self.safe_string_2(leverage, 'currency_pair', 'id')
6674
7432
  leverageValue = self.safe_integer(leverage, 'leverage')
6675
7433
  return {
@@ -6680,7 +7438,257 @@ class gate(Exchange, ImplicitAPI):
6680
7438
  'shortLeverage': leverageValue,
6681
7439
  }
6682
7440
 
6683
- def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
7441
+ async def fetch_option(self, symbol: str, params={}) -> Option:
7442
+ """
7443
+ fetches option data that is commonly found in an option chain
7444
+
7445
+ https://www.gate.io/docs/developers/apiv4/en/#query-specified-contract-detail
7446
+
7447
+ :param str symbol: unified market symbol
7448
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7449
+ :returns dict: an `option chain structure <https://docs.ccxt.com/#/?id=option-chain-structure>`
7450
+ """
7451
+ await self.load_markets()
7452
+ market = self.market(symbol)
7453
+ request: dict = {
7454
+ 'contract': market['id'],
7455
+ }
7456
+ response = await self.publicOptionsGetContractsContract(self.extend(request, params))
7457
+ #
7458
+ # {
7459
+ # "is_active": True,
7460
+ # "mark_price_round": "0.01",
7461
+ # "settle_fee_rate": "0.00015",
7462
+ # "bid1_size": 30,
7463
+ # "taker_fee_rate": "0.0003",
7464
+ # "price_limit_fee_rate": "0.1",
7465
+ # "order_price_round": "0.1",
7466
+ # "tag": "month",
7467
+ # "ref_rebate_rate": "0",
7468
+ # "name": "ETH_USDT-20240628-4500-C",
7469
+ # "strike_price": "4500",
7470
+ # "ask1_price": "280.5",
7471
+ # "ref_discount_rate": "0",
7472
+ # "order_price_deviate": "0.2",
7473
+ # "ask1_size": -19,
7474
+ # "mark_price_down": "155.45",
7475
+ # "orderbook_id": 11724695,
7476
+ # "is_call": True,
7477
+ # "last_price": "188.7",
7478
+ # "mark_price": "274.26",
7479
+ # "underlying": "ETH_USDT",
7480
+ # "create_time": 1688024882,
7481
+ # "settle_limit_fee_rate": "0.1",
7482
+ # "orders_limit": 10,
7483
+ # "mark_price_up": "403.83",
7484
+ # "position_size": 80,
7485
+ # "order_size_max": 10000,
7486
+ # "position_limit": 100000,
7487
+ # "multiplier": "0.01",
7488
+ # "order_size_min": 1,
7489
+ # "trade_size": 229,
7490
+ # "underlying_price": "3326.6",
7491
+ # "maker_fee_rate": "0.0003",
7492
+ # "expiration_time": 1719561600,
7493
+ # "trade_id": 15,
7494
+ # "bid1_price": "269.3"
7495
+ # }
7496
+ #
7497
+ return self.parse_option(response, None, market)
7498
+
7499
+ async def fetch_option_chain(self, code: str, params={}) -> OptionChain:
7500
+ """
7501
+ fetches data for an underlying asset that is commonly found in an option chain
7502
+
7503
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-the-contracts-with-specified-underlying-and-expiration-time
7504
+
7505
+ :param str code: base currency to fetch an option chain for
7506
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7507
+ :param str [params.underlying]: the underlying asset, can be obtained from fetchUnderlyingAssets()
7508
+ :param int [params.expiration]: unix timestamp of the expiration time
7509
+ :returns dict: a list of `option chain structures <https://docs.ccxt.com/#/?id=option-chain-structure>`
7510
+ """
7511
+ await self.load_markets()
7512
+ currency = self.currency(code)
7513
+ request: dict = {
7514
+ 'underlying': currency['code'] + '_USDT', # todo: currency['id'].upper() & network junctions
7515
+ }
7516
+ response = await self.publicOptionsGetContracts(self.extend(request, params))
7517
+ #
7518
+ # [
7519
+ # {
7520
+ # "is_active": True,
7521
+ # "mark_price_round": "0.1",
7522
+ # "settle_fee_rate": "0.00015",
7523
+ # "bid1_size": 434,
7524
+ # "taker_fee_rate": "0.0003",
7525
+ # "price_limit_fee_rate": "0.1",
7526
+ # "order_price_round": "1",
7527
+ # "tag": "day",
7528
+ # "ref_rebate_rate": "0",
7529
+ # "name": "BTC_USDT-20240324-63500-P",
7530
+ # "strike_price": "63500",
7531
+ # "ask1_price": "387",
7532
+ # "ref_discount_rate": "0",
7533
+ # "order_price_deviate": "0.15",
7534
+ # "ask1_size": -454,
7535
+ # "mark_price_down": "124.3",
7536
+ # "orderbook_id": 29600,
7537
+ # "is_call": False,
7538
+ # "last_price": "0",
7539
+ # "mark_price": "366.6",
7540
+ # "underlying": "BTC_USDT",
7541
+ # "create_time": 1711118829,
7542
+ # "settle_limit_fee_rate": "0.1",
7543
+ # "orders_limit": 10,
7544
+ # "mark_price_up": "630",
7545
+ # "position_size": 0,
7546
+ # "order_size_max": 10000,
7547
+ # "position_limit": 10000,
7548
+ # "multiplier": "0.01",
7549
+ # "order_size_min": 1,
7550
+ # "trade_size": 0,
7551
+ # "underlying_price": "64084.65",
7552
+ # "maker_fee_rate": "0.0003",
7553
+ # "expiration_time": 1711267200,
7554
+ # "trade_id": 0,
7555
+ # "bid1_price": "307"
7556
+ # },
7557
+ # ]
7558
+ #
7559
+ return self.parse_option_chain(response, None, 'name')
7560
+
7561
+ def parse_option(self, chain: dict, currency: Currency = None, market: Market = None) -> Option:
7562
+ #
7563
+ # {
7564
+ # "is_active": True,
7565
+ # "mark_price_round": "0.1",
7566
+ # "settle_fee_rate": "0.00015",
7567
+ # "bid1_size": 434,
7568
+ # "taker_fee_rate": "0.0003",
7569
+ # "price_limit_fee_rate": "0.1",
7570
+ # "order_price_round": "1",
7571
+ # "tag": "day",
7572
+ # "ref_rebate_rate": "0",
7573
+ # "name": "BTC_USDT-20240324-63500-P",
7574
+ # "strike_price": "63500",
7575
+ # "ask1_price": "387",
7576
+ # "ref_discount_rate": "0",
7577
+ # "order_price_deviate": "0.15",
7578
+ # "ask1_size": -454,
7579
+ # "mark_price_down": "124.3",
7580
+ # "orderbook_id": 29600,
7581
+ # "is_call": False,
7582
+ # "last_price": "0",
7583
+ # "mark_price": "366.6",
7584
+ # "underlying": "BTC_USDT",
7585
+ # "create_time": 1711118829,
7586
+ # "settle_limit_fee_rate": "0.1",
7587
+ # "orders_limit": 10,
7588
+ # "mark_price_up": "630",
7589
+ # "position_size": 0,
7590
+ # "order_size_max": 10000,
7591
+ # "position_limit": 10000,
7592
+ # "multiplier": "0.01",
7593
+ # "order_size_min": 1,
7594
+ # "trade_size": 0,
7595
+ # "underlying_price": "64084.65",
7596
+ # "maker_fee_rate": "0.0003",
7597
+ # "expiration_time": 1711267200,
7598
+ # "trade_id": 0,
7599
+ # "bid1_price": "307"
7600
+ # }
7601
+ #
7602
+ marketId = self.safe_string(chain, 'name')
7603
+ market = self.safe_market(marketId, market)
7604
+ timestamp = self.safe_timestamp(chain, 'create_time')
7605
+ return {
7606
+ 'info': chain,
7607
+ 'currency': None,
7608
+ 'symbol': market['symbol'],
7609
+ 'timestamp': timestamp,
7610
+ 'datetime': self.iso8601(timestamp),
7611
+ 'impliedVolatility': None,
7612
+ 'openInterest': None,
7613
+ 'bidPrice': self.safe_number(chain, 'bid1_price'),
7614
+ 'askPrice': self.safe_number(chain, 'ask1_price'),
7615
+ 'midPrice': None,
7616
+ 'markPrice': self.safe_number(chain, 'mark_price'),
7617
+ 'lastPrice': self.safe_number(chain, 'last_price'),
7618
+ 'underlyingPrice': self.safe_number(chain, 'underlying_price'),
7619
+ 'change': None,
7620
+ 'percentage': None,
7621
+ 'baseVolume': None,
7622
+ 'quoteVolume': None,
7623
+ }
7624
+
7625
+ async def fetch_positions_history(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
7626
+ """
7627
+ fetches historical positions
7628
+
7629
+ https://www.gate.io/docs/developers/apiv4/#list-position-close-history
7630
+ https://www.gate.io/docs/developers/apiv4/#list-position-close-history-2
7631
+
7632
+ :param str[] symbols: unified conract symbols, must all have the same settle currency and the same market type
7633
+ :param int [since]: the earliest time in ms to fetch positions for
7634
+ :param int [limit]: the maximum amount of records to fetch, default=1000
7635
+ :param dict params: extra parameters specific to the exchange api endpoint
7636
+ :param int [params.until]: the latest time in ms to fetch positions for
7637
+
7638
+ EXCHANGE SPECIFIC PARAMETERS
7639
+ :param int [params.offset]: list offset, starting from 0
7640
+ :param str [params.side]: long or short
7641
+ :param str [params.pnl]: query profit or loss
7642
+ :returns dict[]: a list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
7643
+ """
7644
+ await self.load_markets()
7645
+ market = None
7646
+ if symbols is not None:
7647
+ symbolsLength = len(symbols)
7648
+ if symbolsLength == 1:
7649
+ market = self.market(symbols[0])
7650
+ marketType = None
7651
+ marketType, params = self.handle_market_type_and_params('fetchPositionsHistory', market, params, 'swap')
7652
+ until = self.safe_integer(params, 'until')
7653
+ params = self.omit(params, 'until')
7654
+ request: dict = {}
7655
+ request, params = self.prepare_request(market, marketType, params)
7656
+ if limit is not None:
7657
+ request['limit'] = limit
7658
+ if since is not None:
7659
+ request['from'] = self.parse_to_int(since / 1000)
7660
+ if until is not None:
7661
+ request['to'] = self.parse_to_int(until / 1000)
7662
+ response = None
7663
+ if marketType == 'swap':
7664
+ response = await self.privateFuturesGetSettlePositionClose(self.extend(request, params))
7665
+ elif marketType == 'future':
7666
+ response = await self.privateDeliveryGetSettlePositionClose(self.extend(request, params))
7667
+ else:
7668
+ raise NotSupported(self.id + ' fetchPositionsHistory() does not support markets of type ' + marketType)
7669
+ #
7670
+ # [
7671
+ # {
7672
+ # "contract": "SLERF_USDT",
7673
+ # "text": "web",
7674
+ # "long_price": "0.766306",
7675
+ # "pnl": "-23.41702352",
7676
+ # "pnl_pnl": "-22.7187",
7677
+ # "pnl_fee": "-0.06527125",
7678
+ # "pnl_fund": "-0.63305227",
7679
+ # "accum_size": "100",
7680
+ # "time": 1711279263,
7681
+ # "short_price": "0.539119",
7682
+ # "side": "long",
7683
+ # "max_size": "100",
7684
+ # "first_open_time": 1711037985
7685
+ # },
7686
+ # ...
7687
+ # ]
7688
+ #
7689
+ return self.parse_positions(response, symbols, params)
7690
+
7691
+ def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
6684
7692
  if response is None:
6685
7693
  return None
6686
7694
  #
@@ -6689,6 +7697,7 @@ class gate(Exchange, ImplicitAPI):
6689
7697
  # {"label": "INVALID_PARAM_VALUE", "message": "invalid argument: Trigger.rule"}
6690
7698
  # {"label": "INVALID_PARAM_VALUE", "message": "invalid argument: trigger.expiration invalid range"}
6691
7699
  # {"label": "INVALID_ARGUMENT", "detail": "invalid size"}
7700
+ # {"user_id":10406147,"id":"id","succeeded":false,"message":"INVALID_PROTOCOL","label":"INVALID_PROTOCOL"}
6692
7701
  #
6693
7702
  label = self.safe_string(response, 'label')
6694
7703
  if label is not None: