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