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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (528) hide show
  1. ccxt/__init__.py +39 -35
  2. ccxt/abantether.py +9 -9
  3. ccxt/abstract/alpaca.py +4 -0
  4. ccxt/abstract/apex.py +31 -0
  5. ccxt/abstract/bigone.py +1 -1
  6. ccxt/abstract/binance.py +106 -48
  7. ccxt/abstract/binancecoinm.py +106 -48
  8. ccxt/abstract/binanceus.py +141 -83
  9. ccxt/abstract/binanceusdm.py +106 -48
  10. ccxt/abstract/bingx.py +50 -1
  11. ccxt/abstract/bitbank.py +5 -0
  12. ccxt/abstract/bitfinex.py +136 -65
  13. ccxt/abstract/bitflyer.py +1 -0
  14. ccxt/abstract/bitget.py +67 -0
  15. ccxt/abstract/bitmart.py +19 -1
  16. ccxt/abstract/bitopro.py +1 -0
  17. ccxt/abstract/bitrue.py +68 -68
  18. ccxt/abstract/bitstamp.py +1 -0
  19. ccxt/abstract/blofin.py +30 -0
  20. ccxt/abstract/btcbox.py +2 -0
  21. ccxt/abstract/bybit.py +28 -13
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbaseexchange.py +1 -0
  24. ccxt/abstract/coinbaseinternational.py +1 -1
  25. ccxt/abstract/cryptocom.py +16 -0
  26. ccxt/abstract/cryptomus.py +20 -0
  27. ccxt/abstract/defx.py +69 -0
  28. ccxt/abstract/deribit.py +1 -0
  29. ccxt/abstract/derive.py +117 -0
  30. ccxt/abstract/digifinex.py +1 -0
  31. ccxt/abstract/ellipx.py +25 -0
  32. ccxt/abstract/foxbit.py +26 -0
  33. ccxt/abstract/gate.py +19 -0
  34. ccxt/abstract/gateio.py +19 -0
  35. ccxt/abstract/gemini.py +1 -0
  36. ccxt/abstract/hibachi.py +26 -0
  37. ccxt/abstract/hyperliquid.py +1 -1
  38. ccxt/abstract/independentreserve.py +6 -0
  39. ccxt/abstract/kraken.py +1 -0
  40. ccxt/abstract/krakenfutures.py +4 -0
  41. ccxt/abstract/kucoin.py +10 -0
  42. ccxt/abstract/kucoinfutures.py +18 -0
  43. ccxt/abstract/lbank.py +2 -1
  44. ccxt/abstract/luno.py +1 -0
  45. ccxt/abstract/mexc.py +2 -0
  46. ccxt/abstract/modetrade.py +119 -0
  47. ccxt/abstract/myokx.py +349 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +25 -0
  50. ccxt/abstract/okxus.py +349 -0
  51. ccxt/abstract/onetrading.py +0 -12
  52. ccxt/abstract/paradex.py +23 -0
  53. ccxt/abstract/phemex.py +2 -0
  54. ccxt/abstract/poloniex.py +36 -0
  55. ccxt/abstract/tradeogre.py +3 -1
  56. ccxt/abstract/upbit.py +51 -34
  57. ccxt/abstract/whitebit.py +16 -0
  58. ccxt/abstract/woo.py +64 -6
  59. ccxt/abstract/xt.py +10 -5
  60. ccxt/afratether.py +7 -7
  61. ccxt/alpaca.py +828 -51
  62. ccxt/apex.py +1875 -0
  63. ccxt/arzinja.py +7 -7
  64. ccxt/arzplus.py +9 -9
  65. ccxt/ascendex.py +501 -306
  66. ccxt/async_support/__init__.py +39 -35
  67. ccxt/async_support/abantether.py +10 -10
  68. ccxt/async_support/afratether.py +9 -9
  69. ccxt/async_support/alpaca.py +828 -51
  70. ccxt/async_support/apex.py +1875 -0
  71. ccxt/async_support/arzinja.py +10 -10
  72. ccxt/async_support/arzplus.py +12 -12
  73. ccxt/async_support/ascendex.py +502 -306
  74. ccxt/async_support/base/exchange.py +303 -89
  75. ccxt/async_support/base/ws/cache.py +9 -3
  76. ccxt/async_support/base/ws/client.py +173 -38
  77. ccxt/async_support/base/ws/future.py +25 -37
  78. ccxt/async_support/bequant.py +5 -3
  79. ccxt/async_support/bigone.py +279 -144
  80. ccxt/async_support/binance.py +2347 -1158
  81. ccxt/async_support/binancecoinm.py +9 -3
  82. ccxt/async_support/binanceus.py +17 -3
  83. ccxt/async_support/binanceusdm.py +9 -4
  84. ccxt/async_support/bingx.py +2962 -920
  85. ccxt/async_support/bit2c.py +147 -27
  86. ccxt/async_support/bitbank.py +151 -23
  87. ccxt/async_support/bitbns.py +104 -30
  88. ccxt/async_support/bitfinex.py +3291 -1113
  89. ccxt/async_support/bitflyer.py +202 -27
  90. ccxt/async_support/bitget.py +3683 -1538
  91. ccxt/async_support/bithumb.py +195 -38
  92. ccxt/async_support/bitimen.py +12 -12
  93. ccxt/async_support/bitir.py +38 -38
  94. ccxt/async_support/bitmart.py +1288 -350
  95. ccxt/async_support/bitmex.py +260 -75
  96. ccxt/async_support/bitopro.py +262 -62
  97. ccxt/async_support/bitpin.py +17 -16
  98. ccxt/async_support/bitrue.py +459 -290
  99. ccxt/async_support/bitso.py +199 -54
  100. ccxt/async_support/bitstamp.py +230 -96
  101. ccxt/async_support/bitteam.py +167 -25
  102. ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
  103. ccxt/async_support/bitvavo.py +213 -49
  104. ccxt/async_support/blockchaincom.py +160 -46
  105. ccxt/async_support/blofin.py +502 -120
  106. ccxt/async_support/btcalpha.py +169 -31
  107. ccxt/async_support/btcbox.py +292 -23
  108. ccxt/async_support/btcmarkets.py +211 -58
  109. ccxt/async_support/btcturk.py +161 -38
  110. ccxt/async_support/bybit.py +1775 -1030
  111. ccxt/async_support/cex.py +1440 -1303
  112. ccxt/async_support/coinbase.py +724 -212
  113. ccxt/async_support/coinbaseadvanced.py +2 -1
  114. ccxt/async_support/coinbaseexchange.py +388 -89
  115. ccxt/async_support/coinbaseinternational.py +412 -57
  116. ccxt/async_support/coincatch.py +177 -78
  117. ccxt/async_support/coincheck.py +135 -19
  118. ccxt/async_support/coinex.py +606 -232
  119. ccxt/async_support/coinmate.py +189 -63
  120. ccxt/async_support/coinmetro.py +195 -54
  121. ccxt/async_support/coinone.py +158 -51
  122. ccxt/async_support/coinsph.py +336 -61
  123. ccxt/async_support/coinspot.py +151 -52
  124. ccxt/async_support/cryptocom.py +661 -111
  125. ccxt/async_support/cryptomus.py +1137 -0
  126. ccxt/async_support/defx.py +2071 -0
  127. ccxt/async_support/delta.py +299 -99
  128. ccxt/async_support/deribit.py +348 -126
  129. ccxt/async_support/derive.py +2572 -0
  130. ccxt/async_support/digifinex.py +430 -214
  131. ccxt/async_support/ellipx.py +2029 -0
  132. ccxt/async_support/eterex.py +10 -10
  133. ccxt/async_support/excoino.py +31 -31
  134. ccxt/async_support/exir.py +14 -14
  135. ccxt/async_support/exmo.py +344 -131
  136. ccxt/async_support/exnovin.py +10 -10
  137. ccxt/async_support/farhadexchange.py +12 -12
  138. ccxt/async_support/fmfwio.py +2 -1
  139. ccxt/async_support/foxbit.py +1935 -0
  140. ccxt/async_support/gate.py +1351 -529
  141. ccxt/async_support/gateio.py +2 -1
  142. ccxt/async_support/gemini.py +144 -39
  143. ccxt/async_support/hashkey.py +152 -109
  144. ccxt/async_support/hibachi.py +2080 -0
  145. ccxt/async_support/hitbtc.py +395 -167
  146. ccxt/async_support/hitobit.py +12 -12
  147. ccxt/async_support/hollaex.py +307 -119
  148. ccxt/async_support/htx.py +851 -383
  149. ccxt/async_support/huobi.py +2 -1
  150. ccxt/async_support/hyperliquid.py +1848 -536
  151. ccxt/async_support/independentreserve.py +288 -15
  152. ccxt/async_support/indodax.py +190 -33
  153. ccxt/async_support/jibitex.py +12 -12
  154. ccxt/async_support/kraken.py +795 -351
  155. ccxt/async_support/krakenfutures.py +214 -62
  156. ccxt/async_support/kucoin.py +715 -396
  157. ccxt/async_support/kucoinfutures.py +652 -89
  158. ccxt/async_support/latoken.py +217 -113
  159. ccxt/async_support/lbank.py +425 -97
  160. ccxt/async_support/luno.py +382 -35
  161. ccxt/async_support/mercado.py +113 -6
  162. ccxt/async_support/mexc.py +874 -437
  163. ccxt/async_support/modetrade.py +2818 -0
  164. ccxt/async_support/myokx.py +54 -0
  165. ccxt/async_support/ndax.py +221 -64
  166. ccxt/async_support/nobitex.py +31 -37
  167. ccxt/async_support/novadax.py +190 -34
  168. ccxt/async_support/oceanex.py +217 -28
  169. ccxt/async_support/okcoin.py +253 -145
  170. ccxt/async_support/okexchange.py +11 -11
  171. ccxt/async_support/okx.py +1088 -351
  172. ccxt/async_support/okxus.py +54 -0
  173. ccxt/async_support/ompfinex.py +25 -24
  174. ccxt/async_support/onetrading.py +213 -392
  175. ccxt/async_support/oxfun.py +245 -166
  176. ccxt/async_support/p2b.py +151 -29
  177. ccxt/async_support/paradex.py +562 -49
  178. ccxt/async_support/paymium.py +82 -19
  179. ccxt/async_support/phemex.py +713 -172
  180. ccxt/async_support/poloniex.py +1602 -283
  181. ccxt/async_support/probit.py +224 -95
  182. ccxt/async_support/ramzinex.py +30 -27
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +14 -13
  186. ccxt/async_support/tetherland.py +9 -9
  187. ccxt/async_support/timex.py +210 -51
  188. ccxt/async_support/tokocrypto.py +167 -47
  189. ccxt/async_support/tradeogre.py +266 -31
  190. ccxt/async_support/twox.py +9 -9
  191. ccxt/async_support/ubitex.py +12 -12
  192. ccxt/async_support/upbit.py +568 -165
  193. ccxt/async_support/vertex.py +160 -32
  194. ccxt/async_support/wallex.py +12 -12
  195. ccxt/async_support/wavesexchange.py +165 -30
  196. ccxt/async_support/whitebit.py +975 -127
  197. ccxt/async_support/woo.py +1918 -1016
  198. ccxt/async_support/woofipro.py +433 -141
  199. ccxt/async_support/xt.py +649 -193
  200. ccxt/async_support/yobit.py +195 -70
  201. ccxt/async_support/zaif.py +91 -15
  202. ccxt/async_support/zonda.py +151 -36
  203. ccxt/base/decimal_to_precision.py +14 -10
  204. ccxt/base/errors.py +49 -18
  205. ccxt/base/exchange.py +1556 -450
  206. ccxt/base/precise.py +10 -0
  207. ccxt/base/types.py +114 -6
  208. ccxt/bequant.py +5 -3
  209. ccxt/bigone.py +279 -144
  210. ccxt/binance.py +2347 -1158
  211. ccxt/binancecoinm.py +9 -3
  212. ccxt/binanceus.py +17 -3
  213. ccxt/binanceusdm.py +9 -4
  214. ccxt/bingx.py +2962 -920
  215. ccxt/bit2c.py +147 -27
  216. ccxt/bitbank.py +151 -23
  217. ccxt/bitbns.py +104 -30
  218. ccxt/bitfinex.py +3290 -1113
  219. ccxt/bitflyer.py +202 -27
  220. ccxt/bitget.py +3683 -1538
  221. ccxt/bithumb.py +194 -38
  222. ccxt/bitimen.py +9 -9
  223. ccxt/bitir.py +35 -35
  224. ccxt/bitmart.py +1288 -350
  225. ccxt/bitmex.py +260 -75
  226. ccxt/bitopro.py +262 -62
  227. ccxt/bitpin.py +15 -14
  228. ccxt/bitrue.py +459 -290
  229. ccxt/bitso.py +199 -54
  230. ccxt/bitstamp.py +230 -96
  231. ccxt/bitteam.py +167 -25
  232. ccxt/{huobijp.py → bittrade.py} +158 -30
  233. ccxt/bitvavo.py +213 -49
  234. ccxt/blockchaincom.py +160 -46
  235. ccxt/blofin.py +502 -120
  236. ccxt/btcalpha.py +169 -31
  237. ccxt/btcbox.py +291 -23
  238. ccxt/btcmarkets.py +211 -58
  239. ccxt/btcturk.py +161 -38
  240. ccxt/bybit.py +1775 -1030
  241. ccxt/cex.py +1439 -1303
  242. ccxt/coinbase.py +724 -212
  243. ccxt/coinbaseadvanced.py +2 -1
  244. ccxt/coinbaseexchange.py +388 -89
  245. ccxt/coinbaseinternational.py +412 -57
  246. ccxt/coincatch.py +177 -78
  247. ccxt/coincheck.py +135 -19
  248. ccxt/coinex.py +606 -232
  249. ccxt/coinmate.py +189 -63
  250. ccxt/coinmetro.py +194 -54
  251. ccxt/coinone.py +158 -51
  252. ccxt/coinsph.py +336 -61
  253. ccxt/coinspot.py +151 -52
  254. ccxt/cryptocom.py +661 -111
  255. ccxt/cryptomus.py +1137 -0
  256. ccxt/defx.py +2070 -0
  257. ccxt/delta.py +299 -99
  258. ccxt/deribit.py +348 -126
  259. ccxt/derive.py +2571 -0
  260. ccxt/digifinex.py +430 -214
  261. ccxt/ellipx.py +2029 -0
  262. ccxt/eterex.py +7 -7
  263. ccxt/excoino.py +29 -29
  264. ccxt/exir.py +11 -11
  265. ccxt/exmo.py +343 -131
  266. ccxt/exnovin.py +8 -8
  267. ccxt/farhadexchange.py +10 -10
  268. ccxt/fmfwio.py +2 -1
  269. ccxt/foxbit.py +1935 -0
  270. ccxt/gate.py +1351 -529
  271. ccxt/gateio.py +2 -1
  272. ccxt/gemini.py +144 -39
  273. ccxt/hashkey.py +152 -109
  274. ccxt/hibachi.py +2079 -0
  275. ccxt/hitbtc.py +395 -167
  276. ccxt/hitobit.py +9 -9
  277. ccxt/hollaex.py +307 -119
  278. ccxt/htx.py +851 -383
  279. ccxt/huobi.py +2 -1
  280. ccxt/hyperliquid.py +1848 -536
  281. ccxt/independentreserve.py +287 -15
  282. ccxt/indodax.py +190 -33
  283. ccxt/jibitex.py +9 -9
  284. ccxt/kraken.py +794 -351
  285. ccxt/krakenfutures.py +214 -62
  286. ccxt/kucoin.py +715 -396
  287. ccxt/kucoinfutures.py +652 -89
  288. ccxt/latoken.py +217 -113
  289. ccxt/lbank.py +425 -97
  290. ccxt/luno.py +382 -35
  291. ccxt/mercado.py +113 -6
  292. ccxt/mexc.py +873 -437
  293. ccxt/modetrade.py +2818 -0
  294. ccxt/myokx.py +54 -0
  295. ccxt/ndax.py +221 -64
  296. ccxt/nobitex.py +29 -35
  297. ccxt/novadax.py +190 -34
  298. ccxt/oceanex.py +217 -28
  299. ccxt/okcoin.py +253 -145
  300. ccxt/okexchange.py +9 -9
  301. ccxt/okx.py +1088 -351
  302. ccxt/okxus.py +54 -0
  303. ccxt/ompfinex.py +22 -21
  304. ccxt/onetrading.py +213 -392
  305. ccxt/oxfun.py +245 -166
  306. ccxt/p2b.py +151 -29
  307. ccxt/paradex.py +562 -49
  308. ccxt/paymium.py +82 -19
  309. ccxt/phemex.py +712 -172
  310. ccxt/poloniex.py +1601 -283
  311. ccxt/pro/__init__.py +76 -17
  312. ccxt/pro/alpaca.py +21 -6
  313. ccxt/pro/apex.py +984 -0
  314. ccxt/pro/ascendex.py +58 -10
  315. ccxt/pro/bequant.py +6 -1
  316. ccxt/pro/binance.py +728 -156
  317. ccxt/pro/binancecoinm.py +6 -2
  318. ccxt/pro/binanceus.py +8 -4
  319. ccxt/pro/binanceusdm.py +7 -2
  320. ccxt/pro/bingx.py +333 -142
  321. ccxt/pro/bitfinex.py +727 -262
  322. ccxt/pro/bitget.py +570 -79
  323. ccxt/pro/bithumb.py +20 -6
  324. ccxt/pro/bitmart.py +216 -87
  325. ccxt/pro/bitmex.py +47 -9
  326. ccxt/pro/bitopro.py +26 -14
  327. ccxt/pro/bitrue.py +22 -22
  328. ccxt/pro/bitstamp.py +54 -21
  329. ccxt/pro/{huobijp.py → bittrade.py} +7 -6
  330. ccxt/pro/bitvavo.py +191 -67
  331. ccxt/pro/blockchaincom.py +21 -8
  332. ccxt/pro/blofin.py +9 -1
  333. ccxt/pro/bybit.py +632 -245
  334. ccxt/pro/cex.py +59 -24
  335. ccxt/pro/coinbase.py +102 -73
  336. ccxt/pro/coinbaseadvanced.py +2 -1
  337. ccxt/pro/coinbaseexchange.py +8 -8
  338. ccxt/pro/coinbaseinternational.py +181 -25
  339. ccxt/pro/coincatch.py +6 -7
  340. ccxt/pro/coincheck.py +11 -6
  341. ccxt/pro/coinex.py +967 -665
  342. ccxt/pro/coinone.py +16 -9
  343. ccxt/pro/cryptocom.py +448 -45
  344. ccxt/pro/defx.py +831 -0
  345. ccxt/pro/deribit.py +150 -14
  346. ccxt/pro/derive.py +704 -0
  347. ccxt/pro/exmo.py +239 -6
  348. ccxt/pro/gate.py +623 -65
  349. ccxt/pro/gateio.py +2 -1
  350. ccxt/pro/gemini.py +27 -11
  351. ccxt/pro/hashkey.py +2 -2
  352. ccxt/pro/hitbtc.py +196 -91
  353. ccxt/pro/hollaex.py +23 -7
  354. ccxt/pro/htx.py +51 -14
  355. ccxt/pro/huobi.py +2 -1
  356. ccxt/pro/hyperliquid.py +591 -27
  357. ccxt/pro/independentreserve.py +9 -6
  358. ccxt/pro/kraken.py +640 -320
  359. ccxt/pro/krakenfutures.py +62 -35
  360. ccxt/pro/kucoin.py +267 -46
  361. ccxt/pro/kucoinfutures.py +165 -21
  362. ccxt/pro/lbank.py +102 -21
  363. ccxt/pro/luno.py +12 -8
  364. ccxt/pro/mexc.py +877 -111
  365. ccxt/pro/modetrade.py +1271 -0
  366. ccxt/pro/myokx.py +38 -0
  367. ccxt/pro/ndax.py +15 -2
  368. ccxt/pro/okcoin.py +23 -4
  369. ccxt/pro/okx.py +573 -98
  370. ccxt/pro/okxus.py +38 -0
  371. ccxt/pro/onetrading.py +30 -13
  372. ccxt/pro/oxfun.py +131 -27
  373. ccxt/pro/p2b.py +88 -22
  374. ccxt/pro/paradex.py +3 -3
  375. ccxt/pro/phemex.py +75 -21
  376. ccxt/pro/poloniex.py +124 -41
  377. ccxt/pro/probit.py +87 -80
  378. ccxt/pro/tradeogre.py +272 -0
  379. ccxt/pro/upbit.py +152 -12
  380. ccxt/pro/vertex.py +8 -3
  381. ccxt/pro/whitebit.py +58 -5
  382. ccxt/pro/woo.py +228 -37
  383. ccxt/pro/woofipro.py +106 -18
  384. ccxt/pro/xt.py +111 -5
  385. ccxt/probit.py +224 -95
  386. ccxt/protobuf/__init__.py +0 -0
  387. ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
  388. ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
  389. ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
  390. ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
  391. ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
  392. ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
  393. ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
  394. ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
  395. ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
  396. ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
  397. ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
  398. ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
  399. ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
  400. ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
  401. ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
  402. ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
  403. ccxt/protobuf/mexc/__init__.py +0 -0
  404. ccxt/ramzinex.py +28 -25
  405. ccxt/sarmayex.py +7 -7
  406. ccxt/sarrafex.py +10 -10
  407. ccxt/static_dependencies/__init__.py +1 -1
  408. ccxt/static_dependencies/lark/py.typed +0 -0
  409. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  410. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  411. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  412. ccxt/tabdeal.py +12 -11
  413. ccxt/test/tests_async.py +261 -57
  414. ccxt/test/tests_helpers.py +1 -3
  415. ccxt/test/tests_init.py +4 -3
  416. ccxt/test/tests_sync.py +261 -57
  417. ccxt/tetherland.py +7 -7
  418. ccxt/timex.py +210 -51
  419. ccxt/tokocrypto.py +167 -47
  420. ccxt/tradeogre.py +266 -31
  421. ccxt/twox.py +7 -7
  422. ccxt/ubitex.py +9 -9
  423. ccxt/upbit.py +568 -165
  424. ccxt/vertex.py +160 -32
  425. ccxt/wallex.py +9 -9
  426. ccxt/wavesexchange.py +165 -30
  427. ccxt/whitebit.py +975 -127
  428. ccxt/woo.py +1917 -1016
  429. ccxt/woofipro.py +432 -141
  430. ccxt/xt.py +649 -193
  431. ccxt/yobit.py +194 -70
  432. ccxt/zaif.py +91 -15
  433. ccxt/zonda.py +151 -36
  434. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.0.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/WHEEL +1 -1
  437. ccxt/abstract/ace.py +0 -15
  438. ccxt/abstract/bitbay.py +0 -53
  439. ccxt/abstract/bitcoincom.py +0 -115
  440. ccxt/abstract/bitfinex2.py +0 -139
  441. ccxt/abstract/bitpanda.py +0 -35
  442. ccxt/abstract/bl3p.py +0 -19
  443. ccxt/abstract/coinlist.py +0 -54
  444. ccxt/abstract/currencycom.py +0 -68
  445. ccxt/abstract/hitbtc3.py +0 -115
  446. ccxt/abstract/idex.py +0 -26
  447. ccxt/abstract/kuna.py +0 -182
  448. ccxt/abstract/lykke.py +0 -29
  449. ccxt/abstract/poloniexfutures.py +0 -48
  450. ccxt/abstract/wazirx.py +0 -30
  451. ccxt/ace.py +0 -1012
  452. ccxt/async_support/ace.py +0 -1012
  453. ccxt/async_support/base/ws/aiohttp_client.py +0 -125
  454. ccxt/async_support/base/ws/fast_client.py +0 -96
  455. ccxt/async_support/bitbay.py +0 -17
  456. ccxt/async_support/bitcoincom.py +0 -17
  457. ccxt/async_support/bitfinex2.py +0 -3552
  458. ccxt/async_support/bitpanda.py +0 -16
  459. ccxt/async_support/bl3p.py +0 -485
  460. ccxt/async_support/coinlist.py +0 -2243
  461. ccxt/async_support/currencycom.py +0 -1950
  462. ccxt/async_support/hitbtc3.py +0 -16
  463. ccxt/async_support/idex.py +0 -1766
  464. ccxt/async_support/kuna.py +0 -1841
  465. ccxt/async_support/lykke.py +0 -1270
  466. ccxt/async_support/poloniexfutures.py +0 -1717
  467. ccxt/async_support/wazirx.py +0 -1224
  468. ccxt/bitbay.py +0 -17
  469. ccxt/bitcoincom.py +0 -17
  470. ccxt/bitfinex2.py +0 -3552
  471. ccxt/bitpanda.py +0 -16
  472. ccxt/bl3p.py +0 -485
  473. ccxt/coinlist.py +0 -2243
  474. ccxt/currencycom.py +0 -1950
  475. ccxt/hitbtc3.py +0 -16
  476. ccxt/idex.py +0 -1766
  477. ccxt/kuna.py +0 -1841
  478. ccxt/lykke.py +0 -1270
  479. ccxt/poloniexfutures.py +0 -1717
  480. ccxt/pro/bitcoincom.py +0 -34
  481. ccxt/pro/bitfinex2.py +0 -1083
  482. ccxt/pro/bitpanda.py +0 -15
  483. ccxt/pro/currencycom.py +0 -536
  484. ccxt/pro/idex.py +0 -672
  485. ccxt/pro/poloniexfutures.py +0 -990
  486. ccxt/pro/wazirx.py +0 -749
  487. ccxt/test/base/__init__.py +0 -29
  488. ccxt/test/base/test_account.py +0 -26
  489. ccxt/test/base/test_balance.py +0 -56
  490. ccxt/test/base/test_borrow_interest.py +0 -35
  491. ccxt/test/base/test_borrow_rate.py +0 -32
  492. ccxt/test/base/test_calculate_fee.py +0 -51
  493. ccxt/test/base/test_crypto.py +0 -127
  494. ccxt/test/base/test_currency.py +0 -76
  495. ccxt/test/base/test_datetime.py +0 -109
  496. ccxt/test/base/test_decimal_to_precision.py +0 -392
  497. ccxt/test/base/test_deep_extend.py +0 -68
  498. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  499. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  500. ccxt/test/base/test_funding_rate_history.py +0 -29
  501. ccxt/test/base/test_last_price.py +0 -31
  502. ccxt/test/base/test_ledger_entry.py +0 -45
  503. ccxt/test/base/test_ledger_item.py +0 -48
  504. ccxt/test/base/test_leverage_tier.py +0 -33
  505. ccxt/test/base/test_liquidation.py +0 -50
  506. ccxt/test/base/test_margin_mode.py +0 -24
  507. ccxt/test/base/test_margin_modification.py +0 -35
  508. ccxt/test/base/test_market.py +0 -193
  509. ccxt/test/base/test_number.py +0 -411
  510. ccxt/test/base/test_ohlcv.py +0 -33
  511. ccxt/test/base/test_open_interest.py +0 -32
  512. ccxt/test/base/test_order.py +0 -64
  513. ccxt/test/base/test_order_book.py +0 -69
  514. ccxt/test/base/test_position.py +0 -60
  515. ccxt/test/base/test_shared_methods.py +0 -353
  516. ccxt/test/base/test_status.py +0 -24
  517. ccxt/test/base/test_throttle.py +0 -126
  518. ccxt/test/base/test_ticker.py +0 -92
  519. ccxt/test/base/test_trade.py +0 -47
  520. ccxt/test/base/test_trading_fee.py +0 -26
  521. ccxt/test/base/test_transaction.py +0 -39
  522. ccxt/test/test_async.py +0 -1649
  523. ccxt/test/test_sync.py +0 -1648
  524. ccxt/wazirx.py +0 -1224
  525. ccxt_ir-4.3.46.0.2.dist-info/RECORD +0 -772
  526. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  527. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info/licenses}/LICENSE.txt +0 -0
  528. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/top_level.txt +0 -0
ccxt/gate.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.gate import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currencies, Currency, FundingHistory, Greeks, Int, Leverage, Leverages, LeverageTier, LeverageTiers, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
9
+ from ccxt.base.types import Any, Balances, BorrowInterest, Bool, Currencies, Currency, DepositAddress, FundingHistory, Greeks, Int, LedgerEntry, Leverage, Leverages, LeverageTier, LeverageTiers, MarginModification, Market, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, MarketInterface, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -16,7 +16,6 @@ from ccxt.base.errors import AccountSuspended
16
16
  from ccxt.base.errors import ArgumentsRequired
17
17
  from ccxt.base.errors import BadRequest
18
18
  from ccxt.base.errors import BadSymbol
19
- from ccxt.base.errors import BadResponse
20
19
  from ccxt.base.errors import InsufficientFunds
21
20
  from ccxt.base.errors import InvalidOrder
22
21
  from ccxt.base.errors import OrderNotFound
@@ -30,7 +29,7 @@ from ccxt.base.precise import Precise
30
29
 
31
30
  class gate(Exchange, ImplicitAPI):
32
31
 
33
- def describe(self):
32
+ def describe(self) -> Any:
34
33
  return self.deep_extend(super(gate, self).describe(), {
35
34
  'id': 'gate',
36
35
  'name': 'Gate.io',
@@ -40,7 +39,7 @@ class gate(Exchange, ImplicitAPI):
40
39
  'certified': True,
41
40
  'pro': True,
42
41
  'urls': {
43
- 'logo': 'https://user-images.githubusercontent.com/1294454/31784029-0313c702-b509-11e7-9ccc-bc0da6a0e435.jpg',
42
+ 'logo': 'https://github.com/user-attachments/assets/64f988c5-07b6-4652-b5c1-679a6bf67c85',
44
43
  'doc': 'https://www.gate.io/docs/developers/apiv4/en/',
45
44
  'www': 'https://gate.io/',
46
45
  'api': {
@@ -99,6 +98,8 @@ class gate(Exchange, ImplicitAPI):
99
98
  'borrowIsolatedMargin': True,
100
99
  'cancelAllOrders': True,
101
100
  'cancelOrder': True,
101
+ 'cancelOrders': True,
102
+ 'cancelOrdersForSymbols': True,
102
103
  'createMarketBuyOrderWithCost': True,
103
104
  'createMarketOrder': True,
104
105
  'createMarketOrderWithCost': False,
@@ -115,6 +116,7 @@ class gate(Exchange, ImplicitAPI):
115
116
  'createTriggerOrder': True,
116
117
  'editOrder': True,
117
118
  'fetchBalance': True,
119
+ 'fetchBorrowInterest': True,
118
120
  'fetchBorrowRateHistories': False,
119
121
  'fetchBorrowRateHistory': False,
120
122
  'fetchClosedOrders': True,
@@ -122,6 +124,8 @@ class gate(Exchange, ImplicitAPI):
122
124
  'fetchCrossBorrowRates': False,
123
125
  'fetchCurrencies': True,
124
126
  'fetchDepositAddress': True,
127
+ 'fetchDepositAddresses': False,
128
+ 'fetchDepositAddressesByNetwork': True,
125
129
  'fetchDeposits': True,
126
130
  'fetchDepositWithdrawFee': 'emulated',
127
131
  'fetchDepositWithdrawFees': True,
@@ -164,7 +168,7 @@ class gate(Exchange, ImplicitAPI):
164
168
  'fetchSettlementHistory': True,
165
169
  'fetchTicker': True,
166
170
  'fetchTickers': True,
167
- 'fetchTime': False,
171
+ 'fetchTime': True,
168
172
  'fetchTrades': True,
169
173
  'fetchTradingFee': True,
170
174
  'fetchTradingFees': True,
@@ -234,6 +238,7 @@ class gate(Exchange, ImplicitAPI):
234
238
  '{settle}/contract_stats': 1,
235
239
  '{settle}/index_constituents/{index}': 1,
236
240
  '{settle}/liq_orders': 1,
241
+ '{settle}/risk_limit_tiers': 1,
237
242
  },
238
243
  },
239
244
  'delivery': {
@@ -275,6 +280,7 @@ class gate(Exchange, ImplicitAPI):
275
280
  'withdrawals': {
276
281
  'post': {
277
282
  'withdrawals': 20, # 1r/s cost = 20 / 1 = 20
283
+ 'push': 1,
278
284
  },
279
285
  'delete': {
280
286
  'withdrawals/{withdrawal_id}': 1,
@@ -286,6 +292,7 @@ class gate(Exchange, ImplicitAPI):
286
292
  'withdrawals': 1,
287
293
  'deposits': 1,
288
294
  'sub_account_transfers': 1,
295
+ 'order_status': 1,
289
296
  'withdraw_status': 1,
290
297
  'sub_account_balances': 2.5,
291
298
  'sub_account_margin_balances': 2.5,
@@ -296,6 +303,7 @@ class gate(Exchange, ImplicitAPI):
296
303
  'total_balance': 2.5,
297
304
  'small_balance': 1,
298
305
  'small_balance_history': 1,
306
+ 'push': 1,
299
307
  },
300
308
  'post': {
301
309
  'transfers': 2.5, # 8r/s cost = 20 / 8 = 2.5
@@ -335,10 +343,20 @@ class gate(Exchange, ImplicitAPI):
335
343
  'interest_records': 20 / 15,
336
344
  'estimate_rate': 20 / 15,
337
345
  'currency_discount_tiers': 20 / 15,
346
+ 'risk_units': 20 / 15,
347
+ 'unified_mode': 20 / 15,
348
+ 'loan_margin_tiers': 20 / 15,
349
+ 'leverage/user_currency_config': 20 / 15,
350
+ 'leverage/user_currency_setting': 20 / 15,
338
351
  },
339
352
  'post': {
340
353
  'account_mode': 20 / 15,
341
354
  'loans': 200 / 15, # 15r/10s cost = 20 / 1.5 = 13.33
355
+ 'portfolio_calculator': 20 / 15,
356
+ 'leverage/user_currency_setting': 20 / 15,
357
+ },
358
+ 'put': {
359
+ 'unified_mode': 20 / 15,
342
360
  },
343
361
  },
344
362
  'spot': {
@@ -515,9 +533,13 @@ class gate(Exchange, ImplicitAPI):
515
533
  'orders': 20 / 15,
516
534
  'orders/{order_id}': 20 / 15,
517
535
  'my_trades': 20 / 15,
536
+ 'mmp': 20 / 15,
518
537
  },
519
538
  'post': {
520
539
  'orders': 20 / 15,
540
+ 'countdown_cancel_all': 20 / 15,
541
+ 'mmp': 20 / 15,
542
+ 'mmp/reset': 20 / 15,
521
543
  },
522
544
  'delete': {
523
545
  'orders': 20 / 15,
@@ -561,6 +583,7 @@ class gate(Exchange, ImplicitAPI):
561
583
  'multi_collateral/currencies': 20 / 15,
562
584
  'multi_collateral/ltv': 20 / 15,
563
585
  'multi_collateral/fixed_rate': 20 / 15,
586
+ 'multi_collateral/current_rate': 20 / 15,
564
587
  },
565
588
  'post': {
566
589
  'collateral/orders': 20 / 15,
@@ -574,8 +597,10 @@ class gate(Exchange, ImplicitAPI):
574
597
  'account': {
575
598
  'get': {
576
599
  'detail': 20 / 15,
600
+ 'rate_limit': 20 / 15,
577
601
  'stp_groups': 20 / 15,
578
602
  'stp_groups/{stp_id}/users': 20 / 15,
603
+ 'stp_groups/debit_fee': 20 / 15,
579
604
  },
580
605
  'post': {
581
606
  'stp_groups': 20 / 15,
@@ -609,22 +634,25 @@ class gate(Exchange, ImplicitAPI):
609
634
  },
610
635
  # copied from gatev2
611
636
  'commonCurrencies': {
637
+ 'ORT': 'XREATORS',
638
+ 'ASS': 'ASSF',
612
639
  '88MPH': 'MPH',
613
- 'AXIS': 'Axis DeFi',
614
- 'BIFI': 'Bitcoin File',
615
- 'BOX': 'DefiBox',
616
- 'BYN': 'BeyondFi',
617
- 'EGG': 'Goose Finance',
618
- 'GTC': 'Game.com', # conflict with Gitcoin and Gastrocoin
619
- 'GTC_HT': 'Game.com HT',
620
- 'GTC_BSC': 'Game.com BSC',
621
- 'HIT': 'HitChain',
622
- 'MM': 'Million', # conflict with MilliMeter
623
- 'MPH': 'Morpher', # conflict with 88MPH
624
- 'POINT': 'GatePoint',
625
- 'RAI': 'Rai Reflex Index', # conflict with RAI Finance
626
- 'SBTC': 'Super Bitcoin',
627
- 'TNC': 'Trinity Network Credit',
640
+ 'AXIS': 'AXISDEFI',
641
+ 'BIFI': 'BITCOINFILE',
642
+ 'BOX': 'DEFIBOX',
643
+ 'BYN': 'BEYONDFI',
644
+ 'EGG': 'GOOSEFINANCE',
645
+ 'GTC': 'GAMECOM', # conflict with Gitcoin and Gastrocoin
646
+ 'GTC_HT': 'GAMECOM_HT',
647
+ 'GTC_BSC': 'GAMECOM_BSC',
648
+ 'HIT': 'HITCHAIN',
649
+ 'MM': 'MILLION', # conflict with MilliMeter
650
+ 'MPH': 'MORPHER', # conflict with 88MPH
651
+ 'POINT': 'GATEPOINT',
652
+ 'RAI': 'RAIREFLEXINDEX', # conflict with RAI Finance
653
+ 'RED': 'RedLang',
654
+ 'SBTC': 'SUPERBITCOIN',
655
+ 'TNC': 'TRINITYNETWORKCREDIT',
628
656
  'VAI': 'VAIOT',
629
657
  'TRAC': 'TRACO', # conflict with OriginTrail(TRAC)
630
658
  },
@@ -636,23 +664,84 @@ class gate(Exchange, ImplicitAPI):
636
664
  'X-Gate-Channel-Id': 'ccxt',
637
665
  },
638
666
  'options': {
667
+ 'timeDifference': 0, # the difference between system clock and exchange clock
668
+ 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
639
669
  'sandboxMode': False,
670
+ 'unifiedAccount': None,
640
671
  'createOrder': {
641
672
  'expiration': 86400, # for conditional orders
642
673
  },
674
+ 'createMarketBuyOrderRequiresPrice': True,
643
675
  'networks': {
644
- 'AVAXC': 'AVAX_C',
676
+ 'BTC': 'BTC',
677
+ 'BRC20': 'BTCBRC', # for eg: ORDI, RATS, ...
678
+ 'ETH': 'ETH',
679
+ 'ERC20': 'ETH',
680
+ 'TRX': 'TRX',
681
+ 'TRC20': 'TRX',
682
+ 'HECO': 'HT',
683
+ 'HRC20': 'HT',
684
+ 'BSC': 'BSC',
645
685
  'BEP20': 'BSC',
686
+ 'SOL': 'SOL',
687
+ 'MATIC': 'MATIC',
688
+ 'OPTIMISM': 'OPETH',
689
+ 'ADA': 'ADA', # CARDANO
690
+ 'AVAXC': 'AVAX_C',
691
+ 'NEAR': 'NEAR',
692
+ 'ARBONE': 'ARBEVM',
693
+ 'BASE': 'BASEEVM',
694
+ 'SUI': 'SUI',
695
+ 'CRONOS': 'CRO',
696
+ 'CRO': 'CRO',
697
+ 'APT': 'APT',
698
+ 'SCROLL': 'SCROLLETH',
699
+ 'TAIKO': 'TAIKOETH',
700
+ 'HYPE': 'HYPE',
701
+ 'ALGO': 'ALGO',
702
+ # KAVA: ['KAVA', 'KAVAEVM']
703
+ # SEI: ['SEI', 'SEIEVM']
704
+ 'LINEA': 'LINEAETH',
705
+ 'BLAST': 'BLASTETH',
706
+ 'XLM': 'XLM',
707
+ 'RSK': 'RBTC',
708
+ 'TON': 'TON',
709
+ 'MNT': 'MNT',
710
+ # 'RUNE': 'BTCRUNES', probably, cant verify atm
711
+ 'CELO': 'CELO',
712
+ 'HBAR': 'HBAR',
713
+ # 'FTM': SONIC REBRAND, todo
714
+ 'ZKSERA': 'ZKSERA',
715
+ 'KLAY': 'KLAY',
646
716
  'EOS': 'EOS',
647
- 'ERC20': 'ETH',
717
+ 'ACA': 'ACA',
718
+ # TLOS: ['TLOS', 'TLOSEVM']
719
+ # ASTR: ['ASTR', 'ASTREVM']
720
+ # CFX: ['CFX', 'CFXEVM']
721
+ 'XTZ': 'XTZ',
722
+ 'EGLD': 'EGLD',
723
+ 'GLMR': 'GLMR',
724
+ 'AURORA': 'AURORAEVM',
725
+ # others
726
+ 'KON': 'KONET',
648
727
  'GATECHAIN': 'GTEVM',
649
- 'HRC20': 'HT',
650
728
  'KUSAMA': 'KSMSM',
651
- 'NEAR': 'NEAR',
652
729
  'OKC': 'OKT',
653
- 'OPTIMISM': 'OPETH',
654
- 'POLKADOT': 'DOTSM',
655
- 'TRC20': 'TRX',
730
+ 'POLKADOT': 'DOTSM', # todo: DOT for main DOT
731
+ 'LUNA': 'LUNC',
732
+ },
733
+ 'networksById': {
734
+ 'OPETH': 'OP',
735
+ 'ETH': 'ERC20', # for GOlang
736
+ 'ERC20': 'ERC20',
737
+ 'TRX': 'TRC20',
738
+ 'TRC20': 'TRC20',
739
+ 'HT': 'HRC20',
740
+ 'HECO': 'HRC20',
741
+ 'BSC': 'BEP20',
742
+ 'BEP20': 'BEP20',
743
+ 'POLYGON': 'MATIC',
744
+ 'POL': 'MATIC',
656
745
  },
657
746
  'timeInForce': {
658
747
  'GTC': 'gtc',
@@ -675,6 +764,9 @@ class gate(Exchange, ImplicitAPI):
675
764
  'option': 'options',
676
765
  'options': 'options',
677
766
  },
767
+ 'fetchMarkets': {
768
+ 'types': ['spot', 'swap', 'future', 'option'],
769
+ },
678
770
  'swap': {
679
771
  'fetchMarkets': {
680
772
  'settlementCurrencies': ['usdt', 'btc'],
@@ -686,6 +778,118 @@ class gate(Exchange, ImplicitAPI):
686
778
  },
687
779
  },
688
780
  },
781
+ 'features': {
782
+ 'default': {
783
+ 'sandbox': True,
784
+ 'createOrder': {
785
+ 'marginMode': True,
786
+ 'triggerPrice': True,
787
+ 'triggerDirection': True, # todo: implementation edit needed
788
+ 'triggerPriceType': None,
789
+ 'stopLossPrice': True,
790
+ 'takeProfitPrice': True,
791
+ 'attachedStopLossTakeProfit': None,
792
+ 'timeInForce': {
793
+ 'IOC': True,
794
+ 'FOK': True,
795
+ 'PO': True,
796
+ 'GTD': False,
797
+ },
798
+ 'hedged': False,
799
+ 'trailing': False,
800
+ 'iceberg': True, # todo implement
801
+ 'selfTradePrevention': True, # todo implement
802
+ 'leverage': False,
803
+ 'marketBuyByCost': True,
804
+ 'marketBuyRequiresPrice': True,
805
+ },
806
+ 'createOrders': {
807
+ 'max': 40, # NOTE! max 10 per symbol
808
+ },
809
+ 'fetchMyTrades': {
810
+ 'marginMode': True,
811
+ 'limit': 1000,
812
+ 'daysBack': None,
813
+ 'untilDays': 30,
814
+ 'symbolRequired': False,
815
+ },
816
+ 'fetchOrder': {
817
+ 'marginMode': False,
818
+ 'trigger': True,
819
+ 'trailing': False,
820
+ 'symbolRequired': True,
821
+ },
822
+ 'fetchOpenOrders': {
823
+ 'marginMode': True,
824
+ 'trigger': True,
825
+ 'trailing': False,
826
+ 'limit': 100,
827
+ 'symbolRequired': False,
828
+ },
829
+ 'fetchOrders': None,
830
+ 'fetchClosedOrders': {
831
+ 'marginMode': True,
832
+ 'trigger': True,
833
+ 'trailing': False,
834
+ 'limit': 100,
835
+ 'untilDays': 30,
836
+ 'daysBack': None,
837
+ 'daysBackCanceled': None,
838
+ 'symbolRequired': False,
839
+ },
840
+ 'fetchOHLCV': {
841
+ 'limit': 1000,
842
+ },
843
+ },
844
+ 'spot': {
845
+ 'extends': 'default',
846
+ },
847
+ 'forDerivatives': {
848
+ 'extends': 'spot',
849
+ 'createOrder': {
850
+ 'marginMode': False,
851
+ 'triggerPriceType': {
852
+ 'last': True,
853
+ 'mark': True,
854
+ 'index': True,
855
+ },
856
+ },
857
+ 'createOrders': {
858
+ 'max': 10,
859
+ },
860
+ 'fetchMyTrades': {
861
+ 'marginMode': False,
862
+ 'untilDays': None,
863
+ },
864
+ 'fetchOpenOrders': {
865
+ 'marginMode': False,
866
+ },
867
+ 'fetchClosedOrders': {
868
+ 'marginMode': False,
869
+ 'untilDays': None,
870
+ 'limit': 1000,
871
+ },
872
+ 'fetchOHLCV': {
873
+ 'limit': 1999,
874
+ },
875
+ },
876
+ 'swap': {
877
+ 'linear': {
878
+ 'extends': 'forDerivatives',
879
+ },
880
+ 'inverse': {
881
+ 'extends': 'forDerivatives',
882
+ },
883
+ },
884
+ 'future': {
885
+ 'linear': {
886
+ 'extends': 'forDerivatives',
887
+ },
888
+ 'inverse': {
889
+ 'extends': 'forDerivatives',
890
+ },
891
+ },
892
+ },
689
893
  'precisionMode': TICK_SIZE,
690
894
  'fees': {
691
895
  'trading': {
@@ -797,6 +1001,7 @@ class gate(Exchange, ImplicitAPI):
797
1001
  'NOT_ACCEPTABLE': BadRequest,
798
1002
  'METHOD_NOT_ALLOWED': BadRequest,
799
1003
  'NOT_FOUND': ExchangeError,
1004
+ 'AUTHENTICATION_FAILED': AuthenticationError,
800
1005
  'INVALID_CREDENTIALS': AuthenticationError,
801
1006
  'INVALID_KEY': AuthenticationError,
802
1007
  'IP_FORBIDDEN': AuthenticationError,
@@ -891,6 +1096,59 @@ class gate(Exchange, ImplicitAPI):
891
1096
  super(gate, self).set_sandbox_mode(enable)
892
1097
  self.options['sandboxMode'] = enable
893
1098
 
1099
+ def load_unified_status(self, params={}):
1100
+ """
1101
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1102
+ returns unifiedAccount so the user can check if the unified account is enabled
1103
+
1104
+ https://www.gate.io/docs/developers/apiv4/#get-account-detail
1105
+
1106
+ :returns boolean: True or False if the enabled unified account is enabled or not and sets the unifiedAccount option if it is None
1107
+ """
1108
+ unifiedAccount = self.safe_bool(self.options, 'unifiedAccount')
1109
+ if unifiedAccount is None:
1110
+ try:
1111
+ #
1112
+ # {
1113
+ # "user_id": 10406147,
1114
+ # "ip_whitelist": [],
1115
+ # "currency_pairs": [],
1116
+ # "key": {
1117
+ # "mode": 1
1118
+ # },
1119
+ # "tier": 0,
1120
+ # "tier_expire_time": "0001-01-01T00:00:00Z",
1121
+ # "copy_trading_role": 0
1122
+ # }
1123
+ #
1124
+ response = self.privateAccountGetDetail(params)
1125
+ result = self.safe_dict(response, 'key', {})
1126
+ self.options['unifiedAccount'] = self.safe_integer(result, 'mode') == 2
1127
+ except Exception as e:
1128
+ # if the request fails, the unifiedAccount is disabled
1129
+ self.options['unifiedAccount'] = False
1130
+ return self.options['unifiedAccount']
1131
+
1132
+ def upgrade_unified_trade_account(self, params={}):
1133
+ return self.privateUnifiedPutUnifiedMode(params)
1134
+
1135
+ def fetch_time(self, params={}) -> Int:
1136
+ """
1137
+ fetches the current integer timestamp in milliseconds from the exchange server
1138
+
1139
+ https://www.gate.io/docs/developers/apiv4/en/#get-server-current-time
1140
+
1141
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1142
+ :returns int: the current integer timestamp in milliseconds from the exchange server
1143
+ """
1144
+ response = self.publicSpotGetTime(params)
1145
+ #
1146
+ # {
1147
+ # "server_time": 1731447921098
1148
+ # }
1149
+ #
1150
+ return self.safe_integer(response, 'server_time')
1151
+
894
1152
  def create_expired_option_market(self, symbol: str):
895
1153
  # support expired option contracts
896
1154
  quote = 'USDT'
@@ -964,33 +1222,43 @@ class gate(Exchange, ImplicitAPI):
964
1222
  def fetch_markets(self, params={}) -> List[Market]:
965
1223
  """
966
1224
  retrieves data on all markets for gate
967
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-currency-pairs-supported # spot
968
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-supported-currency-pairs-supported-in-margin-trading # margin
969
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts # swap
970
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts-2 # future
971
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-the-contracts-with-specified-underlying-and-expiration-time # option
1225
+
1226
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-currency-pairs-supported # spot
1227
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-supported-currency-pairs-supported-in-margin-trading # margin
1228
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts # swap
1229
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts-2 # future
1230
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-the-contracts-with-specified-underlying-and-expiration-time # option
1231
+
972
1232
  :param dict [params]: extra parameters specific to the exchange API endpoint
973
1233
  :returns dict[]: an array of objects representing market data
974
1234
  """
1235
+ if self.options['adjustForTimeDifference']:
1236
+ self.load_time_difference()
1237
+ if self.check_required_credentials(False):
1238
+ self.load_unified_status()
1239
+ rawPromises = []
975
1240
  sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
976
- rawPromises = [
977
- self.fetch_contract_markets(params),
978
- self.fetch_option_markets(params),
979
- ]
980
- if not sandboxMode:
981
- # gate does not have a sandbox for spot markets
982
- mainnetOnly = [self.fetch_spot_markets(params)]
983
- rawPromises = self.array_concat(rawPromises, mainnetOnly)
984
- promises = rawPromises
985
- spotMarkets = self.safe_value(promises, 0, [])
986
- contractMarkets = self.safe_value(promises, 1, [])
987
- optionMarkets = self.safe_value(promises, 2, [])
988
- markets = self.array_concat(spotMarkets, contractMarkets)
989
- return self.array_concat(markets, optionMarkets)
1241
+ fetchMarketsOptions = self.safe_dict(self.options, 'fetchMarkets')
1242
+ types = self.safe_list(fetchMarketsOptions, 'types', ['spot', 'swap', 'future', 'option'])
1243
+ for i in range(0, len(types)):
1244
+ marketType = types[i]
1245
+ if marketType == 'spot':
1246
+ if not sandboxMode:
1247
+ # gate doesn't have a sandbox for spot markets
1248
+ rawPromises.append(self.fetch_spot_markets(params))
1249
+ elif marketType == 'swap':
1250
+ rawPromises.append(self.fetch_swap_markets(params))
1251
+ elif marketType == 'future':
1252
+ rawPromises.append(self.fetch_future_markets(params))
1253
+ elif marketType == 'option':
1254
+ rawPromises.append(self.fetch_option_markets(params))
1255
+ results = rawPromises
1256
+ return self.arrays_concat(results)
990
1257
 
991
1258
  def fetch_spot_markets(self, params={}):
992
- marginResponse = self.publicMarginGetCurrencyPairs(params)
993
- spotMarketsResponse = self.publicSpotGetCurrencyPairs(params)
1259
+ marginPromise = self.publicMarginGetCurrencyPairs(params)
1260
+ spotMarketsPromise = self.publicSpotGetCurrencyPairs(params)
1261
+ marginResponse, spotMarketsResponse = [marginPromise, spotMarketsPromise]
994
1262
  marginMarkets = self.index_by(marginResponse, 'id')
995
1263
  #
996
1264
  # Spot
@@ -999,17 +1267,21 @@ class gate(Exchange, ImplicitAPI):
999
1267
  # {
1000
1268
  # "id": "QTUM_ETH",
1001
1269
  # "base": "QTUM",
1270
+ # "base_name": "Quantum",
1002
1271
  # "quote": "ETH",
1272
+ # "quote_name": "Ethereum",
1003
1273
  # "fee": "0.2",
1004
1274
  # "min_base_amount": "0.01",
1005
1275
  # "min_quote_amount": "0.001",
1276
+ # "max_quote_amount": "50000",
1006
1277
  # "amount_precision": 3,
1007
1278
  # "precision": 6,
1008
1279
  # "trade_status": "tradable",
1009
- # "sell_start": 0,
1010
- # "buy_start": 0
1280
+ # "sell_start": 1607313600,
1281
+ # "buy_start": 1700492400,
1282
+ # "type": "normal",
1283
+ # "trade_url": "https://www.gate.io/trade/QTUM_ETH",
1011
1284
  # }
1012
- # ]
1013
1285
  #
1014
1286
  # Margin
1015
1287
  #
@@ -1040,6 +1312,8 @@ class gate(Exchange, ImplicitAPI):
1040
1312
  tradeStatus = self.safe_string(market, 'trade_status')
1041
1313
  leverage = self.safe_number(market, 'leverage')
1042
1314
  margin = leverage is not None
1315
+ buyStart = self.safe_integer_product(spotMarket, 'buy_start', 1000) # buy_start is the trading start time, while sell_start is offline orders start time
1316
+ createdTs = buyStart if (buyStart != 0) else None
1043
1317
  result.append({
1044
1318
  'id': id,
1045
1319
  'symbol': base + '/' + quote,
@@ -1089,15 +1363,14 @@ class gate(Exchange, ImplicitAPI):
1089
1363
  'max': self.safe_number(market, 'max_quote_amount') if margin else None,
1090
1364
  },
1091
1365
  },
1092
- 'created': None,
1366
+ 'created': createdTs,
1093
1367
  'info': market,
1094
1368
  })
1095
1369
  return result
1096
1370
 
1097
- def fetch_contract_markets(self, params={}):
1371
+ def fetch_swap_markets(self, params={}):
1098
1372
  result = []
1099
1373
  swapSettlementCurrencies = self.get_settlement_currencies('swap', 'fetchMarkets')
1100
- futureSettlementCurrencies = self.get_settlement_currencies('future', 'fetchMarkets')
1101
1374
  for c in range(0, len(swapSettlementCurrencies)):
1102
1375
  settleId = swapSettlementCurrencies[c]
1103
1376
  request: dict = {
@@ -1107,6 +1380,11 @@ class gate(Exchange, ImplicitAPI):
1107
1380
  for i in range(0, len(response)):
1108
1381
  parsedMarket = self.parse_contract_market(response[i], settleId)
1109
1382
  result.append(parsedMarket)
1383
+ return result
1384
+
1385
+ def fetch_future_markets(self, params={}):
1386
+ result = []
1387
+ futureSettlementCurrencies = self.get_settlement_currencies('future', 'fetchMarkets')
1110
1388
  for c in range(0, len(futureSettlementCurrencies)):
1111
1389
  settleId = futureSettlementCurrencies[c]
1112
1390
  request: dict = {
@@ -1154,6 +1432,7 @@ class gate(Exchange, ImplicitAPI):
1154
1432
  # "funding_next_apply": 1610035200,
1155
1433
  # "short_users": 977,
1156
1434
  # "config_change_time": 1609899548,
1435
+ # "create_time": 1609800048,
1157
1436
  # "trade_size": 28530850594,
1158
1437
  # "position_size": 5223816,
1159
1438
  # "long_users": 455,
@@ -1232,6 +1511,10 @@ class gate(Exchange, ImplicitAPI):
1232
1511
  takerPercent = self.safe_string(market, 'taker_fee_rate')
1233
1512
  makerPercent = self.safe_string(market, 'maker_fee_rate', takerPercent)
1234
1513
  isLinear = quote == settle
1514
+ contractSize = self.safe_string(market, 'quanto_multiplier')
1515
+ # exception only for one market: https://api.gateio.ws/api/v4/futures/btc/contracts
1516
+ if contractSize == '0':
1517
+ contractSize = '1' # 1 USD in WEB: https://i.imgur.com/MBBUI04.png
1235
1518
  return {
1236
1519
  'id': id,
1237
1520
  'symbol': symbol,
@@ -1253,7 +1536,7 @@ class gate(Exchange, ImplicitAPI):
1253
1536
  'inverse': not isLinear,
1254
1537
  'taker': self.parse_number(Precise.string_div(takerPercent, '100')), # Fee is in %, so divide by 100
1255
1538
  'maker': self.parse_number(Precise.string_div(makerPercent, '100')),
1256
- 'contractSize': self.safe_number(market, 'quanto_multiplier'),
1539
+ 'contractSize': self.parse_number(contractSize),
1257
1540
  'expiry': expiry,
1258
1541
  'expiryDatetime': self.iso8601(expiry),
1259
1542
  'strike': None,
@@ -1280,7 +1563,7 @@ class gate(Exchange, ImplicitAPI):
1280
1563
  'max': None,
1281
1564
  },
1282
1565
  },
1283
- 'created': None,
1566
+ 'created': self.safe_integer_product(market, 'create_time', 1000),
1284
1567
  'info': market,
1285
1568
  }
1286
1569
 
@@ -1377,7 +1660,7 @@ class gate(Exchange, ImplicitAPI):
1377
1660
  'contractSize': self.parse_number('1'),
1378
1661
  'expiry': expiry,
1379
1662
  'expiryDatetime': self.iso8601(expiry),
1380
- 'strike': strike,
1663
+ 'strike': self.parse_number(strike),
1381
1664
  'optionType': optionType,
1382
1665
  'precision': {
1383
1666
  'amount': self.parse_number('1'), # all options have self step size
@@ -1427,7 +1710,7 @@ class gate(Exchange, ImplicitAPI):
1427
1710
 
1428
1711
  def prepare_request(self, market=None, type=None, params={}):
1429
1712
  """
1430
- * @ignore
1713
+ @ignore
1431
1714
  Fills request params contract, settle, currency_pair, market and account where applicable
1432
1715
  :param dict market: CCXT market, required when type is None
1433
1716
  :param str type: 'spot', 'swap', or 'future', required when market is None
@@ -1453,50 +1736,50 @@ class gate(Exchange, ImplicitAPI):
1453
1736
  request['settle'] = settle
1454
1737
  return [request, params]
1455
1738
 
1456
- def spot_order_prepare_request(self, market=None, stop=False, params={}):
1739
+ def spot_order_prepare_request(self, market=None, trigger=False, params={}):
1457
1740
  """
1458
- * @ignore
1741
+ @ignore
1459
1742
  Fills request params currency_pair, market and account where applicable for spot order methods like fetchOpenOrders, cancelAllOrders
1460
1743
  :param dict market: CCXT market
1461
- :param bool stop: True if for a stop order
1744
+ :param bool trigger: True if for a trigger order
1462
1745
  :param dict [params]: request parameters
1463
1746
  :returns: the api request object, and the new params object with non-needed parameters removed
1464
1747
  """
1465
- marginMode, query = self.get_margin_mode(stop, params)
1748
+ marginMode, query = self.get_margin_mode(trigger, params)
1466
1749
  request: dict = {}
1467
- if not stop:
1750
+ if not trigger:
1468
1751
  if market is None:
1469
- raise ArgumentsRequired(self.id + ' spotOrderPrepareRequest() requires a market argument for non-stop orders')
1752
+ raise ArgumentsRequired(self.id + ' spotOrderPrepareRequest() requires a market argument for non-trigger orders')
1470
1753
  request['account'] = marginMode
1471
- request['currency_pair'] = market['id'] # Should always be set for non-stop
1754
+ request['currency_pair'] = market['id'] # Should always be set for non-trigger
1472
1755
  return [request, query]
1473
1756
 
1474
- def multi_order_spot_prepare_request(self, market=None, stop=False, params={}):
1757
+ def multi_order_spot_prepare_request(self, market=None, trigger=False, params={}):
1475
1758
  """
1476
- * @ignore
1759
+ @ignore
1477
1760
  Fills request params currency_pair, market and account where applicable for spot order methods like fetchOpenOrders, cancelAllOrders
1478
1761
  :param dict market: CCXT market
1479
- :param bool stop: True if for a stop order
1762
+ :param bool trigger: True if for a trigger order
1480
1763
  :param dict [params]: request parameters
1481
1764
  :returns: the api request object, and the new params object with non-needed parameters removed
1482
1765
  """
1483
- marginMode, query = self.get_margin_mode(stop, params)
1766
+ marginMode, query = self.get_margin_mode(trigger, params)
1484
1767
  request: dict = {
1485
1768
  'account': marginMode,
1486
1769
  }
1487
1770
  if market is not None:
1488
- if stop:
1489
- # 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
1771
+ if trigger:
1772
+ # 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
1490
1773
  request['market'] = market['id']
1491
1774
  else:
1492
1775
  request['currency_pair'] = market['id']
1493
1776
  return [request, query]
1494
1777
 
1495
- def get_margin_mode(self, stop, params):
1778
+ def get_margin_mode(self, trigger, params):
1496
1779
  """
1497
- * @ignore
1780
+ @ignore
1498
1781
  Gets the margin type for self api call
1499
- :param bool stop: True if for a stop order
1782
+ :param bool trigger: True if for a trigger order
1500
1783
  :param dict [params]: Request params
1501
1784
  :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
1502
1785
  """
@@ -1509,12 +1792,16 @@ class gate(Exchange, ImplicitAPI):
1509
1792
  marginMode = 'margin'
1510
1793
  elif marginMode == '':
1511
1794
  marginMode = 'spot'
1512
- if stop:
1795
+ if trigger:
1513
1796
  if marginMode == 'spot':
1514
- # gate spot stop orders use the term normal instead of spot
1797
+ # gate spot trigger orders use the term normal instead of spot
1515
1798
  marginMode = 'normal'
1516
1799
  if marginMode == 'cross_margin':
1517
- raise BadRequest(self.id + ' getMarginMode() does not support stop orders for cross margin')
1800
+ raise BadRequest(self.id + ' getMarginMode() does not support trigger orders for cross margin')
1801
+ isUnifiedAccount = False
1802
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'getMarginMode', 'unifiedAccount')
1803
+ if isUnifiedAccount:
1804
+ marginMode = 'unified'
1518
1805
  return [marginMode, params]
1519
1806
 
1520
1807
  def get_settlement_currencies(self, type, method):
@@ -1526,7 +1813,9 @@ class gate(Exchange, ImplicitAPI):
1526
1813
  def fetch_currencies(self, params={}) -> Currencies:
1527
1814
  """
1528
1815
  fetches all available currencies on an exchange
1529
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-currencies-details
1816
+
1817
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-currencies-details
1818
+
1530
1819
  :param dict [params]: extra parameters specific to the exchange API endpoint
1531
1820
  :returns dict: an associative dictionary of currencies
1532
1821
  """
@@ -1536,80 +1825,68 @@ class gate(Exchange, ImplicitAPI):
1536
1825
  return None
1537
1826
  response = self.publicSpotGetCurrencies(params)
1538
1827
  #
1539
- # {
1540
- # "currency": "BCN",
1541
- # "delisted": False,
1542
- # "withdraw_disabled": True,
1543
- # "withdraw_delayed": False,
1544
- # "deposit_disabled": True,
1545
- # "trade_disabled": False
1546
- # }
1547
- #
1548
- # {
1549
- # "currency":"USDT_ETH",
1550
- # "delisted":false,
1551
- # "withdraw_disabled":false,
1552
- # "withdraw_delayed":false,
1553
- # "deposit_disabled":false,
1554
- # "trade_disabled":false,
1555
- # "chain":"ETH"
1556
- # }
1828
+ # [
1829
+ # {
1830
+ # "currency": "USDT",
1831
+ # "name": "Tether",
1832
+ # "delisted": False,
1833
+ # "withdraw_disabled": False,
1834
+ # "withdraw_delayed": False,
1835
+ # "deposit_disabled": False,
1836
+ # "trade_disabled": False,
1837
+ # "fixed_rate": "",
1838
+ # "chain": "ETH",
1839
+ # "chains": [
1840
+ # {
1841
+ # "name": "ETH",
1842
+ # "addr": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
1843
+ # "withdraw_disabled": False,
1844
+ # "withdraw_delayed": False,
1845
+ # "deposit_disabled": False
1846
+ # },
1847
+ # {
1848
+ # "name": "ARBEVM",
1849
+ # "addr": "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
1850
+ # "withdraw_disabled": False,
1851
+ # "withdraw_delayed": False,
1852
+ # "deposit_disabled": False
1853
+ # },
1854
+ # {
1855
+ # "name": "BSC",
1856
+ # "addr": "0x55d398326f99059fF775485246999027B3197955",
1857
+ # "withdraw_disabled": False,
1858
+ # "withdraw_delayed": False,
1859
+ # "deposit_disabled": False
1860
+ # },
1861
+ # ]
1862
+ # },
1863
+ # ]
1557
1864
  #
1865
+ indexedCurrencies = self.index_by(response, 'currency')
1558
1866
  result: dict = {}
1559
1867
  for i in range(0, len(response)):
1560
1868
  entry = response[i]
1561
1869
  currencyId = self.safe_string(entry, 'currency')
1562
- currencyIdLower = self.safe_string_lower(entry, 'currency')
1563
- parts = currencyId.split('_')
1564
- currency = parts[0]
1565
- code = self.safe_currency_code(currency)
1566
- networkId = self.safe_string(entry, 'chain')
1567
- networkCode = None
1568
- if networkId is not None:
1569
- networkCode = self.network_id_to_code(networkId, code)
1570
- delisted = self.safe_value(entry, 'delisted')
1571
- withdrawDisabled = self.safe_bool(entry, 'withdraw_disabled', False)
1572
- depositDisabled = self.safe_bool(entry, 'deposit_disabled', False)
1573
- tradeDisabled = self.safe_bool(entry, 'trade_disabled', False)
1574
- withdrawEnabled = not withdrawDisabled
1575
- depositEnabled = not depositDisabled
1576
- tradeEnabled = not tradeDisabled
1577
- listed = not delisted
1578
- active = listed and tradeEnabled and withdrawEnabled and depositEnabled
1579
- if self.safe_value(result, code) is None:
1580
- result[code] = {
1581
- 'id': code.lower(),
1582
- 'code': code,
1583
- 'info': None,
1584
- 'name': None,
1585
- 'active': active,
1586
- 'deposit': depositEnabled,
1587
- 'withdraw': withdrawEnabled,
1588
- 'fee': None,
1589
- 'fees': [],
1590
- 'precision': self.parse_number('1e-4'),
1591
- 'limits': self.limits,
1592
- 'networks': {},
1593
- }
1594
- depositAvailable = self.safe_value(result[code], 'deposit')
1595
- depositAvailable = depositEnabled if (depositEnabled) else depositAvailable
1596
- withdrawAvailable = self.safe_value(result[code], 'withdraw')
1597
- withdrawAvailable = withdrawEnabled if (withdrawEnabled) else withdrawAvailable
1598
- networks = self.safe_value(result[code], 'networks', {})
1599
- if networkCode is not None:
1870
+ code = self.safe_currency_code(currencyId)
1871
+ # check leveraged tokens(e.g. BTC3S, ETH5L)
1872
+ type = 'leveraged' if self.is_leveraged_currency(currencyId, True, indexedCurrencies) else 'crypto'
1873
+ chains = self.safe_list(entry, 'chains', [])
1874
+ networks = {}
1875
+ for j in range(0, len(chains)):
1876
+ chain = chains[j]
1877
+ networkId = self.safe_string(chain, 'name')
1878
+ networkCode = self.network_id_to_code(networkId)
1600
1879
  networks[networkCode] = {
1601
- 'info': entry,
1880
+ 'info': chain,
1602
1881
  'id': networkId,
1603
1882
  'network': networkCode,
1604
- 'currencyId': currencyId,
1605
- 'lowerCaseCurrencyId': currencyIdLower,
1606
- 'deposit': depositEnabled,
1607
- 'withdraw': withdrawEnabled,
1608
- 'active': active,
1883
+ 'active': None,
1884
+ 'deposit': not self.safe_bool(chain, 'deposit_disabled'),
1885
+ 'withdraw': not self.safe_bool(chain, 'withdraw_disabled'),
1609
1886
  'fee': None,
1610
- 'precision': self.parse_number('1e-4'),
1887
+ 'precision': self.parse_number('0.0001'), # temporary safe default, because no value provided from API,
1611
1888
  'limits': {
1612
- 'amount': {
1889
+ 'deposit': {
1613
1890
  'min': None,
1614
1891
  'max': None,
1615
1892
  },
@@ -1617,25 +1894,29 @@ class gate(Exchange, ImplicitAPI):
1617
1894
  'min': None,
1618
1895
  'max': None,
1619
1896
  },
1620
- 'deposit': {
1621
- 'min': None,
1622
- 'max': None,
1623
- },
1624
1897
  },
1625
1898
  }
1626
- result[code]['networks'] = networks
1627
- info = self.safe_value(result[code], 'info', [])
1628
- info.append(entry)
1629
- result[code]['info'] = info
1630
- result[code]['active'] = depositAvailable and withdrawAvailable
1631
- result[code]['deposit'] = depositAvailable
1632
- result[code]['withdraw'] = withdrawAvailable
1899
+ result[code] = self.safe_currency_structure({
1900
+ 'id': currencyId,
1901
+ 'code': code,
1902
+ 'name': self.safe_string(entry, 'name'),
1903
+ 'type': type,
1904
+ 'active': not self.safe_bool(entry, 'delisted'),
1905
+ 'deposit': not self.safe_bool(entry, 'deposit_disabled'),
1906
+ 'withdraw': not self.safe_bool(entry, 'withdraw_disabled'),
1907
+ 'fee': None,
1908
+ 'networks': networks,
1909
+ 'precision': self.parse_number('0.0001'),
1910
+ 'info': entry,
1911
+ })
1633
1912
  return result
1634
1913
 
1635
- def fetch_funding_rate(self, symbol: str, params={}):
1914
+ def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
1636
1915
  """
1637
1916
  fetch the current funding rate
1638
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-a-single-contract
1917
+
1918
+ https://www.gate.io/docs/developers/apiv4/en/#get-a-single-contract
1919
+
1639
1920
  :param str symbol: unified market symbol
1640
1921
  :param dict [params]: extra parameters specific to the exchange API endpoint
1641
1922
  :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
@@ -1692,17 +1973,23 @@ class gate(Exchange, ImplicitAPI):
1692
1973
  #
1693
1974
  return self.parse_funding_rate(response)
1694
1975
 
1695
- def fetch_funding_rates(self, symbols: Strings = None, params={}):
1976
+ def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
1696
1977
  """
1697
1978
  fetch the funding rate for multiple markets
1698
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts
1979
+
1980
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts
1981
+
1699
1982
  :param str[]|None symbols: list of unified market symbols
1700
1983
  :param dict [params]: extra parameters specific to the exchange API endpoint
1701
- :returns dict: a dictionary of `funding rates structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexe by market symbols
1984
+ :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexed by market symbols
1702
1985
  """
1703
1986
  self.load_markets()
1704
1987
  symbols = self.market_symbols(symbols)
1705
- request, query = self.prepare_request(None, 'swap', params)
1988
+ market = None
1989
+ if symbols is not None:
1990
+ firstSymbol = self.safe_string(symbols, 0)
1991
+ market = self.market(firstSymbol)
1992
+ request, query = self.prepare_request(market, 'swap', params)
1706
1993
  response = self.publicFuturesGetSettleContracts(self.extend(request, query))
1707
1994
  #
1708
1995
  # [
@@ -1748,10 +2035,9 @@ class gate(Exchange, ImplicitAPI):
1748
2035
  # }
1749
2036
  # ]
1750
2037
  #
1751
- result = self.parse_funding_rates(response)
1752
- return self.filter_by_array(result, 'symbol', symbols)
2038
+ return self.parse_funding_rates(response, symbols)
1753
2039
 
1754
- def parse_funding_rate(self, contract, market: Market = None):
2040
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
1755
2041
  #
1756
2042
  # {
1757
2043
  # "name": "BTC_USDT",
@@ -1802,6 +2088,7 @@ class gate(Exchange, ImplicitAPI):
1802
2088
  fundingRate = self.safe_number(contract, 'funding_rate')
1803
2089
  fundingTime = self.safe_timestamp(contract, 'funding_next_apply')
1804
2090
  fundingRateIndicative = self.safe_number(contract, 'funding_rate_indicative')
2091
+ fundingInterval = Precise.string_mul('1000', self.safe_string(contract, 'funding_interval'))
1805
2092
  return {
1806
2093
  'info': contract,
1807
2094
  'symbol': symbol,
@@ -1820,7 +2107,18 @@ class gate(Exchange, ImplicitAPI):
1820
2107
  'previousFundingRate': None,
1821
2108
  'previousFundingTimestamp': None,
1822
2109
  'previousFundingDatetime': None,
2110
+ 'interval': self.parse_funding_interval(fundingInterval),
2111
+ }
2112
+
2113
+ def parse_funding_interval(self, interval):
2114
+ intervals: dict = {
2115
+ '3600000': '1h',
2116
+ '14400000': '4h',
2117
+ '28800000': '8h',
2118
+ '57600000': '16h',
2119
+ '86400000': '24h',
1823
2120
  }
2121
+ return self.safe_string(intervals, interval, interval)
1824
2122
 
1825
2123
  def fetch_network_deposit_address(self, code: str, params={}):
1826
2124
  self.load_markets()
@@ -1859,82 +2157,69 @@ class gate(Exchange, ImplicitAPI):
1859
2157
  }
1860
2158
  return result
1861
2159
 
1862
- def fetch_deposit_address(self, code: str, params={}):
2160
+ def fetch_deposit_addresses_by_network(self, code: str, params={}) -> List[DepositAddress]:
2161
+ """
2162
+ fetch a dictionary of addresses for a currency, indexed by network
2163
+ :param str code: unified currency code of the currency for the deposit address
2164
+ :param dict [params]: extra parameters specific to the api endpoint
2165
+ :returns dict: a dictionary of `address structures <https://docs.ccxt.com/#/?id=address-structure>` indexed by the network
2166
+ """
2167
+ self.load_markets()
2168
+ currency = self.currency(code)
2169
+ request = {
2170
+ 'currency': currency['id'],
2171
+ }
2172
+ response = self.privateWalletGetDepositAddress(self.extend(request, params))
2173
+ chains = self.safe_value(response, 'multichain_addresses', [])
2174
+ currencyId = self.safe_string(response, 'currency')
2175
+ currency = self.safe_currency(currencyId, currency)
2176
+ parsed = self.parse_deposit_addresses(chains, None, False)
2177
+ return self.index_by(parsed, 'network')
2178
+
2179
+ def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
1863
2180
  """
1864
2181
  fetch the deposit address for a currency associated with self account
1865
- :see: https://www.gate.io/docs/developers/apiv4/en/#generate-currency-deposit-address
2182
+
2183
+ https://www.gate.io/docs/developers/apiv4/en/#generate-currency-deposit-address
2184
+
1866
2185
  :param str code: unified currency code
1867
2186
  :param dict [params]: extra parameters specific to the exchange API endpoint
1868
2187
  :param str [params.network]: unified network code(not used directly by gate.io but used by ccxt to filter the response)
1869
2188
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
1870
2189
  """
1871
2190
  self.load_markets()
1872
- currency = self.currency(code)
1873
- rawNetwork = self.safe_string_upper(params, 'network')
1874
- params = self.omit(params, 'network')
1875
- request: dict = {
1876
- 'currency': currency['id'], # todo: currencies have network-junctions
1877
- }
1878
- response = self.privateWalletGetDepositAddress(self.extend(request, params))
2191
+ networkCode = None
2192
+ networkCode, params = self.handle_network_code_and_params(params)
2193
+ chainsIndexedById = self.fetch_deposit_addresses_by_network(code, params)
2194
+ selectedNetworkIdOrCode = self.select_network_code_from_unified_networks(code, networkCode, chainsIndexedById)
2195
+ return chainsIndexedById[selectedNetworkIdOrCode]
2196
+
2197
+ def parse_deposit_address(self, depositAddress, currency=None):
1879
2198
  #
1880
- # {
1881
- # "currency": "XRP",
1882
- # "address": "rHcFoo6a9qT5NHiVn1THQRhsEGcxtYCV4d 391331007",
1883
- # "multichain_addresses": [
1884
- # {
1885
- # "chain": "XRP",
1886
- # "address": "rHcFoo6a9qT5NHiVn1THQRhsEGcxtYCV4d",
1887
- # "payment_id": "391331007",
1888
- # "payment_name": "Tag",
1889
- # "obtain_failed": 0
1890
- # }
1891
- # ]
1892
- # }
2199
+ # {
2200
+ # chain: "BTC",
2201
+ # address: "1Nxu.......Ys",
2202
+ # payment_id: "",
2203
+ # payment_name: "",
2204
+ # obtain_failed: "0",
2205
+ # }
1893
2206
  #
1894
- currencyId = self.safe_string(response, 'currency')
1895
- code = self.safe_currency_code(currencyId)
1896
- networkId = self.network_code_to_id(rawNetwork, code)
1897
- network = None
1898
- tag = None
1899
- address = None
1900
- if networkId is not None:
1901
- addresses = self.safe_value(response, 'multichain_addresses')
1902
- for i in range(0, len(addresses)):
1903
- entry = addresses[i]
1904
- entryNetwork = self.safe_string(entry, 'chain')
1905
- if networkId == entryNetwork:
1906
- obtainFailed = self.safe_integer(entry, 'obtain_failed')
1907
- if obtainFailed:
1908
- break
1909
- address = self.safe_string(entry, 'address')
1910
- tag = self.safe_string(entry, 'payment_id')
1911
- network = self.network_id_to_code(networkId, code)
1912
- break
1913
- else:
1914
- addressField = self.safe_string(response, 'address')
1915
- if addressField is not None:
1916
- if addressField.find('New address is being generated for you, please wait') >= 0:
1917
- raise BadResponse(self.id + ' ' + 'New address is being generated for you, please wait a few seconds and try again to get the address.')
1918
- if addressField.find(' ') >= 0:
1919
- splitted = addressField.split(' ')
1920
- address = splitted[0]
1921
- tag = splitted[1]
1922
- else:
1923
- address = addressField
2207
+ address = self.safe_string(depositAddress, 'address')
1924
2208
  self.check_address(address)
1925
2209
  return {
1926
- 'info': response,
1927
- 'code': code, # kept here for backward-compatibility, but will be removed soon
1928
- 'currency': code,
2210
+ 'info': depositAddress,
2211
+ 'currency': self.safe_string(currency, 'code'),
1929
2212
  'address': address,
1930
- 'tag': tag,
1931
- 'network': network,
2213
+ 'tag': self.safe_string(depositAddress, 'payment_id'),
2214
+ 'network': self.network_id_to_code(self.safe_string(depositAddress, 'chain')),
1932
2215
  }
1933
2216
 
1934
2217
  def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
1935
2218
  """
1936
2219
  fetch the trading fees for a market
1937
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-personal-trading-fee
2220
+
2221
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-personal-trading-fee
2222
+
1938
2223
  :param str symbol: unified market symbol
1939
2224
  :param dict [params]: extra parameters specific to the exchange API endpoint
1940
2225
  :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -1964,7 +2249,9 @@ class gate(Exchange, ImplicitAPI):
1964
2249
  def fetch_trading_fees(self, params={}) -> TradingFees:
1965
2250
  """
1966
2251
  fetch the trading fees for multiple markets
1967
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-personal-trading-fee
2252
+
2253
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-personal-trading-fee
2254
+
1968
2255
  :param dict [params]: extra parameters specific to the exchange API endpoint
1969
2256
  :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
1970
2257
  """
@@ -2026,9 +2313,11 @@ class gate(Exchange, ImplicitAPI):
2026
2313
 
2027
2314
  def fetch_transaction_fees(self, codes: Strings = None, params={}):
2028
2315
  """
2029
- * @deprecated
2316
+ @deprecated
2030
2317
  please use fetchDepositWithdrawFees instead
2031
- :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
+
2032
2321
  :param str[]|None codes: list of unified currency codes
2033
2322
  :param dict [params]: extra parameters specific to the exchange API endpoint
2034
2323
  :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -2079,7 +2368,9 @@ class gate(Exchange, ImplicitAPI):
2079
2368
  def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
2080
2369
  """
2081
2370
  fetch deposit and withdraw fees
2082
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-withdrawal-status
2371
+
2372
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-withdrawal-status
2373
+
2083
2374
  :param str[]|None codes: list of unified currency codes
2084
2375
  :param dict [params]: extra parameters specific to the exchange API endpoint
2085
2376
  :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -2142,7 +2433,8 @@ class gate(Exchange, ImplicitAPI):
2142
2433
  chainKeys = list(withdrawFixOnChains.keys())
2143
2434
  for i in range(0, len(chainKeys)):
2144
2435
  chainKey = chainKeys[i]
2145
- result['networks'][chainKey] = {
2436
+ networkCode = self.network_id_to_code(chainKey, self.safe_string(fee, 'currency'))
2437
+ result['networks'][networkCode] = {
2146
2438
  'withdraw': {
2147
2439
  'fee': self.parse_number(withdrawFixOnChains[chainKey]),
2148
2440
  'percentage': False,
@@ -2157,8 +2449,10 @@ class gate(Exchange, ImplicitAPI):
2157
2449
  def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2158
2450
  """
2159
2451
  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
2452
+
2453
+ https://www.gate.io/docs/developers/apiv4/en/#query-account-book-2
2454
+ https://www.gate.io/docs/developers/apiv4/en/#query-account-book-3
2455
+
2162
2456
  :param str symbol: unified market symbol
2163
2457
  :param int [since]: the earliest time in ms to fetch funding history for
2164
2458
  :param int [limit]: the maximum number of funding history structures to retrieve
@@ -2235,10 +2529,12 @@ class gate(Exchange, ImplicitAPI):
2235
2529
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
2236
2530
  """
2237
2531
  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
2532
+
2533
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-order-book
2534
+ https://www.gate.io/docs/developers/apiv4/en/#futures-order-book
2535
+ https://www.gate.io/docs/developers/apiv4/en/#futures-order-book-2
2536
+ https://www.gate.io/docs/developers/apiv4/en/#options-order-book
2537
+
2242
2538
  :param str symbol: unified symbol of the market to fetch the order book for
2243
2539
  :param int [limit]: the maximum amount of order book entries to return
2244
2540
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2256,7 +2552,11 @@ class gate(Exchange, ImplicitAPI):
2256
2552
  #
2257
2553
  request, query = self.prepare_request(market, market['type'], params)
2258
2554
  if limit is not None:
2259
- request['limit'] = limit # default 10, max 100
2555
+ if market['spot']:
2556
+ limit = min(limit, 1000)
2557
+ else:
2558
+ limit = min(limit, 300)
2559
+ request['limit'] = limit
2260
2560
  request['with_id'] = True
2261
2561
  response = None
2262
2562
  if market['spot'] or market['margin']:
@@ -2346,10 +2646,12 @@ class gate(Exchange, ImplicitAPI):
2346
2646
  def fetch_ticker(self, symbol: str, params={}) -> Ticker:
2347
2647
  """
2348
2648
  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
2649
+
2650
+ https://www.gate.io/docs/developers/apiv4/en/#get-details-of-a-specifc-order
2651
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-tickers
2652
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-tickers-2
2653
+ https://www.gate.io/docs/developers/apiv4/en/#list-tickers-of-options-contracts
2654
+
2353
2655
  :param str symbol: unified symbol of the market to fetch the ticker for
2354
2656
  :param dict [params]: extra parameters specific to the exchange API endpoint
2355
2657
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -2489,16 +2791,20 @@ class gate(Exchange, ImplicitAPI):
2489
2791
  'average': None,
2490
2792
  'baseVolume': baseVolume,
2491
2793
  'quoteVolume': quoteVolume,
2794
+ 'markPrice': self.safe_string(ticker, 'mark_price'),
2795
+ 'indexPrice': self.safe_string(ticker, 'index_price'),
2492
2796
  'info': ticker,
2493
2797
  }, market)
2494
2798
 
2495
2799
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
2496
2800
  """
2497
2801
  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
2802
+
2803
+ https://www.gate.io/docs/developers/apiv4/en/#get-details-of-a-specifc-order
2804
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-tickers
2805
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-tickers-2
2806
+ https://www.gate.io/docs/developers/apiv4/en/#list-tickers-of-options-contracts
2807
+
2502
2808
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
2503
2809
  :param dict [params]: extra parameters specific to the exchange API endpoint
2504
2810
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -2545,10 +2851,15 @@ class gate(Exchange, ImplicitAPI):
2545
2851
  :param str [params.settle]: 'btc' or 'usdt' - settle currency for perpetual swap and future - default="usdt" for swap and "btc" for future
2546
2852
  :param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
2547
2853
  :param str [params.symbol]: margin only - unified ccxt symbol
2854
+ :param boolean [params.unifiedAccount]: default False, set to True for fetching the unified account balance
2855
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
2548
2856
  """
2549
2857
  self.load_markets()
2858
+ self.load_unified_status()
2550
2859
  symbol = self.safe_string(params, 'symbol')
2551
2860
  params = self.omit(params, 'symbol')
2861
+ isUnifiedAccount = False
2862
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'fetchBalance', 'unifiedAccount')
2552
2863
  type, query = self.handle_market_type_and_params('fetchBalance', None, params)
2553
2864
  request, requestParams = self.prepare_request(None, type, query)
2554
2865
  marginMode, requestQuery = self.get_margin_mode(False, requestParams)
@@ -2556,7 +2867,9 @@ class gate(Exchange, ImplicitAPI):
2556
2867
  market = self.market(symbol)
2557
2868
  request['currency_pair'] = market['id']
2558
2869
  response = None
2559
- if type == 'spot':
2870
+ if isUnifiedAccount:
2871
+ response = self.privateUnifiedGetAccounts(self.extend(request, params))
2872
+ elif type == 'spot':
2560
2873
  if marginMode == 'spot':
2561
2874
  response = self.privateSpotGetAccounts(self.extend(request, requestQuery))
2562
2875
  elif marginMode == 'margin':
@@ -2719,12 +3032,63 @@ class gate(Exchange, ImplicitAPI):
2719
3032
  # "orders_limit": 10
2720
3033
  # }
2721
3034
  #
3035
+ # unified
3036
+ #
3037
+ # {
3038
+ # "user_id": 10001,
3039
+ # "locked": False,
3040
+ # "balances": {
3041
+ # "ETH": {
3042
+ # "available": "0",
3043
+ # "freeze": "0",
3044
+ # "borrowed": "0.075393666654",
3045
+ # "negative_liab": "0",
3046
+ # "futures_pos_liab": "0",
3047
+ # "equity": "1016.1",
3048
+ # "total_freeze": "0",
3049
+ # "total_liab": "0"
3050
+ # },
3051
+ # "POINT": {
3052
+ # "available": "9999999999.017023138734",
3053
+ # "freeze": "0",
3054
+ # "borrowed": "0",
3055
+ # "negative_liab": "0",
3056
+ # "futures_pos_liab": "0",
3057
+ # "equity": "12016.1",
3058
+ # "total_freeze": "0",
3059
+ # "total_liab": "0"
3060
+ # },
3061
+ # "USDT": {
3062
+ # "available": "0.00000062023",
3063
+ # "freeze": "0",
3064
+ # "borrowed": "0",
3065
+ # "negative_liab": "0",
3066
+ # "futures_pos_liab": "0",
3067
+ # "equity": "16.1",
3068
+ # "total_freeze": "0",
3069
+ # "total_liab": "0"
3070
+ # }
3071
+ # },
3072
+ # "total": "230.94621713",
3073
+ # "borrowed": "161.66395521",
3074
+ # "total_initial_margin": "1025.0524665088",
3075
+ # "total_margin_balance": "3382495.944473949183",
3076
+ # "total_maintenance_margin": "205.01049330176",
3077
+ # "total_initial_margin_rate": "3299.827135672679",
3078
+ # "total_maintenance_margin_rate": "16499.135678363399",
3079
+ # "total_available_margin": "3381470.892007440383",
3080
+ # "unified_account_total": "3381470.892007440383",
3081
+ # "unified_account_total_liab": "0",
3082
+ # "unified_account_total_equity": "100016.1",
3083
+ # "leverage": "2"
3084
+ # }
3085
+ #
2722
3086
  result: dict = {
2723
3087
  'info': response,
2724
3088
  }
2725
3089
  isolated = marginMode == 'margin'
2726
3090
  data = response
2727
- if 'balances' in data: # True for cross_margin
3091
+ if 'balances' in data: # True for cross_margin and unified
2728
3092
  flatBalances = []
2729
3093
  balances = self.safe_value(data, 'balances', [])
2730
3094
  # inject currency and create an artificial balance object
@@ -2758,10 +3122,12 @@ class gate(Exchange, ImplicitAPI):
2758
3122
  def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
2759
3123
  """
2760
3124
  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
3125
+
3126
+ https://www.gate.io/docs/developers/apiv4/en/#market-candlesticks # spot
3127
+ https://www.gate.io/docs/developers/apiv4/en/#get-futures-candlesticks # swap
3128
+ https://www.gate.io/docs/developers/apiv4/en/#market-candlesticks # future
3129
+ https://www.gate.io/docs/developers/apiv4/en/#get-options-candlesticks # option
3130
+
2765
3131
  :param str symbol: unified symbol of the market to fetch OHLCV data for
2766
3132
  :param str timeframe: the length of time each candle represents
2767
3133
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -2807,7 +3173,6 @@ class gate(Exchange, ImplicitAPI):
2807
3173
  request['limit'] = limit
2808
3174
  response = None
2809
3175
  if market['contract']:
2810
- maxLimit = 1999
2811
3176
  isMark = (price == 'mark')
2812
3177
  isIndex = (price == 'index')
2813
3178
  if isMark or isIndex:
@@ -2834,23 +3199,38 @@ class gate(Exchange, ImplicitAPI):
2834
3199
  def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2835
3200
  """
2836
3201
  fetches historical funding rate prices
2837
- :see: https://www.gate.io/docs/developers/apiv4/en/#funding-rate-history
3202
+
3203
+ https://www.gate.io/docs/developers/apiv4/en/#funding-rate-history
3204
+
2838
3205
  :param str symbol: unified symbol of the market to fetch the funding rate history for
2839
3206
  :param int [since]: timestamp in ms of the earliest funding rate to fetch
2840
3207
  :param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
2841
3208
  :param dict [params]: extra parameters specific to the exchange API endpoint
3209
+ :param int [params.until]: timestamp in ms of the latest funding rate to fetch
3210
+ :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
3211
  :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>`
2843
3212
  """
2844
3213
  if symbol is None:
2845
3214
  raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
2846
3215
  self.load_markets()
3216
+ paginate = False
3217
+ paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
3218
+ if paginate:
3219
+ return self.fetch_paginated_call_deterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params)
2847
3220
  market = self.market(symbol)
2848
3221
  if not market['swap']:
2849
3222
  raise BadSymbol(self.id + ' fetchFundingRateHistory() supports swap contracts only')
2850
- request, query = self.prepare_request(market, None, params)
3223
+ request: dict = {}
3224
+ request, params = self.prepare_request(market, None, params)
2851
3225
  if limit is not None:
2852
3226
  request['limit'] = limit
2853
- response = self.publicFuturesGetSettleFundingRate(self.extend(request, query))
3227
+ if since is not None:
3228
+ request['from'] = self.parse_to_int(since / 1000)
3229
+ until = self.safe_integer(params, 'until')
3230
+ if until is not None:
3231
+ params = self.omit(params, 'until')
3232
+ request['to'] = self.parse_to_int(until / 1000)
3233
+ response = self.publicFuturesGetSettleFundingRate(self.extend(request, params))
2854
3234
  #
2855
3235
  # {
2856
3236
  # "r": "0.00063521",
@@ -2919,10 +3299,12 @@ class gate(Exchange, ImplicitAPI):
2919
3299
  def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
2920
3300
  """
2921
3301
  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
3302
+
3303
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-market-trades
3304
+ https://www.gate.io/docs/developers/apiv4/en/#futures-trading-history
3305
+ https://www.gate.io/docs/developers/apiv4/en/#futures-trading-history-2
3306
+ https://www.gate.io/docs/developers/apiv4/en/#options-trade-history
3307
+
2926
3308
  :param str symbol: unified symbol of the market to fetch trades for
2927
3309
  :param int [since]: timestamp in ms of the earliest trade to fetch
2928
3310
  :param int [limit]: the maximum amount of trades to fetch
@@ -3023,10 +3405,12 @@ class gate(Exchange, ImplicitAPI):
3023
3405
  def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3024
3406
  """
3025
3407
  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
3408
+
3409
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history
3410
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-2
3411
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-3
3412
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-4
3413
+
3030
3414
  :param str id: order id
3031
3415
  :param str symbol: unified market symbol
3032
3416
  :param int [since]: the earliest time in ms to fetch trades for
@@ -3062,10 +3446,12 @@ class gate(Exchange, ImplicitAPI):
3062
3446
  def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3063
3447
  """
3064
3448
  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
3449
+
3450
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history
3451
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-2
3452
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-3
3453
+ https://www.gate.io/docs/developers/apiv4/en/#list-personal-trading-history-4
3454
+
3069
3455
  :param str symbol: unified market symbol
3070
3456
  :param int [since]: the earliest time in ms to fetch trades for
3071
3457
  :param int [limit]: the maximum number of trades structures to retrieve
@@ -3079,10 +3465,12 @@ class gate(Exchange, ImplicitAPI):
3079
3465
  :param int [params.offset]: *contract only* list offset, starting from 0
3080
3466
  :param str [params.last_id]: *contract only* specify list staring point using the id of last record in previous list-query results
3081
3467
  :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)
3468
+ :param bool [params.unifiedAccount]: set to True for fetching trades in a unified account
3469
+ :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
3470
  :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
3084
3471
  """
3085
3472
  self.load_markets()
3473
+ self.load_unified_status()
3086
3474
  paginate = False
3087
3475
  paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
3088
3476
  if paginate:
@@ -3101,7 +3489,7 @@ class gate(Exchange, ImplicitAPI):
3101
3489
  params = self.omit(params, 'order_id')
3102
3490
  else:
3103
3491
  if market is not None:
3104
- request['currency_pair'] = market['id'] # Should always be set for non-stop
3492
+ request['currency_pair'] = market['id'] # Should always be set for non-trigger
3105
3493
  marginMode, params = self.get_margin_mode(False, params)
3106
3494
  request['account'] = marginMode
3107
3495
  if limit is not None:
@@ -3191,6 +3579,7 @@ class gate(Exchange, ImplicitAPI):
3191
3579
  #
3192
3580
  # public
3193
3581
  #
3582
+ # spot:
3194
3583
  # {
3195
3584
  # "id": "1334253759",
3196
3585
  # "create_time": "1626342738",
@@ -3201,6 +3590,18 @@ class gate(Exchange, ImplicitAPI):
3201
3590
  # "price": "32452.16"
3202
3591
  # }
3203
3592
  #
3593
+ # swap:
3594
+ #
3595
+ # {
3596
+ # "id": "442288327",
3597
+ # "contract": "BTC_USDT",
3598
+ # "create_time": "1739814676.707",
3599
+ # "create_time_ms": "1739814676.707",
3600
+ # "size": "-105",
3601
+ # "price": "95594.8"
3602
+ # }
3603
+ #
3604
+ #
3204
3605
  # public ws
3205
3606
  #
3206
3607
  # {
@@ -3277,8 +3678,14 @@ class gate(Exchange, ImplicitAPI):
3277
3678
  # }
3278
3679
  #
3279
3680
  id = self.safe_string_2(trade, 'id', 'trade_id')
3280
- timestamp = self.safe_timestamp_2(trade, 'time', 'create_time')
3281
- timestamp = self.safe_integer(trade, 'create_time_ms', timestamp)
3681
+ timestamp: Int = None
3682
+ msString = self.safe_string(trade, 'create_time_ms')
3683
+ if msString is not None:
3684
+ msString = Precise.string_mul(msString, '1000')
3685
+ msString = msString[0:13]
3686
+ timestamp = self.parse_to_int(msString)
3687
+ else:
3688
+ timestamp = self.safe_timestamp_2(trade, 'time', 'create_time')
3282
3689
  marketId = self.safe_string_2(trade, 'currency_pair', 'contract')
3283
3690
  marketType = 'contract' if ('contract' in trade) else 'spot'
3284
3691
  market = self.safe_market(marketId, market, '_', marketType)
@@ -3289,8 +3696,8 @@ class gate(Exchange, ImplicitAPI):
3289
3696
  side = self.safe_string_2(trade, 'side', 'type', contractSide)
3290
3697
  orderId = self.safe_string(trade, 'order_id')
3291
3698
  feeAmount = self.safe_string(trade, 'fee')
3292
- gtFee = self.safe_string(trade, 'gt_fee')
3293
- pointFee = self.safe_string(trade, 'point_fee')
3699
+ gtFee = self.omit_zero(self.safe_string(trade, 'gt_fee'))
3700
+ pointFee = self.omit_zero(self.safe_string(trade, 'point_fee'))
3294
3701
  fees = []
3295
3702
  if feeAmount is not None:
3296
3703
  feeCurrencyId = self.safe_string(trade, 'fee_currency')
@@ -3332,12 +3739,14 @@ class gate(Exchange, ImplicitAPI):
3332
3739
  def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
3333
3740
  """
3334
3741
  fetch all deposits made to an account
3335
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-deposit-records
3742
+
3743
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-deposit-records
3744
+
3336
3745
  :param str code: unified currency code
3337
3746
  :param int [since]: the earliest time in ms to fetch deposits for
3338
3747
  :param int [limit]: the maximum number of deposits structures to retrieve
3339
- :param int [params.until]: end time in ms
3340
3748
  :param dict [params]: extra parameters specific to the exchange API endpoint
3749
+ :param int [params.until]: end time in ms
3341
3750
  :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
3751
  :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
3343
3752
  """
@@ -3357,14 +3766,16 @@ class gate(Exchange, ImplicitAPI):
3357
3766
  start = self.parse_to_int(since / 1000)
3358
3767
  request['from'] = start
3359
3768
  request['to'] = self.sum(start, 30 * 24 * 60 * 60)
3360
- request, params = self.handle_until_option('to', request, params)
3769
+ request, params = self.handle_until_option('to', request, params, 0.001)
3361
3770
  response = self.privateWalletGetDeposits(self.extend(request, params))
3362
3771
  return self.parse_transactions(response, currency)
3363
3772
 
3364
3773
  def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
3365
3774
  """
3366
3775
  fetch all withdrawals made from an account
3367
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-withdrawal-records
3776
+
3777
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-withdrawal-records
3778
+
3368
3779
  :param str code: unified currency code
3369
3780
  :param int [since]: the earliest time in ms to fetch withdrawals for
3370
3781
  :param int [limit]: the maximum number of withdrawals structures to retrieve
@@ -3389,14 +3800,16 @@ class gate(Exchange, ImplicitAPI):
3389
3800
  start = self.parse_to_int(since / 1000)
3390
3801
  request['from'] = start
3391
3802
  request['to'] = self.sum(start, 30 * 24 * 60 * 60)
3392
- request, params = self.handle_until_option('to', request, params)
3803
+ request, params = self.handle_until_option('to', request, params, 0.001)
3393
3804
  response = self.privateWalletGetWithdrawals(self.extend(request, params))
3394
3805
  return self.parse_transactions(response, currency)
3395
3806
 
3396
- def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
3807
+ def withdraw(self, code: str, amount: float, address: str, tag: Str = None, params={}) -> Transaction:
3397
3808
  """
3398
3809
  make a withdrawal
3399
- :see: https://www.gate.io/docs/developers/apiv4/en/#withdraw
3810
+
3811
+ https://www.gate.io/docs/developers/apiv4/en/#withdraw
3812
+
3400
3813
  :param str code: unified currency code
3401
3814
  :param float amount: the amount to withdraw
3402
3815
  :param str address: the address to withdraw to
@@ -3415,14 +3828,10 @@ class gate(Exchange, ImplicitAPI):
3415
3828
  }
3416
3829
  if tag is not None:
3417
3830
  request['memo'] = tag
3418
- networks = self.safe_value(self.options, 'networks', {})
3419
- network = self.safe_string_upper(params, 'network') # self line allows the user to specify either ERC20 or ETH
3420
- network = self.safe_string_lower(networks, network, network) # handle ETH>ERC20 alias
3421
- if network is not None:
3422
- request['chain'] = network
3423
- params = self.omit(params, 'network')
3424
- else:
3425
- request['chain'] = currency['id'] # todo: currencies have network-junctions
3831
+ networkCode = None
3832
+ networkCode, params = self.handle_network_code_and_params(params)
3833
+ if networkCode is not None:
3834
+ request['chain'] = self.network_code_to_id(networkCode)
3426
3835
  response = self.privateWithdrawalsPostWithdrawals(self.extend(request, params))
3427
3836
  #
3428
3837
  # {
@@ -3462,32 +3871,61 @@ class gate(Exchange, ImplicitAPI):
3462
3871
 
3463
3872
  def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
3464
3873
  #
3465
- # deposits
3874
+ # fetchDeposits
3466
3875
  #
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
- # }
3876
+ # {
3877
+ # "id": "d33361395",
3878
+ # "currency": "USDT_TRX",
3879
+ # "address": "TErdnxenuLtXfnMafLbfappYdHtnXQ5U4z",
3880
+ # "amount": "100",
3881
+ # "txid": "ae9374de34e558562fe18cbb1bf9ab4d9eb8aa7669d65541c9fa2a532c1474a0",
3882
+ # "timestamp": "1626345819",
3883
+ # "status": "DONE",
3884
+ # "memo": ""
3885
+ # }
3477
3886
  #
3478
3887
  # withdraw
3479
3888
  #
3480
- # {
3481
- # "id": "w13389675",
3482
- # "currency": "USDT",
3483
- # "amount": "50",
3484
- # "address": "TUu2rLFrmzUodiWfYki7QCNtv1akL682p1",
3485
- # "memo": null
3486
- # }
3889
+ # {
3890
+ # "id":"w64413318",
3891
+ # "currency":"usdt",
3892
+ # "amount":"10150",
3893
+ # "address":"0x0ab891497116f7f5532a4c2f4f7b1784488628e1",
3894
+ # "memo":null,
3895
+ # "status":"REQUEST",
3896
+ # "chain":"eth",
3897
+ # "withdraw_order_id":"",
3898
+ # "fee_amount":"4.15000000"
3899
+ # }
3900
+ #
3901
+ # fetchWithdrawals
3902
+ #
3903
+ # {
3904
+ # "id": "210496",
3905
+ # "timestamp": "1542000000",
3906
+ # "withdraw_order_id": "order_123456",
3907
+ # "currency": "USDT",
3908
+ # "address": "1HkxtBAMrA3tP5ENnYY2CZortjZvFDH5Cs",
3909
+ # "txid": "128988928203223323290",
3910
+ # "block_number": "41575382",
3911
+ # "amount": "222.61",
3912
+ # "fee": "0.01",
3913
+ # "memo": "",
3914
+ # "status": "DONE",
3915
+ # "chain": "TRX"
3916
+ # }
3917
+ #
3918
+ # {
3919
+ # "id": "w13389675",
3920
+ # "currency": "USDT",
3921
+ # "amount": "50",
3922
+ # "address": "TUu2rLFrmzUodiWfYki7QCNtv1akL682p1",
3923
+ # "memo": null
3924
+ # }
3487
3925
  #
3488
3926
  # {
3489
3927
  # "currency":"usdt",
3490
- # "address":"0x01b0A9b7b4CdE774AF0f3E47CB4f1c2CCdBa0806",
3928
+ # "address":"0x01c0A9b7b4CdE774AF0f3E47CB4f1c2CCdBa0806",
3491
3929
  # "amount":"1880",
3492
3930
  # "chain":"eth"
3493
3931
  # }
@@ -3502,7 +3940,7 @@ class gate(Exchange, ImplicitAPI):
3502
3940
  amountString = Precise.string_abs(amountString)
3503
3941
  else:
3504
3942
  type = self.parse_transaction_type(id[0])
3505
- feeCostString = self.safe_string(transaction, 'fee')
3943
+ feeCostString = self.safe_string_2(transaction, 'fee', 'fee_amount')
3506
3944
  if type == 'withdrawal':
3507
3945
  amountString = Precise.string_sub(amountString, feeCostString)
3508
3946
  networkId = self.safe_string_upper(transaction, 'chain')
@@ -3543,20 +3981,22 @@ class gate(Exchange, ImplicitAPI):
3543
3981
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
3544
3982
  """
3545
3983
  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
3984
+
3985
+ https://www.gate.io/docs/developers/apiv4/en/#create-an-order
3986
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-price-triggered-order
3987
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order
3988
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-price-triggered-order-2
3989
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order-2
3990
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-price-triggered-order-3
3991
+ https://www.gate.io/docs/developers/apiv4/en/#create-an-options-order
3992
+
3553
3993
  :param str symbol: Unified CCXT market symbol
3554
3994
  :param str type: 'limit' or 'market' *"market" is contract only*
3555
3995
  :param str side: 'buy' or 'sell'
3556
3996
  :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
3997
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
3558
3998
  :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
3999
+ :param float [params.triggerPrice]: The price at which a trigger order is triggered at
3560
4000
  :param str [params.timeInForce]: "GTC", "IOC", or "PO"
3561
4001
  :param float [params.stopLossPrice]: The price at which a stop loss order is triggered at
3562
4002
  :param float [params.takeProfitPrice]: The price at which a take profit order is triggered at
@@ -3571,9 +4011,11 @@ class gate(Exchange, ImplicitAPI):
3571
4011
  :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
4012
  :param int [params.price_type]: *contract only* 0 latest deal price, 1 mark price, 2 index price
3573
4013
  :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
4014
+ :param bool [params.unifiedAccount]: set to True for creating an order in the unified account
3574
4015
  :returns dict|None: `An order structure <https://docs.ccxt.com/#/?id=order-structure>`
3575
4016
  """
3576
4017
  self.load_markets()
4018
+ self.load_unified_status()
3577
4019
  market = self.market(symbol)
3578
4020
  trigger = self.safe_value(params, 'trigger')
3579
4021
  triggerPrice = self.safe_value_2(params, 'triggerPrice', 'stopPrice')
@@ -3581,8 +4023,8 @@ class gate(Exchange, ImplicitAPI):
3581
4023
  takeProfitPrice = self.safe_value(params, 'takeProfitPrice')
3582
4024
  isStopLossOrder = stopLossPrice is not None
3583
4025
  isTakeProfitOrder = takeProfitPrice is not None
3584
- isStopOrder = isStopLossOrder or isTakeProfitOrder
3585
- nonTriggerOrder = not isStopOrder and (trigger is None)
4026
+ isTpsl = isStopLossOrder or isTakeProfitOrder
4027
+ nonTriggerOrder = not isTpsl and (trigger is None)
3586
4028
  orderRequest = self.create_order_request(symbol, type, side, amount, price, params)
3587
4029
  response = None
3588
4030
  if market['spot'] or market['margin']:
@@ -3668,17 +4110,14 @@ class gate(Exchange, ImplicitAPI):
3668
4110
  #
3669
4111
  return self.parse_order(response, market)
3670
4112
 
3671
- 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
- self.load_markets()
4113
+ def create_orders_request(self, orders: List[OrderRequest], params={}):
3680
4114
  ordersRequests = []
3681
4115
  orderSymbols = []
4116
+ ordersLength = len(orders)
4117
+ if ordersLength == 0:
4118
+ raise BadRequest(self.id + ' createOrders() requires at least one order')
4119
+ if ordersLength > 10:
4120
+ raise BadRequest(self.id + ' createOrders() accepts a maximum of 10 orders at a time')
3682
4121
  for i in range(0, len(orders)):
3683
4122
  rawOrder = orders[i]
3684
4123
  marketId = self.safe_string(rawOrder, 'symbol')
@@ -3699,6 +4138,25 @@ class gate(Exchange, ImplicitAPI):
3699
4138
  market = self.market(symbols[0])
3700
4139
  if market['future'] or market['option']:
3701
4140
  raise NotSupported(self.id + ' createOrders() does not support futures or options markets')
4141
+ return ordersRequests
4142
+
4143
+ def create_orders(self, orders: List[OrderRequest], params={}):
4144
+ """
4145
+ create a list of trade orders
4146
+
4147
+ https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-2
4148
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-batch-of-orders
4149
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-batch-of-futures-orders
4150
+
4151
+ :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
4152
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4153
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4154
+ """
4155
+ self.load_markets()
4156
+ self.load_unified_status()
4157
+ ordersRequests = self.create_orders_request(orders, params)
4158
+ firstOrder = orders[0]
4159
+ market = self.market(firstOrder['symbol'])
3702
4160
  response = None
3703
4161
  if market['spot']:
3704
4162
  response = self.privateSpotPostBatchOrders(ordersRequests)
@@ -3715,7 +4173,7 @@ class gate(Exchange, ImplicitAPI):
3715
4173
  takeProfitPrice = self.safe_value(params, 'takeProfitPrice')
3716
4174
  isStopLossOrder = stopLossPrice is not None
3717
4175
  isTakeProfitOrder = takeProfitPrice is not None
3718
- isStopOrder = isStopLossOrder or isTakeProfitOrder
4176
+ isTpsl = isStopLossOrder or isTakeProfitOrder
3719
4177
  if isStopLossOrder and isTakeProfitOrder:
3720
4178
  raise ExchangeError(self.id + ' createOrder() stopLossPrice and takeProfitPrice cannot both be defined')
3721
4179
  reduceOnly = self.safe_value(params, 'reduceOnly')
@@ -3751,7 +4209,7 @@ class gate(Exchange, ImplicitAPI):
3751
4209
  signedAmount = Precise.string_neg(amountToPrecision) if (side == 'sell') else amountToPrecision
3752
4210
  amount = int(signedAmount)
3753
4211
  request = None
3754
- nonTriggerOrder = not isStopOrder and (trigger is None)
4212
+ nonTriggerOrder = not isTpsl and (trigger is None)
3755
4213
  if nonTriggerOrder:
3756
4214
  if contract:
3757
4215
  # contract order
@@ -3768,9 +4226,9 @@ class gate(Exchange, ImplicitAPI):
3768
4226
  if not market['option']:
3769
4227
  request['settle'] = market['settleId'] # filled in prepareRequest above
3770
4228
  if isMarketOrder:
3771
- request['price'] = price # set to 0 for market orders
4229
+ request['price'] = '0' # set to 0 for market orders
3772
4230
  else:
3773
- request['price'] = self.price_to_precision(symbol, price)
4231
+ request['price'] = '0' if (price == 0) else self.price_to_precision(symbol, price)
3774
4232
  if reduceOnly is not None:
3775
4233
  request['reduce_only'] = reduceOnly
3776
4234
  if timeInForce is not None:
@@ -3783,7 +4241,7 @@ class gate(Exchange, ImplicitAPI):
3783
4241
  # 'text': clientOrderId, # 't-abcdef1234567890',
3784
4242
  'currency_pair': market['id'], # filled in prepareRequest above
3785
4243
  'type': type,
3786
- 'account': marginMode, # 'spot', 'margin', 'cross_margin'
4244
+ 'account': marginMode, # spot, margin, cross_margin, unified
3787
4245
  'side': side,
3788
4246
  # 'time_in_force': 'gtc', # gtc, ioc, poc PendingOrCancelled == postOnly order
3789
4247
  # '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 +4299,7 @@ class gate(Exchange, ImplicitAPI):
3841
4299
  'initial': {
3842
4300
  'contract': market['id'],
3843
4301
  '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
4302
+ # 'price': '0' if (price == 0) else self.price_to_precision(symbol, price), # set to 0 to use market price
3845
4303
  # 'close': False, # set to True if trying to close the position
3846
4304
  # 'tif': 'gtc', # gtc, ioc, if using market price, only ioc is supported
3847
4305
  # 'text': clientOrderId, # web, api, app
@@ -3849,6 +4307,10 @@ class gate(Exchange, ImplicitAPI):
3849
4307
  },
3850
4308
  'settle': market['settleId'],
3851
4309
  }
4310
+ if type == 'market':
4311
+ request['initial']['price'] = '0'
4312
+ else:
4313
+ request['initial']['price'] = '0' if (price == 0) else self.price_to_precision(symbol, price)
3852
4314
  if trigger is None:
3853
4315
  rule = None
3854
4316
  triggerOrderPrice = None
@@ -3916,44 +4378,39 @@ class gate(Exchange, ImplicitAPI):
3916
4378
  def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
3917
4379
  """
3918
4380
  create a market buy order by providing the symbol and cost
3919
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-an-order
4381
+
4382
+ https://www.gate.io/docs/developers/apiv4/en/#create-an-order
4383
+
3920
4384
  :param str symbol: unified symbol of the market to create an order in
3921
4385
  :param float cost: how much you want to trade in units of the quote currency
3922
4386
  :param dict [params]: extra parameters specific to the exchange API endpoint
4387
+ :param bool [params.unifiedAccount]: set to True for creating a unified account order
3923
4388
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3924
4389
  """
3925
4390
  self.load_markets()
4391
+ self.load_unified_status()
3926
4392
  market = self.market(symbol)
3927
4393
  if not market['spot']:
3928
4394
  raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
3929
4395
  params['createMarketBuyOrderRequiresPrice'] = False
3930
4396
  return self.create_order(symbol, 'market', 'buy', cost, None, params)
3931
4397
 
3932
- 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
- self.load_markets()
4398
+ def edit_order_request(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
3947
4399
  market = self.market(symbol)
3948
- marketType, query = self.handle_market_type_and_params('editOrder', market, params)
4400
+ marketType = None
4401
+ marketType, params = self.handle_market_type_and_params('editOrder', market, params)
3949
4402
  account = self.convert_type_to_account(marketType)
4403
+ isUnifiedAccount = False
4404
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'editOrder', 'unifiedAccount')
4405
+ if isUnifiedAccount:
4406
+ account = 'unified'
3950
4407
  isLimitOrder = (type == 'limit')
3951
4408
  if account == 'spot':
3952
4409
  if not isLimitOrder:
3953
4410
  # exchange doesn't have market orders for spot
3954
4411
  raise InvalidOrder(self.id + ' editOrder() does not support ' + type + ' orders for ' + marketType + ' markets')
3955
4412
  request: dict = {
3956
- 'order_id': id,
4413
+ 'order_id': str(id),
3957
4414
  'currency_pair': market['id'],
3958
4415
  'account': account,
3959
4416
  }
@@ -3962,17 +4419,41 @@ class gate(Exchange, ImplicitAPI):
3962
4419
  request['amount'] = self.amount_to_precision(symbol, amount)
3963
4420
  else:
3964
4421
  if side == 'sell':
3965
- request['size'] = Precise.string_neg(self.amount_to_precision(symbol, amount))
4422
+ request['size'] = self.parse_to_numeric(Precise.string_neg(self.amount_to_precision(symbol, amount)))
3966
4423
  else:
3967
- request['size'] = self.amount_to_precision(symbol, amount)
4424
+ request['size'] = self.parse_to_numeric(self.amount_to_precision(symbol, amount))
3968
4425
  if price is not None:
3969
4426
  request['price'] = self.price_to_precision(symbol, price)
4427
+ if not market['spot']:
4428
+ request['settle'] = market['settleId']
4429
+ return self.extend(request, params)
4430
+
4431
+ def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
4432
+ """
4433
+ edit a trade order, gate currently only supports the modification of the price or amount fields
4434
+
4435
+ https://www.gate.io/docs/developers/apiv4/en/#amend-an-order
4436
+ https://www.gate.io/docs/developers/apiv4/en/#amend-an-order-2
4437
+
4438
+ :param str id: order id
4439
+ :param str symbol: unified symbol of the market to create an order in
4440
+ :param str type: 'market' or 'limit'
4441
+ :param str side: 'buy' or 'sell'
4442
+ :param float amount: how much of the currency you want to trade in units of the base currency
4443
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
4444
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4445
+ :param bool [params.unifiedAccount]: set to True for editing an order in a unified account
4446
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4447
+ """
4448
+ self.load_markets()
4449
+ self.load_unified_status()
4450
+ market = self.market(symbol)
4451
+ extendedRequest = self.edit_order_request(id, symbol, type, side, amount, price, params)
3970
4452
  response = None
3971
4453
  if market['spot']:
3972
- response = self.privateSpotPatchOrdersOrderId(self.extend(request, query))
4454
+ response = self.privateSpotPatchOrdersOrderId(extendedRequest)
3973
4455
  else:
3974
- request['settle'] = market['settleId']
3975
- response = self.privateFuturesPutSettleOrdersOrderId(self.extend(request, query))
4456
+ response = self.privateFuturesPutSettleOrdersOrderId(extendedRequest)
3976
4457
  #
3977
4458
  # {
3978
4459
  # "id": "243233276443",
@@ -4164,6 +4645,8 @@ class gate(Exchange, ImplicitAPI):
4164
4645
  # "message": "Not enough balance"
4165
4646
  # }
4166
4647
  #
4648
+ # {"user_id":10406147,"id":"id","succeeded":false,"message":"INVALID_PROTOCOL","label":"INVALID_PROTOCOL"}
4649
+ #
4167
4650
  succeeded = self.safe_bool(order, 'succeeded', True)
4168
4651
  if not succeeded:
4169
4652
  # cancelOrders response
@@ -4171,6 +4654,7 @@ class gate(Exchange, ImplicitAPI):
4171
4654
  'clientOrderId': self.safe_string(order, 'text'),
4172
4655
  'info': order,
4173
4656
  'status': 'rejected',
4657
+ 'id': self.safe_string(order, 'id'),
4174
4658
  })
4175
4659
  put = self.safe_value_2(order, 'put', 'initial', {})
4176
4660
  trigger = self.safe_value(order, 'trigger', {})
@@ -4215,19 +4699,19 @@ class gate(Exchange, ImplicitAPI):
4215
4699
  # Everything below self(above return) is related to fees
4216
4700
  fees = []
4217
4701
  gtFee = self.safe_string(order, 'gt_fee')
4218
- if gtFee:
4702
+ if gtFee is not None:
4219
4703
  fees.append({
4220
4704
  'currency': 'GT',
4221
4705
  'cost': gtFee,
4222
4706
  })
4223
4707
  fee = self.safe_string(order, 'fee')
4224
- if fee:
4708
+ if fee is not None:
4225
4709
  fees.append({
4226
4710
  'currency': self.safe_currency_code(self.safe_string(order, 'fee_currency')),
4227
4711
  'cost': fee,
4228
4712
  })
4229
4713
  rebate = self.safe_string(order, 'rebated_fee')
4230
- if rebate:
4714
+ if rebate is not None:
4231
4715
  fees.append({
4232
4716
  'currency': self.safe_currency_code(self.safe_string(order, 'rebated_fee_currency')),
4233
4717
  'cost': Precise.string_neg(rebate),
@@ -4260,7 +4744,6 @@ class gate(Exchange, ImplicitAPI):
4260
4744
  'reduceOnly': self.safe_value(order, 'is_reduce_only'),
4261
4745
  'side': side,
4262
4746
  'price': price,
4263
- 'stopPrice': triggerPrice,
4264
4747
  'triggerPrice': triggerPrice,
4265
4748
  'average': average,
4266
4749
  'amount': Precise.string_abs(amount),
@@ -4273,50 +4756,62 @@ class gate(Exchange, ImplicitAPI):
4273
4756
  'info': order,
4274
4757
  }, market)
4275
4758
 
4759
+ def fetch_order_request(self, id: str, symbol: Str = None, params={}):
4760
+ market = None if (symbol is None) else self.market(symbol)
4761
+ trigger = self.safe_bool_n(params, ['trigger', 'is_stop_order', 'stop'], False)
4762
+ params = self.omit(params, ['is_stop_order', 'stop', 'trigger'])
4763
+ clientOrderId = self.safe_string_2(params, 'text', 'clientOrderId')
4764
+ orderId = id
4765
+ if clientOrderId is not None:
4766
+ params = self.omit(params, ['text', 'clientOrderId'])
4767
+ if clientOrderId[0] != 't':
4768
+ clientOrderId = 't-' + clientOrderId
4769
+ orderId = clientOrderId
4770
+ type, query = self.handle_market_type_and_params('fetchOrder', market, params)
4771
+ contract = (type == 'swap') or (type == 'future') or (type == 'option')
4772
+ request, requestParams = self.prepare_request(market, type, query) if contract else self.spot_order_prepare_request(market, trigger, query)
4773
+ request['order_id'] = str(orderId)
4774
+ return [request, requestParams]
4775
+
4276
4776
  def fetch_order(self, id: str, symbol: Str = None, params={}):
4277
4777
  """
4278
4778
  Retrieves information on an order
4279
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order
4280
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-2
4281
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-3
4282
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-4
4779
+
4780
+ https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order
4781
+ https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-2
4782
+ https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-3
4783
+ https://www.gate.io/docs/developers/apiv4/en/#get-a-single-order-4
4784
+
4283
4785
  :param str id: Order id
4284
4786
  :param str symbol: Unified market symbol, *required for spot and margin*
4285
4787
  :param dict [params]: Parameters specified by the exchange api
4286
- :param bool [params.stop]: True if the order being fetched is a trigger order
4788
+ :param bool [params.trigger]: True if the order being fetched is a trigger order
4287
4789
  :param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
4288
4790
  :param str [params.type]: 'spot', 'swap', or 'future', if not provided self.options['defaultMarginMode'] is used
4289
4791
  :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
4792
+ :param bool [params.unifiedAccount]: set to True for fetching a unified account order
4290
4793
  :returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4291
4794
  """
4292
4795
  self.load_markets()
4293
- stop = self.safe_value_2(params, 'is_stop_order', 'stop', False)
4294
- params = self.omit(params, ['is_stop_order', 'stop'])
4295
- clientOrderId = self.safe_string_2(params, 'text', 'clientOrderId')
4296
- orderId = id
4297
- if clientOrderId is not None:
4298
- params = self.omit(params, ['text', 'clientOrderId'])
4299
- if clientOrderId[0] != 't':
4300
- clientOrderId = 't-' + clientOrderId
4301
- orderId = clientOrderId
4796
+ self.load_unified_status()
4302
4797
  market = None if (symbol is None) else self.market(symbol)
4303
- type, query = self.handle_market_type_and_params('fetchOrder', market, params)
4304
- contract = (type == 'swap') or (type == 'future') or (type == 'option')
4305
- request, requestParams = self.prepare_request(market, type, query) if contract else self.spot_order_prepare_request(market, stop, query)
4306
- request['order_id'] = orderId
4798
+ result = self.handle_market_type_and_params('fetchOrder', market, params)
4799
+ type = self.safe_string(result, 0)
4800
+ trigger = self.safe_bool_n(params, ['trigger', 'is_stop_order', 'stop'], False)
4801
+ request, requestParams = self.fetch_order_request(id, symbol, params)
4307
4802
  response = None
4308
4803
  if type == 'spot' or type == 'margin':
4309
- if stop:
4804
+ if trigger:
4310
4805
  response = self.privateSpotGetPriceOrdersOrderId(self.extend(request, requestParams))
4311
4806
  else:
4312
4807
  response = self.privateSpotGetOrdersOrderId(self.extend(request, requestParams))
4313
4808
  elif type == 'swap':
4314
- if stop:
4809
+ if trigger:
4315
4810
  response = self.privateFuturesGetSettlePriceOrdersOrderId(self.extend(request, requestParams))
4316
4811
  else:
4317
4812
  response = self.privateFuturesGetSettleOrdersOrderId(self.extend(request, requestParams))
4318
4813
  elif type == 'future':
4319
- if stop:
4814
+ if trigger:
4320
4815
  response = self.privateDeliveryGetSettlePriceOrdersOrderId(self.extend(request, requestParams))
4321
4816
  else:
4322
4817
  response = self.privateDeliveryGetSettleOrdersOrderId(self.extend(request, requestParams))
@@ -4329,14 +4824,18 @@ class gate(Exchange, ImplicitAPI):
4329
4824
  def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
4330
4825
  """
4331
4826
  fetch all unfilled currently open orders
4332
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-open-orders
4827
+
4828
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-open-orders
4829
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-running-auto-order-list
4830
+
4333
4831
  :param str symbol: unified market symbol
4334
4832
  :param int [since]: the earliest time in ms to fetch open orders for
4335
4833
  :param int [limit]: the maximum number of open orders structures to retrieve
4336
4834
  :param dict [params]: extra parameters specific to the exchange API endpoint
4337
- :param bool [params.stop]: True for fetching stop orders
4835
+ :param bool [params.trigger]: True for fetching trigger orders
4338
4836
  :param str [params.type]: spot, margin, swap or future, if not provided self.options['defaultType'] is used
4339
4837
  :param str [params.marginMode]: 'cross' or 'isolated' - marginMode for type='margin', if not provided self.options['defaultMarginMode'] is used
4838
+ :param bool [params.unifiedAccount]: set to True for fetching unified account orders
4340
4839
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4341
4840
  """
4342
4841
  return self.fetch_orders_by_status('open', symbol, since, limit, params)
@@ -4344,58 +4843,115 @@ class gate(Exchange, ImplicitAPI):
4344
4843
  def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
4345
4844
  """
4346
4845
  fetches information on multiple closed orders made by the user
4347
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-orders
4348
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-running-auto-order-list
4349
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-futures-orders
4350
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-auto-orders
4351
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-futures-orders-2
4352
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-auto-orders-2
4353
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-options-orders
4846
+
4847
+ https://www.gate.io/docs/developers/apiv4/en/#list-orders
4848
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-running-auto-order-list
4849
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-orders
4850
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-auto-orders
4851
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-orders-2
4852
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-auto-orders-2
4853
+ https://www.gate.io/docs/developers/apiv4/en/#list-options-orders
4854
+ https://www.gate.io/docs/developers/apiv4/en/#list-futures-orders-by-time-range
4855
+
4354
4856
  :param str symbol: unified market symbol of the market orders were made in
4355
4857
  :param int [since]: the earliest time in ms to fetch orders for
4356
4858
  :param int [limit]: the maximum number of order structures to retrieve
4357
4859
  :param dict [params]: extra parameters specific to the exchange API endpoint
4358
- :param bool [params.stop]: True for fetching stop orders
4860
+ :param bool [params.trigger]: True for fetching trigger orders
4359
4861
  :param str [params.type]: spot, swap or future, if not provided self.options['defaultType'] is used
4360
4862
  :param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
4863
+ :param boolean [params.historical]: *swap only* True for using historical endpoint
4864
+ :param bool [params.unifiedAccount]: set to True for fetching unified account orders
4361
4865
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4362
4866
  """
4363
- return self.fetch_orders_by_status('finished', symbol, since, limit, params)
4364
-
4365
- def fetch_orders_by_status(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4366
4867
  self.load_markets()
4868
+ self.load_unified_status()
4869
+ until = self.safe_integer(params, 'until')
4870
+ market = None
4871
+ if symbol is not None:
4872
+ market = self.market(symbol)
4873
+ symbol = market['symbol']
4874
+ res = self.handle_market_type_and_params('fetchClosedOrders', market, params)
4875
+ type = self.safe_string(res, 0)
4876
+ useHistorical = False
4877
+ useHistorical, params = self.handle_option_and_params(params, 'fetchClosedOrders', 'historical', False)
4878
+ if not useHistorical and ((since is None and until is None) or (type != 'swap')):
4879
+ return self.fetch_orders_by_status('finished', symbol, since, limit, params)
4880
+ params = self.omit(params, 'type')
4881
+ request = {}
4882
+ request, params = self.prepare_request(market, type, params)
4883
+ if since is not None:
4884
+ request['from'] = self.parse_to_int(since / 1000)
4885
+ if until is not None:
4886
+ params = self.omit(params, 'until')
4887
+ request['to'] = self.parse_to_int(until / 1000)
4888
+ if limit is not None:
4889
+ request['limit'] = limit
4890
+ response = self.privateFuturesGetSettleOrdersTimerange(self.extend(request, params))
4891
+ return self.parse_orders(response, market, since, limit)
4892
+
4893
+ def prepare_orders_by_status_request(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4367
4894
  market = None
4368
4895
  if symbol is not None:
4369
4896
  market = self.market(symbol)
4370
4897
  symbol = market['symbol']
4371
- stop = self.safe_value(params, 'stop')
4372
- params = self.omit(params, 'stop')
4373
- type, query = self.handle_market_type_and_params('fetchOrdersByStatus', market, params)
4898
+ trigger: Bool = None
4899
+ trigger, params = self.handle_param_bool_2(params, 'trigger', 'stop')
4900
+ type: Str = None
4901
+ type, params = self.handle_market_type_and_params('fetchOrdersByStatus', market, params)
4374
4902
  spot = (type == 'spot') or (type == 'margin')
4375
- request, requestParams = self.multi_order_spot_prepare_request(market, stop, query) if spot else self.prepare_request(market, type, query)
4903
+ request: dict = {}
4904
+ request, params = self.multi_order_spot_prepare_request(market, trigger, params) if spot else self.prepare_request(market, type, params)
4905
+ if spot and trigger:
4906
+ request = self.omit(request, 'account')
4376
4907
  if status == 'closed':
4377
4908
  status = 'finished'
4378
4909
  request['status'] = status
4379
4910
  if limit is not None:
4380
4911
  request['limit'] = limit
4381
- if since is not None and spot:
4382
- request['from'] = self.parse_to_int(since / 1000)
4383
- openSpotOrders = spot and (status == 'open') and not stop
4912
+ if spot:
4913
+ if since is not None:
4914
+ request['from'] = self.parse_to_int(since / 1000)
4915
+ until = self.safe_integer(params, 'until')
4916
+ if until is not None:
4917
+ params = self.omit(params, 'until')
4918
+ request['to'] = self.parse_to_int(until / 1000)
4919
+ lastId, finalParams = self.handle_param_string_2(params, 'lastId', 'last_id')
4920
+ if lastId is not None:
4921
+ request['last_id'] = lastId
4922
+ return [request, finalParams]
4923
+
4924
+ def fetch_orders_by_status(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4925
+ self.load_markets()
4926
+ self.load_unified_status()
4927
+ market = None
4928
+ if symbol is not None:
4929
+ market = self.market(symbol)
4930
+ symbol = market['symbol']
4931
+ # don't omit here, omits done in prepareOrdersByStatusRequest
4932
+ trigger: Bool = self.safe_bool_2(params, 'trigger', 'stop')
4933
+ res = self.handle_market_type_and_params('fetchOrdersByStatus', market, params)
4934
+ type = self.safe_string(res, 0)
4935
+ request, requestParams = self.prepare_orders_by_status_request(status, symbol, since, limit, params)
4936
+ spot = (type == 'spot') or (type == 'margin')
4937
+ openStatus = (status == 'open')
4938
+ openSpotOrders = spot and openStatus and not trigger
4384
4939
  response = None
4385
- if type == 'spot' or type == 'margin':
4386
- if openSpotOrders:
4387
- response = self.privateSpotGetOpenOrders(self.extend(request, requestParams))
4388
- elif stop:
4389
- response = self.privateSpotGetPriceOrders(self.extend(request, requestParams))
4940
+ if spot:
4941
+ if not trigger:
4942
+ if openStatus:
4943
+ response = self.privateSpotGetOpenOrders(self.extend(request, requestParams))
4944
+ else:
4945
+ response = self.privateSpotGetOrders(self.extend(request, requestParams))
4390
4946
  else:
4391
- response = self.privateSpotGetOrders(self.extend(request, requestParams))
4947
+ response = self.privateSpotGetPriceOrders(self.extend(request, requestParams))
4392
4948
  elif type == 'swap':
4393
- if stop:
4949
+ if trigger:
4394
4950
  response = self.privateFuturesGetSettlePriceOrders(self.extend(request, requestParams))
4395
4951
  else:
4396
4952
  response = self.privateFuturesGetSettleOrders(self.extend(request, requestParams))
4397
4953
  elif type == 'future':
4398
- if stop:
4954
+ if trigger:
4399
4955
  response = self.privateDeliveryGetSettlePriceOrders(self.extend(request, requestParams))
4400
4956
  else:
4401
4957
  response = self.privateDeliveryGetSettleOrders(self.extend(request, requestParams))
@@ -4475,7 +5031,7 @@ class gate(Exchange, ImplicitAPI):
4475
5031
  # }
4476
5032
  # ]
4477
5033
  #
4478
- # spot stop
5034
+ # spot trigger
4479
5035
  #
4480
5036
  # [
4481
5037
  # {
@@ -4561,36 +5117,40 @@ class gate(Exchange, ImplicitAPI):
4561
5117
  def cancel_order(self, id: str, symbol: Str = None, params={}):
4562
5118
  """
4563
5119
  Cancels an open order
4564
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order
4565
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order-2
4566
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order-3
4567
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order-4
5120
+
5121
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order
5122
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order-2
5123
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order-3
5124
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-single-order-4
5125
+
4568
5126
  :param str id: Order id
4569
5127
  :param str symbol: Unified market symbol
4570
5128
  :param dict [params]: Parameters specified by the exchange api
4571
- :param bool [params.stop]: True if the order to be cancelled is a trigger order
5129
+ :param bool [params.trigger]: True if the order to be cancelled is a trigger order
5130
+ :param bool [params.unifiedAccount]: set to True for canceling unified account orders
4572
5131
  :returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4573
5132
  """
4574
5133
  self.load_markets()
5134
+ self.load_unified_status()
4575
5135
  market = None if (symbol is None) else self.market(symbol)
4576
- stop = self.safe_value_2(params, 'is_stop_order', 'stop', False)
4577
- params = self.omit(params, ['is_stop_order', 'stop'])
5136
+ trigger = self.safe_bool_n(params, ['is_stop_order', 'stop', 'trigger'], False)
5137
+ params = self.omit(params, ['is_stop_order', 'stop', 'trigger'])
4578
5138
  type, query = self.handle_market_type_and_params('cancelOrder', market, params)
4579
- request, requestParams = self.spot_order_prepare_request(market, stop, query) if (type == 'spot' or type == 'margin') else self.prepare_request(market, type, query)
5139
+ request, requestParams = self.spot_order_prepare_request(market, trigger, query) if (type == 'spot' or type == 'margin') else self.prepare_request(market, type, query)
4580
5140
  request['order_id'] = id
4581
5141
  response = None
4582
5142
  if type == 'spot' or type == 'margin':
4583
- if stop:
5143
+ if trigger:
4584
5144
  response = self.privateSpotDeletePriceOrdersOrderId(self.extend(request, requestParams))
4585
5145
  else:
4586
5146
  response = self.privateSpotDeleteOrdersOrderId(self.extend(request, requestParams))
4587
5147
  elif type == 'swap':
4588
- if stop:
5148
+ if trigger:
4589
5149
  response = self.privateFuturesDeleteSettlePriceOrdersOrderId(self.extend(request, requestParams))
4590
5150
  else:
4591
5151
  response = self.privateFuturesDeleteSettleOrdersOrderId(self.extend(request, requestParams))
4592
5152
  elif type == 'future':
4593
- if stop:
5153
+ if trigger:
4594
5154
  response = self.privateDeliveryDeleteSettlePriceOrdersOrderId(self.extend(request, requestParams))
4595
5155
  else:
4596
5156
  response = self.privateDeliveryDeleteSettleOrdersOrderId(self.extend(request, requestParams))
@@ -4681,36 +5241,122 @@ class gate(Exchange, ImplicitAPI):
4681
5241
  #
4682
5242
  return self.parse_order(response, market)
4683
5243
 
5244
+ def cancel_orders(self, ids: List[str], symbol: Str = None, params={}):
5245
+ """
5246
+ cancel multiple orders
5247
+
5248
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-batch-of-orders-with-an-id-list
5249
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-batch-of-orders-with-an-id-list-2
5250
+
5251
+ :param str[] ids: order ids
5252
+ :param str symbol: unified symbol of the market the order was made in
5253
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5254
+ :param bool [params.unifiedAccount]: set to True for canceling unified account orders
5255
+ :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
5256
+ """
5257
+ self.load_markets()
5258
+ self.load_unified_status()
5259
+ market = None
5260
+ if symbol is not None:
5261
+ market = self.market(symbol)
5262
+ type = None
5263
+ defaultSettle = 'usdt' if (market is None) else market['settle']
5264
+ settle = self.safe_string_lower(params, 'settle', defaultSettle)
5265
+ type, params = self.handle_market_type_and_params('cancelOrders', market, params)
5266
+ isSpot = (type == 'spot')
5267
+ if isSpot and (symbol is None):
5268
+ raise ArgumentsRequired(self.id + ' cancelOrders requires a symbol argument for spot markets')
5269
+ if isSpot:
5270
+ ordersRequests = []
5271
+ for i in range(0, len(ids)):
5272
+ id = ids[i]
5273
+ orderItem: dict = {
5274
+ 'id': id,
5275
+ 'symbol': symbol,
5276
+ }
5277
+ ordersRequests.append(orderItem)
5278
+ return self.cancel_orders_for_symbols(ordersRequests, params)
5279
+ request = {
5280
+ 'settle': settle,
5281
+ }
5282
+ finalList = [request] # hacky but needs to be done here
5283
+ for i in range(0, len(ids)):
5284
+ finalList.append(ids[i])
5285
+ response = self.privateFuturesPostSettleBatchCancelOrders(finalList)
5286
+ return self.parse_orders(response)
5287
+
5288
+ def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
5289
+ """
5290
+ cancel multiple orders for multiple symbols
5291
+
5292
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-a-batch-of-orders-with-an-id-list
5293
+
5294
+ :param CancellationRequest[] orders: list of order ids with symbol, example [{"id": "a", "symbol": "BTC/USDT"}, {"id": "b", "symbol": "ETH/USDT"}]
5295
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5296
+ :param str[] [params.clientOrderIds]: client order ids
5297
+ :param bool [params.unifiedAccount]: set to True for canceling unified account orders
5298
+ :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
5299
+ """
5300
+ self.load_markets()
5301
+ self.load_unified_status()
5302
+ ordersRequests = []
5303
+ for i in range(0, len(orders)):
5304
+ order = orders[i]
5305
+ symbol = self.safe_string(order, 'symbol')
5306
+ market = self.market(symbol)
5307
+ if not market['spot']:
5308
+ raise NotSupported(self.id + ' cancelOrdersForSymbols() supports only spot markets')
5309
+ id = self.safe_string(order, 'id')
5310
+ orderItem: dict = {
5311
+ 'id': id,
5312
+ 'currency_pair': market['id'],
5313
+ }
5314
+ ordersRequests.append(orderItem)
5315
+ response = self.privateSpotPostCancelBatchOrders(ordersRequests)
5316
+ #
5317
+ # [
5318
+ # {
5319
+ # "currency_pair": "BTC_USDT",
5320
+ # "id": "123456"
5321
+ # }
5322
+ # ]
5323
+ #
5324
+ return self.parse_orders(response)
5325
+
4684
5326
  def cancel_all_orders(self, symbol: Str = None, params={}):
4685
5327
  """
4686
5328
  cancel all open orders
4687
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-in-specified-currency-pair
4688
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-matched
4689
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-matched-2
4690
- :see: https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-matched-3
5329
+
5330
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-in-specified-currency-pair
5331
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-matched
5332
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-matched-2
5333
+ https://www.gate.io/docs/developers/apiv4/en/#cancel-all-open-orders-matched-3
5334
+
4691
5335
  :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
4692
5336
  :param dict [params]: extra parameters specific to the exchange API endpoint
5337
+ :param bool [params.unifiedAccount]: set to True for canceling unified account orders
4693
5338
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4694
5339
  """
4695
5340
  self.load_markets()
5341
+ self.load_unified_status()
4696
5342
  market = None if (symbol is None) else self.market(symbol)
4697
- stop = self.safe_bool_2(params, 'stop', 'trigger')
5343
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
4698
5344
  params = self.omit(params, ['stop', 'trigger'])
4699
5345
  type, query = self.handle_market_type_and_params('cancelAllOrders', market, params)
4700
- request, requestParams = self.multi_order_spot_prepare_request(market, stop, query) if (type == 'spot') else self.prepare_request(market, type, query)
5346
+ request, requestParams = self.multi_order_spot_prepare_request(market, trigger, query) if (type == 'spot') else self.prepare_request(market, type, query)
4701
5347
  response = None
4702
5348
  if type == 'spot' or type == 'margin':
4703
- if stop:
5349
+ if trigger:
4704
5350
  response = self.privateSpotDeletePriceOrders(self.extend(request, requestParams))
4705
5351
  else:
4706
5352
  response = self.privateSpotDeleteOrders(self.extend(request, requestParams))
4707
5353
  elif type == 'swap':
4708
- if stop:
5354
+ if trigger:
4709
5355
  response = self.privateFuturesDeleteSettlePriceOrders(self.extend(request, requestParams))
4710
5356
  else:
4711
5357
  response = self.privateFuturesDeleteSettleOrders(self.extend(request, requestParams))
4712
5358
  elif type == 'future':
4713
- if stop:
5359
+ if trigger:
4714
5360
  response = self.privateDeliveryDeleteSettlePriceOrders(self.extend(request, requestParams))
4715
5361
  else:
4716
5362
  response = self.privateDeliveryDeleteSettleOrders(self.extend(request, requestParams))
@@ -4751,7 +5397,9 @@ class gate(Exchange, ImplicitAPI):
4751
5397
  def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
4752
5398
  """
4753
5399
  transfer currency internally between wallets on the same account
4754
- :see: https://www.gate.io/docs/developers/apiv4/en/#transfer-between-trading-accounts
5400
+
5401
+ https://www.gate.io/docs/developers/apiv4/en/#transfer-between-trading-accounts
5402
+
4755
5403
  :param str code: unified currency code for currency being transferred
4756
5404
  :param float amount: the amount of currency to transfer
4757
5405
  :param str fromAccount: the account to transfer currency from
@@ -4824,11 +5472,13 @@ class gate(Exchange, ImplicitAPI):
4824
5472
  'info': transfer,
4825
5473
  }
4826
5474
 
4827
- def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
5475
+ def set_leverage(self, leverage: int, symbol: Str = None, params={}):
4828
5476
  """
4829
5477
  set the level of leverage for a market
4830
- :see: https://www.gate.io/docs/developers/apiv4/en/#update-position-leverage
4831
- :see: https://www.gate.io/docs/developers/apiv4/en/#update-position-leverage-2
5478
+
5479
+ https://www.gate.io/docs/developers/apiv4/en/#update-position-leverage
5480
+ https://www.gate.io/docs/developers/apiv4/en/#update-position-leverage-2
5481
+
4832
5482
  :param float leverage: the rate of leverage
4833
5483
  :param str symbol: unified market symbol
4834
5484
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -5029,9 +5679,11 @@ class gate(Exchange, ImplicitAPI):
5029
5679
  def fetch_position(self, symbol: str, params={}):
5030
5680
  """
5031
5681
  fetch data on an open contract position
5032
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-single-position
5033
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-single-position-2
5034
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-specified-contract-position
5682
+
5683
+ https://www.gate.io/docs/developers/apiv4/en/#get-single-position
5684
+ https://www.gate.io/docs/developers/apiv4/en/#get-single-position-2
5685
+ https://www.gate.io/docs/developers/apiv4/en/#get-specified-contract-position
5686
+
5035
5687
  :param str symbol: unified market symbol of the market the position is held in
5036
5688
  :param dict [params]: extra parameters specific to the exchange API endpoint
5037
5689
  :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
@@ -5108,12 +5760,14 @@ class gate(Exchange, ImplicitAPI):
5108
5760
  #
5109
5761
  return self.parse_position(response, market)
5110
5762
 
5111
- def fetch_positions(self, symbols: Strings = None, params={}):
5763
+ def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
5112
5764
  """
5113
5765
  fetch all open positions
5114
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-positions-of-a-user
5115
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-positions-of-a-user-2
5116
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-user-s-positions-of-specified-underlying
5766
+
5767
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-positions-of-a-user
5768
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-positions-of-a-user-2
5769
+ https://www.gate.io/docs/developers/apiv4/en/#list-user-s-positions-of-specified-underlying
5770
+
5117
5771
  :param str[]|None symbols: Not used by gate, but parsed internally by CCXT
5118
5772
  :param dict [params]: extra parameters specific to the exchange API endpoint
5119
5773
  :param str [params.settle]: 'btc' or 'usdt' - settle currency for perpetual swap and future - default="usdt" for swap and "btc" for future
@@ -5211,8 +5865,10 @@ class gate(Exchange, ImplicitAPI):
5211
5865
  def fetch_leverage_tiers(self, symbols: Strings = None, params={}) -> LeverageTiers:
5212
5866
  """
5213
5867
  retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
5214
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts
5215
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts-2
5868
+
5869
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts
5870
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts-2
5871
+
5216
5872
  :param str[] [symbols]: list of unified market symbols
5217
5873
  :param dict [params]: extra parameters specific to the exchange API endpoint
5218
5874
  :returns dict: a dictionary of `leverage tiers structures <https://docs.ccxt.com/#/?id=leverage-tiers-structure>`, indexed by market symbols
@@ -5326,7 +5982,9 @@ class gate(Exchange, ImplicitAPI):
5326
5982
  def fetch_market_leverage_tiers(self, symbol: str, params={}) -> List[LeverageTier]:
5327
5983
  """
5328
5984
  retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes for a single market
5329
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-risk-limit-tiers
5985
+
5986
+ https://www.gate.io/docs/developers/apiv4/en/#list-risk-limit-tiers
5987
+
5330
5988
  :param str symbol: unified market symbol
5331
5989
  :param dict [params]: extra parameters specific to the exchange API endpoint
5332
5990
  :returns dict: a `leverage tiers structure <https://docs.ccxt.com/#/?id=leverage-tiers-structure>`
@@ -5351,7 +6009,8 @@ class gate(Exchange, ImplicitAPI):
5351
6009
  #
5352
6010
  return self.parse_market_leverage_tiers(response, market)
5353
6011
 
5354
- def parse_emulated_leverage_tiers(self, info, market=None):
6012
+ def parse_emulated_leverage_tiers(self, info, market=None) -> List[LeverageTier]:
6013
+ marketId = self.safe_string(info, 'name')
5355
6014
  maintenanceMarginUnit = self.safe_string(info, 'maintenance_rate') # '0.005',
5356
6015
  leverageMax = self.safe_string(info, 'leverage_max') # '100',
5357
6016
  riskLimitStep = self.safe_string(info, 'risk_limit_step') # '1000000',
@@ -5365,6 +6024,7 @@ class gate(Exchange, ImplicitAPI):
5365
6024
  cap = Precise.string_add(floor, riskLimitStep)
5366
6025
  tiers.append({
5367
6026
  'tier': self.parse_number(Precise.string_div(cap, riskLimitStep)),
6027
+ 'symbol': self.safe_symbol(marketId, market, None, 'contract'),
5368
6028
  'currency': self.safe_string(market, 'settle'),
5369
6029
  'minNotional': self.parse_number(floor),
5370
6030
  'maxNotional': self.parse_number(cap),
@@ -5398,6 +6058,7 @@ class gate(Exchange, ImplicitAPI):
5398
6058
  maxNotional = self.safe_number(item, 'risk_limit')
5399
6059
  tiers.append({
5400
6060
  'tier': self.sum(i, 1),
6061
+ 'symbol': market['symbol'],
5401
6062
  'currency': market['base'],
5402
6063
  'minNotional': minNotional,
5403
6064
  'maxNotional': maxNotional,
@@ -5411,7 +6072,9 @@ class gate(Exchange, ImplicitAPI):
5411
6072
  def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
5412
6073
  """
5413
6074
  repay borrowed margin and interest
5414
- :see: https://www.gate.io/docs/apiv4/en/#repay-a-loan
6075
+
6076
+ https://www.gate.io/docs/apiv4/en/#repay-a-loan
6077
+
5415
6078
  :param str symbol: unified market symbol
5416
6079
  :param str code: unified currency code of the currency to repay
5417
6080
  :param float amount: the amount to repay
@@ -5438,48 +6101,61 @@ class gate(Exchange, ImplicitAPI):
5438
6101
  def repay_cross_margin(self, code: str, amount, params={}):
5439
6102
  """
5440
6103
  repay cross margin borrowed margin and interest
5441
- :see: https://www.gate.io/docs/developers/apiv4/en/#cross-margin-repayments
6104
+
6105
+ https://www.gate.io/docs/developers/apiv4/en/#cross-margin-repayments
6106
+ https://www.gate.io/docs/developers/apiv4/en/#borrow-or-repay
6107
+
5442
6108
  :param str code: unified currency code of the currency to repay
5443
6109
  :param float amount: the amount to repay
5444
- :param str symbol: unified market symbol, required for isolated margin
5445
6110
  :param dict [params]: extra parameters specific to the exchange API endpoint
5446
6111
  :param str [params.mode]: 'all' or 'partial' payment mode, extra parameter required for isolated margin
5447
6112
  :param str [params.id]: '34267567' loan id, extra parameter required for isolated margin
6113
+ :param boolean [params.unifiedAccount]: set to True for repaying in the unified account
5448
6114
  :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
5449
6115
  """
5450
6116
  self.load_markets()
6117
+ self.load_unified_status()
5451
6118
  currency = self.currency(code)
5452
6119
  request: dict = {
5453
6120
  'currency': currency['id'].upper(), # todo: currencies have network-junctions
5454
6121
  'amount': self.currency_to_precision(code, amount),
5455
6122
  }
5456
- response = self.privateMarginPostCrossRepayments(self.extend(request, params))
5457
- #
5458
- # [
5459
- # {
5460
- # "id": "17",
5461
- # "create_time": 1620381696159,
5462
- # "update_time": 1620381696159,
5463
- # "currency": "EOS",
5464
- # "amount": "110.553635",
5465
- # "text": "web",
5466
- # "status": 2,
5467
- # "repaid": "110.506649705159",
5468
- # "repaid_interest": "0.046985294841",
5469
- # "unpaid_interest": "0.0000074393366667"
5470
- # }
5471
- # ]
5472
- #
5473
- response = self.safe_value(response, 0)
6123
+ isUnifiedAccount = False
6124
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'repayCrossMargin', 'unifiedAccount')
6125
+ response = None
6126
+ if isUnifiedAccount:
6127
+ request['type'] = 'repay'
6128
+ response = self.privateUnifiedPostLoans(self.extend(request, params))
6129
+ else:
6130
+ response = self.privateMarginPostCrossRepayments(self.extend(request, params))
6131
+ response = self.safe_dict(response, 0)
6132
+ #
6133
+ # [
6134
+ # {
6135
+ # "id": "17",
6136
+ # "create_time": 1620381696159,
6137
+ # "update_time": 1620381696159,
6138
+ # "currency": "EOS",
6139
+ # "amount": "110.553635",
6140
+ # "text": "web",
6141
+ # "status": 2,
6142
+ # "repaid": "110.506649705159",
6143
+ # "repaid_interest": "0.046985294841",
6144
+ # "unpaid_interest": "0.0000074393366667"
6145
+ # }
6146
+ # ]
6147
+ #
5474
6148
  return self.parse_margin_loan(response, currency)
5475
6149
 
5476
6150
  def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
5477
6151
  """
5478
6152
  create a loan to borrow margin
5479
- :see: https://www.gate.io/docs/developers/apiv4/en/#marginuni
6153
+
6154
+ https://www.gate.io/docs/developers/apiv4/en/#marginuni
6155
+
6156
+ :param str symbol: unified market symbol, required for isolated margin
5480
6157
  :param str code: unified currency code of the currency to borrow
5481
6158
  :param float amount: the amount to borrow
5482
- :param str symbol: unified market symbol, required for isolated margin
5483
6159
  :param dict [params]: extra parameters specific to the exchange API endpoint
5484
6160
  :param str [params.rate]: '0.0002' or '0.002' extra parameter required for isolated margin
5485
6161
  :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
@@ -5519,35 +6195,46 @@ class gate(Exchange, ImplicitAPI):
5519
6195
  def borrow_cross_margin(self, code: str, amount: float, params={}):
5520
6196
  """
5521
6197
  create a loan to borrow margin
5522
- :see: https://www.gate.io/docs/apiv4/en/#create-a-cross-margin-borrow-loan
6198
+
6199
+ https://www.gate.io/docs/apiv4/en/#create-a-cross-margin-borrow-loan
6200
+ https://www.gate.io/docs/developers/apiv4/en/#borrow-or-repay
6201
+
5523
6202
  :param str code: unified currency code of the currency to borrow
5524
6203
  :param float amount: the amount to borrow
5525
- :param str symbol: unified market symbol, required for isolated margin
5526
6204
  :param dict [params]: extra parameters specific to the exchange API endpoint
5527
6205
  :param str [params.rate]: '0.0002' or '0.002' extra parameter required for isolated margin
6206
+ :param boolean [params.unifiedAccount]: set to True for borrowing in the unified account
5528
6207
  :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
5529
6208
  """
5530
6209
  self.load_markets()
6210
+ self.load_unified_status()
5531
6211
  currency = self.currency(code)
5532
6212
  request: dict = {
5533
6213
  'currency': currency['id'].upper(), # todo: currencies have network-junctions
5534
6214
  'amount': self.currency_to_precision(code, amount),
5535
6215
  }
5536
- response = self.privateMarginPostCrossLoans(self.extend(request, params))
5537
- #
5538
- # {
5539
- # "id": "17",
5540
- # "create_time": 1620381696159,
5541
- # "update_time": 1620381696159,
5542
- # "currency": "EOS",
5543
- # "amount": "110.553635",
5544
- # "text": "web",
5545
- # "status": 2,
5546
- # "repaid": "110.506649705159",
5547
- # "repaid_interest": "0.046985294841",
5548
- # "unpaid_interest": "0.0000074393366667"
5549
- # }
5550
- #
6216
+ isUnifiedAccount = False
6217
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'borrowCrossMargin', 'unifiedAccount')
6218
+ response = None
6219
+ if isUnifiedAccount:
6220
+ request['type'] = 'borrow'
6221
+ response = self.privateUnifiedPostLoans(self.extend(request, params))
6222
+ else:
6223
+ response = self.privateMarginPostCrossLoans(self.extend(request, params))
6224
+ #
6225
+ # {
6226
+ # "id": "17",
6227
+ # "create_time": 1620381696159,
6228
+ # "update_time": 1620381696159,
6229
+ # "currency": "EOS",
6230
+ # "amount": "110.553635",
6231
+ # "text": "web",
6232
+ # "status": 2,
6233
+ # "repaid": "110.506649705159",
6234
+ # "repaid_interest": "0.046985294841",
6235
+ # "unpaid_interest": "0.0000074393366667"
6236
+ # }
6237
+ #
5551
6238
  return self.parse_margin_loan(response, currency)
5552
6239
 
5553
6240
  def parse_margin_loan(self, info, currency: Currency = None):
@@ -5603,11 +6290,91 @@ class gate(Exchange, ImplicitAPI):
5603
6290
  'info': info,
5604
6291
  }
5605
6292
 
6293
+ def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
6294
+ """
6295
+ fetch the interest owed by the user for borrowing currency for margin trading
6296
+
6297
+ https://www.gate.io/docs/developers/apiv4/en/#list-interest-records
6298
+ https://www.gate.io/docs/developers/apiv4/en/#interest-records-for-the-cross-margin-account
6299
+ https://www.gate.io/docs/developers/apiv4/en/#list-interest-records-2
6300
+
6301
+ :param str [code]: unified currency code
6302
+ :param str [symbol]: unified market symbol when fetching interest in isolated markets
6303
+ :param int [since]: the earliest time in ms to fetch borrow interest for
6304
+ :param int [limit]: the maximum number of structures to retrieve
6305
+ :param dict [params]: extra parameters specific to the exchange API endpoint
6306
+ :param boolean [params.unifiedAccount]: set to True for fetching borrow interest in the unified account
6307
+ :returns dict[]: a list of `borrow interest structures <https://docs.ccxt.com/#/?id=borrow-interest-structure>`
6308
+ """
6309
+ self.load_markets()
6310
+ self.load_unified_status()
6311
+ isUnifiedAccount = False
6312
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'fetchBorrowInterest', 'unifiedAccount')
6313
+ request: dict = {}
6314
+ request, params = self.handle_until_option('to', request, params)
6315
+ currency = None
6316
+ if code is not None:
6317
+ currency = self.currency(code)
6318
+ request['currency'] = currency['id']
6319
+ market = None
6320
+ if symbol is not None:
6321
+ market = self.market(symbol)
6322
+ if since is not None:
6323
+ request['from'] = since
6324
+ if limit is not None:
6325
+ request['limit'] = limit
6326
+ response = None
6327
+ marginMode = None
6328
+ marginMode, params = self.handle_margin_mode_and_params('fetchBorrowInterest', params, 'cross')
6329
+ if isUnifiedAccount:
6330
+ response = self.privateUnifiedGetInterestRecords(self.extend(request, params))
6331
+ elif marginMode == 'isolated':
6332
+ if market is not None:
6333
+ request['currency_pair'] = market['id']
6334
+ response = self.privateMarginGetUniInterestRecords(self.extend(request, params))
6335
+ elif marginMode == 'cross':
6336
+ response = self.privateMarginGetCrossInterestRecords(self.extend(request, params))
6337
+ interest = self.parse_borrow_interests(response, market)
6338
+ return self.filter_by_currency_since_limit(interest, code, since, limit)
6339
+
6340
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
6341
+ marketId = self.safe_string(info, 'currency_pair')
6342
+ market = self.safe_market(marketId, market)
6343
+ marginMode = 'isolated' if (marketId is not None) else 'cross'
6344
+ timestamp = self.safe_integer(info, 'create_time')
6345
+ return {
6346
+ 'info': info,
6347
+ 'symbol': self.safe_string(market, 'symbol'),
6348
+ 'currency': self.safe_currency_code(self.safe_string(info, 'currency')),
6349
+ 'interest': self.safe_number(info, 'interest'),
6350
+ 'interestRate': self.safe_number(info, 'actual_rate'),
6351
+ 'amountBorrowed': None,
6352
+ 'marginMode': marginMode,
6353
+ 'timestamp': timestamp,
6354
+ 'datetime': self.iso8601(timestamp),
6355
+ }
6356
+
6357
+ def nonce(self):
6358
+ return self.milliseconds() - self.options['timeDifference']
6359
+
5606
6360
  def sign(self, path, api=[], method='GET', params={}, headers=None, body=None):
5607
6361
  authentication = api[0] # public, private
5608
6362
  type = api[1] # spot, margin, future, delivery
5609
6363
  query = self.omit(params, self.extract_params(path))
5610
- if isinstance(params, list):
6364
+ containsSettle = path.find('settle') > -1
6365
+ if containsSettle and path.endswith('batch_cancel_orders'): # weird check to prevent $settle in php and converting {settle} to array(settle)
6366
+ # special case where we need to extract the settle from the path
6367
+ # but the body is an array of strings
6368
+ settle = self.safe_dict(params, 0)
6369
+ path = self.implode_params(path, settle)
6370
+ # remove the first element from params
6371
+ newParams = []
6372
+ anyParams = params
6373
+ for i in range(1, len(anyParams)):
6374
+ newParams.append(params[i])
6375
+ params = newParams
6376
+ query = newParams
6377
+ elif isinstance(params, list):
5611
6378
  # endpoints like createOrders use an array instead of an object
5612
6379
  # so we infer the settle from one of the elements
5613
6380
  # they have to be all the same so relying on the first one is fine
@@ -5637,6 +6404,9 @@ class gate(Exchange, ImplicitAPI):
5637
6404
  if (method == 'GET') or (method == 'DELETE') or requiresURLEncoding or (method == 'PATCH'):
5638
6405
  if query:
5639
6406
  queryString = self.urlencode(query)
6407
+ # https://github.com/ccxt/ccxt/issues/25570
6408
+ if queryString.find('currencies=') >= 0 and queryString.find('%2C') >= 0:
6409
+ queryString = queryString.replace('%2C', ',')
5640
6410
  url += '?' + queryString
5641
6411
  if method == 'PATCH':
5642
6412
  body = self.json(query)
@@ -5649,7 +6419,8 @@ class gate(Exchange, ImplicitAPI):
5649
6419
  body = self.json(query)
5650
6420
  bodyPayload = '' if (body is None) else body
5651
6421
  bodySignature = self.hash(self.encode(bodyPayload), 'sha512')
5652
- timestamp = self.seconds()
6422
+ nonce = self.nonce()
6423
+ timestamp = self.parse_to_int(nonce / 1000)
5653
6424
  timestampString = str(timestamp)
5654
6425
  signaturePath = '/api/' + self.version + entirePath
5655
6426
  payloadArray = [method.upper(), signaturePath, queryString, bodySignature, timestampString]
@@ -5725,8 +6496,10 @@ class gate(Exchange, ImplicitAPI):
5725
6496
  def reduce_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
5726
6497
  """
5727
6498
  remove margin from a position
5728
- :see: https://www.gate.io/docs/developers/apiv4/en/#update-position-margin
5729
- :see: https://www.gate.io/docs/developers/apiv4/en/#update-position-margin-2
6499
+
6500
+ https://www.gate.io/docs/developers/apiv4/en/#update-position-margin
6501
+ https://www.gate.io/docs/developers/apiv4/en/#update-position-margin-2
6502
+
5730
6503
  :param str symbol: unified market symbol
5731
6504
  :param float amount: the amount of margin to remove
5732
6505
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -5737,8 +6510,10 @@ class gate(Exchange, ImplicitAPI):
5737
6510
  def add_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
5738
6511
  """
5739
6512
  add margin
5740
- :see: https://www.gate.io/docs/developers/apiv4/en/#update-position-margin
5741
- :see: https://www.gate.io/docs/developers/apiv4/en/#update-position-margin-2
6513
+
6514
+ https://www.gate.io/docs/developers/apiv4/en/#update-position-margin
6515
+ https://www.gate.io/docs/developers/apiv4/en/#update-position-margin-2
6516
+
5742
6517
  :param str symbol: unified market symbol
5743
6518
  :param float amount: amount of margin to add
5744
6519
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -5749,7 +6524,9 @@ class gate(Exchange, ImplicitAPI):
5749
6524
  def fetch_open_interest_history(self, symbol: str, timeframe='5m', since: Int = None, limit: Int = None, params={}):
5750
6525
  """
5751
6526
  Retrieves the open interest of a currency
5752
- :see: https://www.gate.io/docs/developers/apiv4/en/#futures-stats
6527
+
6528
+ https://www.gate.io/docs/developers/apiv4/en/#futures-stats
6529
+
5753
6530
  :param str symbol: Unified CCXT market symbol
5754
6531
  :param str timeframe: "5m", "15m", "30m", "1h", "4h", "1d"
5755
6532
  :param int [since]: the time(ms) of the earliest record to retrieve unix timestamp
@@ -5797,7 +6574,7 @@ class gate(Exchange, ImplicitAPI):
5797
6574
  # ...
5798
6575
  # ]
5799
6576
  #
5800
- return self.parse_open_interests(response, market, since, limit)
6577
+ return self.parse_open_interests_history(response, market, since, limit)
5801
6578
 
5802
6579
  def parse_open_interest(self, interest, market: Market = None):
5803
6580
  #
@@ -5831,7 +6608,9 @@ class gate(Exchange, ImplicitAPI):
5831
6608
  def fetch_settlement_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5832
6609
  """
5833
6610
  fetches historical settlement records
5834
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-settlement-history-2
6611
+
6612
+ https://www.gate.io/docs/developers/apiv4/en/#list-settlement-history-2
6613
+
5835
6614
  :param str symbol: unified market symbol of the settlement history, required on gate
5836
6615
  :param int [since]: timestamp in ms
5837
6616
  :param int [limit]: number of records
@@ -5875,7 +6654,9 @@ class gate(Exchange, ImplicitAPI):
5875
6654
  def fetch_my_settlement_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5876
6655
  """
5877
6656
  fetches historical settlement records of the user
5878
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-my-options-settlements
6657
+
6658
+ https://www.gate.io/docs/developers/apiv4/en/#list-my-options-settlements
6659
+
5879
6660
  :param str symbol: unified market symbol of the settlement history
5880
6661
  :param int [since]: timestamp in ms
5881
6662
  :param int [limit]: number of records
@@ -5995,21 +6776,23 @@ class gate(Exchange, ImplicitAPI):
5995
6776
  result.append(self.parse_settlement(settlements[i], market))
5996
6777
  return result
5997
6778
 
5998
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
6779
+ def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
5999
6780
  """
6000
6781
  fetch the history of changes, actions done by the user or operations that altered the balance of the user
6001
- :see: https://www.gate.io/docs/developers/apiv4/en/#query-account-book
6002
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-margin-account-balance-change-history
6003
- :see: https://www.gate.io/docs/developers/apiv4/en/#query-account-book-2
6004
- :see: https://www.gate.io/docs/developers/apiv4/en/#query-account-book-3
6005
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-account-changing-history
6006
- :param str code: unified currency code
6782
+
6783
+ https://www.gate.io/docs/developers/apiv4/en/#query-account-book
6784
+ https://www.gate.io/docs/developers/apiv4/en/#list-margin-account-balance-change-history
6785
+ https://www.gate.io/docs/developers/apiv4/en/#query-account-book-2
6786
+ https://www.gate.io/docs/developers/apiv4/en/#query-account-book-3
6787
+ https://www.gate.io/docs/developers/apiv4/en/#list-account-changing-history
6788
+
6789
+ :param str [code]: unified currency code
6007
6790
  :param int [since]: timestamp in ms of the earliest ledger entry
6008
6791
  :param int [limit]: max number of ledger entries to return
6009
6792
  :param dict [params]: extra parameters specific to the exchange API endpoint
6010
6793
  :param int [params.until]: end time in ms
6011
- :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)
6012
- :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
6794
+ :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)
6795
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
6013
6796
  """
6014
6797
  self.load_markets()
6015
6798
  paginate = False
@@ -6099,7 +6882,7 @@ class gate(Exchange, ImplicitAPI):
6099
6882
  #
6100
6883
  return self.parse_ledger(response, currency, since, limit)
6101
6884
 
6102
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
6885
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
6103
6886
  #
6104
6887
  # spot
6105
6888
  #
@@ -6152,6 +6935,7 @@ class gate(Exchange, ImplicitAPI):
6152
6935
  else:
6153
6936
  direction = 'in'
6154
6937
  currencyId = self.safe_string(item, 'currency')
6938
+ currency = self.safe_currency(currencyId, currency)
6155
6939
  type = self.safe_string(item, 'type')
6156
6940
  rawTimestamp = self.safe_string(item, 'time')
6157
6941
  timestamp = None
@@ -6162,7 +6946,8 @@ class gate(Exchange, ImplicitAPI):
6162
6946
  balanceString = self.safe_string(item, 'balance')
6163
6947
  changeString = self.safe_string(item, 'change')
6164
6948
  before = self.parse_number(Precise.string_sub(balanceString, changeString))
6165
- return {
6949
+ return self.safe_ledger_entry({
6950
+ 'info': item,
6166
6951
  'id': self.safe_string(item, 'id'),
6167
6952
  'direction': direction,
6168
6953
  'account': None,
@@ -6177,8 +6962,7 @@ class gate(Exchange, ImplicitAPI):
6177
6962
  'after': self.safe_number(item, 'balance'),
6178
6963
  'status': None,
6179
6964
  'fee': None,
6180
- 'info': item,
6181
- }
6965
+ }, currency)
6182
6966
 
6183
6967
  def parse_ledger_entry_type(self, type):
6184
6968
  ledgerType: dict = {
@@ -6226,7 +7010,9 @@ class gate(Exchange, ImplicitAPI):
6226
7010
  def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
6227
7011
  """
6228
7012
  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
6229
- :see: https://www.gate.io/docs/developers/apiv4/en/#enable-or-disable-dual-mode
7013
+
7014
+ https://www.gate.io/docs/developers/apiv4/en/#enable-or-disable-dual-mode
7015
+
6230
7016
  :param bool hedged: set to True to enable dual mode
6231
7017
  :param str|None symbol: if passed, dual mode is set for all markets with the same settle currency
6232
7018
  :param dict params: extra parameters specific to the exchange API endpoint
@@ -6241,7 +7027,9 @@ class gate(Exchange, ImplicitAPI):
6241
7027
  def fetch_underlying_assets(self, params={}):
6242
7028
  """
6243
7029
  fetches the market ids of underlying assets for a specific contract market type
6244
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-underlyings
7030
+
7031
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-underlyings
7032
+
6245
7033
  :param dict [params]: exchange specific params
6246
7034
  :param str [params.type]: the contract market type, 'option', 'swap' or 'future', the default is 'option'
6247
7035
  :returns dict[]: a list of `underlying assets <https://docs.ccxt.com/#/?id=underlying-assets-structure>`
@@ -6274,7 +7062,9 @@ class gate(Exchange, ImplicitAPI):
6274
7062
  def fetch_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}):
6275
7063
  """
6276
7064
  retrieves the public liquidations of a trading pair
6277
- :see: https://www.gate.io/docs/developers/apiv4/en/#retrieve-liquidation-history
7065
+
7066
+ https://www.gate.io/docs/developers/apiv4/en/#retrieve-liquidation-history
7067
+
6278
7068
  :param str symbol: unified CCXT market symbol
6279
7069
  :param int [since]: the earliest time in ms to fetch liquidations for
6280
7070
  :param int [limit]: the maximum number of liquidation structures to retrieve
@@ -6313,9 +7103,11 @@ class gate(Exchange, ImplicitAPI):
6313
7103
  def fetch_my_liquidations(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6314
7104
  """
6315
7105
  retrieves the users liquidated positions
6316
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-liquidation-history
6317
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-liquidation-history-2
6318
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-user-s-liquidation-history-of-specified-underlying
7106
+
7107
+ https://www.gate.io/docs/developers/apiv4/en/#list-liquidation-history
7108
+ https://www.gate.io/docs/developers/apiv4/en/#list-liquidation-history-2
7109
+ https://www.gate.io/docs/developers/apiv4/en/#list-user-s-liquidation-history-of-specified-underlying
7110
+
6319
7111
  :param str symbol: unified CCXT market symbol
6320
7112
  :param int [since]: the earliest time in ms to fetch liquidations for
6321
7113
  :param int [limit]: the maximum number of liquidation structures to retrieve
@@ -6433,12 +7225,27 @@ class gate(Exchange, ImplicitAPI):
6433
7225
  quoteValueString = self.safe_string(liquidation, 'pnl')
6434
7226
  if quoteValueString is None:
6435
7227
  quoteValueString = Precise.string_mul(baseValueString, priceString)
7228
+ # --- derive side ---
7229
+ # 1) options payload has explicit 'side': 'long' | 'short'
7230
+ optPos = self.safe_string_lower(liquidation, 'side')
7231
+ side: Str = None
7232
+ if optPos == 'long':
7233
+ side = 'buy'
7234
+ elif optPos == 'short':
7235
+ side = 'sell'
7236
+ else:
7237
+ if size is not None: # 2) futures/perpetual(and fallback for options): infer from size
7238
+ if Precise.string_gt(size, '0'):
7239
+ side = 'buy'
7240
+ elif Precise.string_lt(size, '0'):
7241
+ side = 'sell'
6436
7242
  return self.safe_liquidation({
6437
7243
  'info': liquidation,
6438
7244
  'symbol': self.safe_symbol(marketId, market),
6439
7245
  'contracts': self.parse_number(contractsString),
6440
7246
  'contractSize': self.parse_number(contractSizeString),
6441
7247
  'price': self.parse_number(priceString),
7248
+ 'side': side,
6442
7249
  'baseValue': self.parse_number(baseValueString),
6443
7250
  'quoteValue': self.parse_number(Precise.string_abs(quoteValueString)),
6444
7251
  'timestamp': timestamp,
@@ -6448,7 +7255,9 @@ class gate(Exchange, ImplicitAPI):
6448
7255
  def fetch_greeks(self, symbol: str, params={}) -> Greeks:
6449
7256
  """
6450
7257
  fetches an option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract
6451
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-tickers-of-options-contracts
7258
+
7259
+ https://www.gate.io/docs/developers/apiv4/en/#list-tickers-of-options-contracts
7260
+
6452
7261
  :param str symbol: unified symbol of the market to fetch greeks for
6453
7262
  :param dict [params]: extra parameters specific to the exchange API endpoint
6454
7263
  :returns dict: a `greeks structure <https://docs.ccxt.com/#/?id=greeks-structure>`
@@ -6537,9 +7346,11 @@ class gate(Exchange, ImplicitAPI):
6537
7346
  def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
6538
7347
  """
6539
7348
  closes open positions for a market
6540
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order
6541
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order-2
6542
- :see: https://www.gate.io/docs/developers/apiv4/en/#create-an-options-order
7349
+
7350
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order
7351
+ https://www.gate.io/docs/developers/apiv4/en/#create-a-futures-order-2
7352
+ https://www.gate.io/docs/developers/apiv4/en/#create-an-options-order
7353
+
6543
7354
  :param str symbol: Unified CCXT market symbol
6544
7355
  :param str side: 'buy' or 'sell'
6545
7356
  :param dict [params]: extra parameters specific to the okx api endpoint
@@ -6556,9 +7367,11 @@ class gate(Exchange, ImplicitAPI):
6556
7367
  def fetch_leverage(self, symbol: str, params={}) -> Leverage:
6557
7368
  """
6558
7369
  fetch the set leverage for a market
6559
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-unified-account-information
6560
- :see: https://www.gate.io/docs/developers/apiv4/en/#get-detail-of-lending-market
6561
- :see: https://www.gate.io/docs/developers/apiv4/en/#query-one-single-margin-currency-pair-deprecated
7370
+
7371
+ https://www.gate.io/docs/developers/apiv4/en/#get-unified-account-information
7372
+ https://www.gate.io/docs/developers/apiv4/en/#get-detail-of-lending-market
7373
+ https://www.gate.io/docs/developers/apiv4/en/#query-one-single-margin-currency-pair-deprecated
7374
+
6562
7375
  :param str symbol: unified market symbol
6563
7376
  :param dict [params]: extra parameters specific to the exchange API endpoint
6564
7377
  :param boolean [params.unified]: default False, set to True for fetching the unified accounts leverage
@@ -6658,8 +7471,10 @@ class gate(Exchange, ImplicitAPI):
6658
7471
  def fetch_leverages(self, symbols: Strings = None, params={}) -> Leverages:
6659
7472
  """
6660
7473
  fetch the set leverage for all leverage markets, only spot margin is supported on gate
6661
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-lending-markets
6662
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-supported-currency-pairs-supported-in-margin-trading-deprecated
7474
+
7475
+ https://www.gate.io/docs/developers/apiv4/en/#list-lending-markets
7476
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-supported-currency-pairs-supported-in-margin-trading-deprecated
7477
+
6663
7478
  :param str[] symbols: a list of unified market symbols
6664
7479
  :param dict [params]: extra parameters specific to the exchange API endpoint
6665
7480
  :param boolean [params.unified]: default False, set to True for fetching unified account leverages
@@ -6716,7 +7531,9 @@ class gate(Exchange, ImplicitAPI):
6716
7531
  def fetch_option(self, symbol: str, params={}) -> Option:
6717
7532
  """
6718
7533
  fetches option data that is commonly found in an option chain
6719
- :see: https://www.gate.io/docs/developers/apiv4/en/#query-specified-contract-detail
7534
+
7535
+ https://www.gate.io/docs/developers/apiv4/en/#query-specified-contract-detail
7536
+
6720
7537
  :param str symbol: unified market symbol
6721
7538
  :param dict [params]: extra parameters specific to the exchange API endpoint
6722
7539
  :returns dict: an `option chain structure <https://docs.ccxt.com/#/?id=option-chain-structure>`
@@ -6772,8 +7589,10 @@ class gate(Exchange, ImplicitAPI):
6772
7589
  def fetch_option_chain(self, code: str, params={}) -> OptionChain:
6773
7590
  """
6774
7591
  fetches data for an underlying asset that is commonly found in an option chain
6775
- :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-the-contracts-with-specified-underlying-and-expiration-time
6776
- :param str currency: base currency to fetch an option chain for
7592
+
7593
+ https://www.gate.io/docs/developers/apiv4/en/#list-all-the-contracts-with-specified-underlying-and-expiration-time
7594
+
7595
+ :param str code: base currency to fetch an option chain for
6777
7596
  :param dict [params]: extra parameters specific to the exchange API endpoint
6778
7597
  :param str [params.underlying]: the underlying asset, can be obtained from fetchUnderlyingAssets()
6779
7598
  :param int [params.expiration]: unix timestamp of the expiration time
@@ -6896,18 +7715,20 @@ class gate(Exchange, ImplicitAPI):
6896
7715
  def fetch_positions_history(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
6897
7716
  """
6898
7717
  fetches historical positions
6899
- :see: https://www.gate.io/docs/developers/apiv4/#list-position-close-history
6900
- :see: https://www.gate.io/docs/developers/apiv4/#list-position-close-history-2
7718
+
7719
+ https://www.gate.io/docs/developers/apiv4/#list-position-close-history
7720
+ https://www.gate.io/docs/developers/apiv4/#list-position-close-history-2
7721
+
6901
7722
  :param str[] symbols: unified conract symbols, must all have the same settle currency and the same market type
6902
7723
  :param int [since]: the earliest time in ms to fetch positions for
6903
7724
  :param int [limit]: the maximum amount of records to fetch, default=1000
6904
7725
  :param dict params: extra parameters specific to the exchange api endpoint
6905
7726
  :param int [params.until]: the latest time in ms to fetch positions for
6906
- *
6907
- * EXCHANGE SPECIFIC PARAMETERS
6908
- :param int offset: list offset, starting from 0
6909
- :param str side: long or short
6910
- :param str pnl: query profit or loss
7727
+
7728
+ EXCHANGE SPECIFIC PARAMETERS
7729
+ :param int [params.offset]: list offset, starting from 0
7730
+ :param str [params.side]: long or short
7731
+ :param str [params.pnl]: query profit or loss
6911
7732
  :returns dict[]: a list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
6912
7733
  """
6913
7734
  self.load_markets()
@@ -6966,6 +7787,7 @@ class gate(Exchange, ImplicitAPI):
6966
7787
  # {"label": "INVALID_PARAM_VALUE", "message": "invalid argument: Trigger.rule"}
6967
7788
  # {"label": "INVALID_PARAM_VALUE", "message": "invalid argument: trigger.expiration invalid range"}
6968
7789
  # {"label": "INVALID_ARGUMENT", "detail": "invalid size"}
7790
+ # {"user_id":10406147,"id":"id","succeeded":false,"message":"INVALID_PROTOCOL","label":"INVALID_PROTOCOL"}
6969
7791
  #
6970
7792
  label = self.safe_string(response, 'label')
6971
7793
  if label is not None: