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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (528) hide show
  1. ccxt/__init__.py +39 -35
  2. ccxt/abantether.py +9 -9
  3. ccxt/abstract/alpaca.py +4 -0
  4. ccxt/abstract/apex.py +31 -0
  5. ccxt/abstract/bigone.py +1 -1
  6. ccxt/abstract/binance.py +106 -48
  7. ccxt/abstract/binancecoinm.py +106 -48
  8. ccxt/abstract/binanceus.py +141 -83
  9. ccxt/abstract/binanceusdm.py +106 -48
  10. ccxt/abstract/bingx.py +50 -1
  11. ccxt/abstract/bitbank.py +5 -0
  12. ccxt/abstract/bitfinex.py +136 -65
  13. ccxt/abstract/bitflyer.py +1 -0
  14. ccxt/abstract/bitget.py +67 -0
  15. ccxt/abstract/bitmart.py +19 -1
  16. ccxt/abstract/bitopro.py +1 -0
  17. ccxt/abstract/bitrue.py +68 -68
  18. ccxt/abstract/bitstamp.py +1 -0
  19. ccxt/abstract/blofin.py +30 -0
  20. ccxt/abstract/btcbox.py +2 -0
  21. ccxt/abstract/bybit.py +28 -13
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbaseexchange.py +1 -0
  24. ccxt/abstract/coinbaseinternational.py +1 -1
  25. ccxt/abstract/cryptocom.py +16 -0
  26. ccxt/abstract/cryptomus.py +20 -0
  27. ccxt/abstract/defx.py +69 -0
  28. ccxt/abstract/deribit.py +1 -0
  29. ccxt/abstract/derive.py +117 -0
  30. ccxt/abstract/digifinex.py +1 -0
  31. ccxt/abstract/ellipx.py +25 -0
  32. ccxt/abstract/foxbit.py +26 -0
  33. ccxt/abstract/gate.py +19 -0
  34. ccxt/abstract/gateio.py +19 -0
  35. ccxt/abstract/gemini.py +1 -0
  36. ccxt/abstract/hibachi.py +26 -0
  37. ccxt/abstract/hyperliquid.py +1 -1
  38. ccxt/abstract/independentreserve.py +6 -0
  39. ccxt/abstract/kraken.py +1 -0
  40. ccxt/abstract/krakenfutures.py +4 -0
  41. ccxt/abstract/kucoin.py +10 -0
  42. ccxt/abstract/kucoinfutures.py +18 -0
  43. ccxt/abstract/lbank.py +2 -1
  44. ccxt/abstract/luno.py +1 -0
  45. ccxt/abstract/mexc.py +2 -0
  46. ccxt/abstract/modetrade.py +119 -0
  47. ccxt/abstract/myokx.py +349 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +25 -0
  50. ccxt/abstract/okxus.py +349 -0
  51. ccxt/abstract/onetrading.py +0 -12
  52. ccxt/abstract/paradex.py +23 -0
  53. ccxt/abstract/phemex.py +2 -0
  54. ccxt/abstract/poloniex.py +36 -0
  55. ccxt/abstract/tradeogre.py +3 -1
  56. ccxt/abstract/upbit.py +51 -34
  57. ccxt/abstract/whitebit.py +16 -0
  58. ccxt/abstract/woo.py +64 -6
  59. ccxt/abstract/xt.py +10 -5
  60. ccxt/afratether.py +7 -7
  61. ccxt/alpaca.py +828 -51
  62. ccxt/apex.py +1875 -0
  63. ccxt/arzinja.py +7 -7
  64. ccxt/arzplus.py +9 -9
  65. ccxt/ascendex.py +501 -306
  66. ccxt/async_support/__init__.py +39 -35
  67. ccxt/async_support/abantether.py +10 -10
  68. ccxt/async_support/afratether.py +9 -9
  69. ccxt/async_support/alpaca.py +828 -51
  70. ccxt/async_support/apex.py +1875 -0
  71. ccxt/async_support/arzinja.py +10 -10
  72. ccxt/async_support/arzplus.py +12 -12
  73. ccxt/async_support/ascendex.py +502 -306
  74. ccxt/async_support/base/exchange.py +303 -89
  75. ccxt/async_support/base/ws/cache.py +9 -3
  76. ccxt/async_support/base/ws/client.py +173 -38
  77. ccxt/async_support/base/ws/future.py +25 -37
  78. ccxt/async_support/bequant.py +5 -3
  79. ccxt/async_support/bigone.py +279 -144
  80. ccxt/async_support/binance.py +2347 -1158
  81. ccxt/async_support/binancecoinm.py +9 -3
  82. ccxt/async_support/binanceus.py +17 -3
  83. ccxt/async_support/binanceusdm.py +9 -4
  84. ccxt/async_support/bingx.py +2962 -920
  85. ccxt/async_support/bit2c.py +147 -27
  86. ccxt/async_support/bitbank.py +151 -23
  87. ccxt/async_support/bitbns.py +104 -30
  88. ccxt/async_support/bitfinex.py +3291 -1113
  89. ccxt/async_support/bitflyer.py +202 -27
  90. ccxt/async_support/bitget.py +3683 -1538
  91. ccxt/async_support/bithumb.py +195 -38
  92. ccxt/async_support/bitimen.py +12 -12
  93. ccxt/async_support/bitir.py +38 -38
  94. ccxt/async_support/bitmart.py +1288 -350
  95. ccxt/async_support/bitmex.py +260 -75
  96. ccxt/async_support/bitopro.py +262 -62
  97. ccxt/async_support/bitpin.py +17 -16
  98. ccxt/async_support/bitrue.py +459 -290
  99. ccxt/async_support/bitso.py +199 -54
  100. ccxt/async_support/bitstamp.py +230 -96
  101. ccxt/async_support/bitteam.py +167 -25
  102. ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
  103. ccxt/async_support/bitvavo.py +213 -49
  104. ccxt/async_support/blockchaincom.py +160 -46
  105. ccxt/async_support/blofin.py +502 -120
  106. ccxt/async_support/btcalpha.py +169 -31
  107. ccxt/async_support/btcbox.py +292 -23
  108. ccxt/async_support/btcmarkets.py +211 -58
  109. ccxt/async_support/btcturk.py +161 -38
  110. ccxt/async_support/bybit.py +1775 -1030
  111. ccxt/async_support/cex.py +1440 -1303
  112. ccxt/async_support/coinbase.py +724 -212
  113. ccxt/async_support/coinbaseadvanced.py +2 -1
  114. ccxt/async_support/coinbaseexchange.py +388 -89
  115. ccxt/async_support/coinbaseinternational.py +412 -57
  116. ccxt/async_support/coincatch.py +177 -78
  117. ccxt/async_support/coincheck.py +135 -19
  118. ccxt/async_support/coinex.py +606 -232
  119. ccxt/async_support/coinmate.py +189 -63
  120. ccxt/async_support/coinmetro.py +195 -54
  121. ccxt/async_support/coinone.py +158 -51
  122. ccxt/async_support/coinsph.py +336 -61
  123. ccxt/async_support/coinspot.py +151 -52
  124. ccxt/async_support/cryptocom.py +661 -111
  125. ccxt/async_support/cryptomus.py +1137 -0
  126. ccxt/async_support/defx.py +2071 -0
  127. ccxt/async_support/delta.py +299 -99
  128. ccxt/async_support/deribit.py +348 -126
  129. ccxt/async_support/derive.py +2572 -0
  130. ccxt/async_support/digifinex.py +430 -214
  131. ccxt/async_support/ellipx.py +2029 -0
  132. ccxt/async_support/eterex.py +10 -10
  133. ccxt/async_support/excoino.py +31 -31
  134. ccxt/async_support/exir.py +14 -14
  135. ccxt/async_support/exmo.py +344 -131
  136. ccxt/async_support/exnovin.py +10 -10
  137. ccxt/async_support/farhadexchange.py +12 -12
  138. ccxt/async_support/fmfwio.py +2 -1
  139. ccxt/async_support/foxbit.py +1935 -0
  140. ccxt/async_support/gate.py +1351 -529
  141. ccxt/async_support/gateio.py +2 -1
  142. ccxt/async_support/gemini.py +144 -39
  143. ccxt/async_support/hashkey.py +152 -109
  144. ccxt/async_support/hibachi.py +2080 -0
  145. ccxt/async_support/hitbtc.py +395 -167
  146. ccxt/async_support/hitobit.py +12 -12
  147. ccxt/async_support/hollaex.py +307 -119
  148. ccxt/async_support/htx.py +851 -383
  149. ccxt/async_support/huobi.py +2 -1
  150. ccxt/async_support/hyperliquid.py +1848 -536
  151. ccxt/async_support/independentreserve.py +288 -15
  152. ccxt/async_support/indodax.py +190 -33
  153. ccxt/async_support/jibitex.py +12 -12
  154. ccxt/async_support/kraken.py +795 -351
  155. ccxt/async_support/krakenfutures.py +214 -62
  156. ccxt/async_support/kucoin.py +715 -396
  157. ccxt/async_support/kucoinfutures.py +652 -89
  158. ccxt/async_support/latoken.py +217 -113
  159. ccxt/async_support/lbank.py +425 -97
  160. ccxt/async_support/luno.py +382 -35
  161. ccxt/async_support/mercado.py +113 -6
  162. ccxt/async_support/mexc.py +874 -437
  163. ccxt/async_support/modetrade.py +2818 -0
  164. ccxt/async_support/myokx.py +54 -0
  165. ccxt/async_support/ndax.py +221 -64
  166. ccxt/async_support/nobitex.py +31 -37
  167. ccxt/async_support/novadax.py +190 -34
  168. ccxt/async_support/oceanex.py +217 -28
  169. ccxt/async_support/okcoin.py +253 -145
  170. ccxt/async_support/okexchange.py +11 -11
  171. ccxt/async_support/okx.py +1088 -351
  172. ccxt/async_support/okxus.py +54 -0
  173. ccxt/async_support/ompfinex.py +25 -24
  174. ccxt/async_support/onetrading.py +213 -392
  175. ccxt/async_support/oxfun.py +245 -166
  176. ccxt/async_support/p2b.py +151 -29
  177. ccxt/async_support/paradex.py +562 -49
  178. ccxt/async_support/paymium.py +82 -19
  179. ccxt/async_support/phemex.py +713 -172
  180. ccxt/async_support/poloniex.py +1602 -283
  181. ccxt/async_support/probit.py +224 -95
  182. ccxt/async_support/ramzinex.py +30 -27
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +14 -13
  186. ccxt/async_support/tetherland.py +9 -9
  187. ccxt/async_support/timex.py +210 -51
  188. ccxt/async_support/tokocrypto.py +167 -47
  189. ccxt/async_support/tradeogre.py +266 -31
  190. ccxt/async_support/twox.py +9 -9
  191. ccxt/async_support/ubitex.py +12 -12
  192. ccxt/async_support/upbit.py +568 -165
  193. ccxt/async_support/vertex.py +160 -32
  194. ccxt/async_support/wallex.py +12 -12
  195. ccxt/async_support/wavesexchange.py +165 -30
  196. ccxt/async_support/whitebit.py +975 -127
  197. ccxt/async_support/woo.py +1918 -1016
  198. ccxt/async_support/woofipro.py +433 -141
  199. ccxt/async_support/xt.py +649 -193
  200. ccxt/async_support/yobit.py +195 -70
  201. ccxt/async_support/zaif.py +91 -15
  202. ccxt/async_support/zonda.py +151 -36
  203. ccxt/base/decimal_to_precision.py +14 -10
  204. ccxt/base/errors.py +49 -18
  205. ccxt/base/exchange.py +1556 -450
  206. ccxt/base/precise.py +10 -0
  207. ccxt/base/types.py +114 -6
  208. ccxt/bequant.py +5 -3
  209. ccxt/bigone.py +279 -144
  210. ccxt/binance.py +2347 -1158
  211. ccxt/binancecoinm.py +9 -3
  212. ccxt/binanceus.py +17 -3
  213. ccxt/binanceusdm.py +9 -4
  214. ccxt/bingx.py +2962 -920
  215. ccxt/bit2c.py +147 -27
  216. ccxt/bitbank.py +151 -23
  217. ccxt/bitbns.py +104 -30
  218. ccxt/bitfinex.py +3290 -1113
  219. ccxt/bitflyer.py +202 -27
  220. ccxt/bitget.py +3683 -1538
  221. ccxt/bithumb.py +194 -38
  222. ccxt/bitimen.py +9 -9
  223. ccxt/bitir.py +35 -35
  224. ccxt/bitmart.py +1288 -350
  225. ccxt/bitmex.py +260 -75
  226. ccxt/bitopro.py +262 -62
  227. ccxt/bitpin.py +15 -14
  228. ccxt/bitrue.py +459 -290
  229. ccxt/bitso.py +199 -54
  230. ccxt/bitstamp.py +230 -96
  231. ccxt/bitteam.py +167 -25
  232. ccxt/{huobijp.py → bittrade.py} +158 -30
  233. ccxt/bitvavo.py +213 -49
  234. ccxt/blockchaincom.py +160 -46
  235. ccxt/blofin.py +502 -120
  236. ccxt/btcalpha.py +169 -31
  237. ccxt/btcbox.py +291 -23
  238. ccxt/btcmarkets.py +211 -58
  239. ccxt/btcturk.py +161 -38
  240. ccxt/bybit.py +1775 -1030
  241. ccxt/cex.py +1439 -1303
  242. ccxt/coinbase.py +724 -212
  243. ccxt/coinbaseadvanced.py +2 -1
  244. ccxt/coinbaseexchange.py +388 -89
  245. ccxt/coinbaseinternational.py +412 -57
  246. ccxt/coincatch.py +177 -78
  247. ccxt/coincheck.py +135 -19
  248. ccxt/coinex.py +606 -232
  249. ccxt/coinmate.py +189 -63
  250. ccxt/coinmetro.py +194 -54
  251. ccxt/coinone.py +158 -51
  252. ccxt/coinsph.py +336 -61
  253. ccxt/coinspot.py +151 -52
  254. ccxt/cryptocom.py +661 -111
  255. ccxt/cryptomus.py +1137 -0
  256. ccxt/defx.py +2070 -0
  257. ccxt/delta.py +299 -99
  258. ccxt/deribit.py +348 -126
  259. ccxt/derive.py +2571 -0
  260. ccxt/digifinex.py +430 -214
  261. ccxt/ellipx.py +2029 -0
  262. ccxt/eterex.py +7 -7
  263. ccxt/excoino.py +29 -29
  264. ccxt/exir.py +11 -11
  265. ccxt/exmo.py +343 -131
  266. ccxt/exnovin.py +8 -8
  267. ccxt/farhadexchange.py +10 -10
  268. ccxt/fmfwio.py +2 -1
  269. ccxt/foxbit.py +1935 -0
  270. ccxt/gate.py +1351 -529
  271. ccxt/gateio.py +2 -1
  272. ccxt/gemini.py +144 -39
  273. ccxt/hashkey.py +152 -109
  274. ccxt/hibachi.py +2079 -0
  275. ccxt/hitbtc.py +395 -167
  276. ccxt/hitobit.py +9 -9
  277. ccxt/hollaex.py +307 -119
  278. ccxt/htx.py +851 -383
  279. ccxt/huobi.py +2 -1
  280. ccxt/hyperliquid.py +1848 -536
  281. ccxt/independentreserve.py +287 -15
  282. ccxt/indodax.py +190 -33
  283. ccxt/jibitex.py +9 -9
  284. ccxt/kraken.py +794 -351
  285. ccxt/krakenfutures.py +214 -62
  286. ccxt/kucoin.py +715 -396
  287. ccxt/kucoinfutures.py +652 -89
  288. ccxt/latoken.py +217 -113
  289. ccxt/lbank.py +425 -97
  290. ccxt/luno.py +382 -35
  291. ccxt/mercado.py +113 -6
  292. ccxt/mexc.py +873 -437
  293. ccxt/modetrade.py +2818 -0
  294. ccxt/myokx.py +54 -0
  295. ccxt/ndax.py +221 -64
  296. ccxt/nobitex.py +29 -35
  297. ccxt/novadax.py +190 -34
  298. ccxt/oceanex.py +217 -28
  299. ccxt/okcoin.py +253 -145
  300. ccxt/okexchange.py +9 -9
  301. ccxt/okx.py +1088 -351
  302. ccxt/okxus.py +54 -0
  303. ccxt/ompfinex.py +22 -21
  304. ccxt/onetrading.py +213 -392
  305. ccxt/oxfun.py +245 -166
  306. ccxt/p2b.py +151 -29
  307. ccxt/paradex.py +562 -49
  308. ccxt/paymium.py +82 -19
  309. ccxt/phemex.py +712 -172
  310. ccxt/poloniex.py +1601 -283
  311. ccxt/pro/__init__.py +76 -17
  312. ccxt/pro/alpaca.py +21 -6
  313. ccxt/pro/apex.py +984 -0
  314. ccxt/pro/ascendex.py +58 -10
  315. ccxt/pro/bequant.py +6 -1
  316. ccxt/pro/binance.py +728 -156
  317. ccxt/pro/binancecoinm.py +6 -2
  318. ccxt/pro/binanceus.py +8 -4
  319. ccxt/pro/binanceusdm.py +7 -2
  320. ccxt/pro/bingx.py +333 -142
  321. ccxt/pro/bitfinex.py +727 -262
  322. ccxt/pro/bitget.py +570 -79
  323. ccxt/pro/bithumb.py +20 -6
  324. ccxt/pro/bitmart.py +216 -87
  325. ccxt/pro/bitmex.py +47 -9
  326. ccxt/pro/bitopro.py +26 -14
  327. ccxt/pro/bitrue.py +22 -22
  328. ccxt/pro/bitstamp.py +54 -21
  329. ccxt/pro/{huobijp.py → bittrade.py} +7 -6
  330. ccxt/pro/bitvavo.py +191 -67
  331. ccxt/pro/blockchaincom.py +21 -8
  332. ccxt/pro/blofin.py +9 -1
  333. ccxt/pro/bybit.py +632 -245
  334. ccxt/pro/cex.py +59 -24
  335. ccxt/pro/coinbase.py +102 -73
  336. ccxt/pro/coinbaseadvanced.py +2 -1
  337. ccxt/pro/coinbaseexchange.py +8 -8
  338. ccxt/pro/coinbaseinternational.py +181 -25
  339. ccxt/pro/coincatch.py +6 -7
  340. ccxt/pro/coincheck.py +11 -6
  341. ccxt/pro/coinex.py +967 -665
  342. ccxt/pro/coinone.py +16 -9
  343. ccxt/pro/cryptocom.py +448 -45
  344. ccxt/pro/defx.py +831 -0
  345. ccxt/pro/deribit.py +150 -14
  346. ccxt/pro/derive.py +704 -0
  347. ccxt/pro/exmo.py +239 -6
  348. ccxt/pro/gate.py +623 -65
  349. ccxt/pro/gateio.py +2 -1
  350. ccxt/pro/gemini.py +27 -11
  351. ccxt/pro/hashkey.py +2 -2
  352. ccxt/pro/hitbtc.py +196 -91
  353. ccxt/pro/hollaex.py +23 -7
  354. ccxt/pro/htx.py +51 -14
  355. ccxt/pro/huobi.py +2 -1
  356. ccxt/pro/hyperliquid.py +591 -27
  357. ccxt/pro/independentreserve.py +9 -6
  358. ccxt/pro/kraken.py +640 -320
  359. ccxt/pro/krakenfutures.py +62 -35
  360. ccxt/pro/kucoin.py +267 -46
  361. ccxt/pro/kucoinfutures.py +165 -21
  362. ccxt/pro/lbank.py +102 -21
  363. ccxt/pro/luno.py +12 -8
  364. ccxt/pro/mexc.py +877 -111
  365. ccxt/pro/modetrade.py +1271 -0
  366. ccxt/pro/myokx.py +38 -0
  367. ccxt/pro/ndax.py +15 -2
  368. ccxt/pro/okcoin.py +23 -4
  369. ccxt/pro/okx.py +573 -98
  370. ccxt/pro/okxus.py +38 -0
  371. ccxt/pro/onetrading.py +30 -13
  372. ccxt/pro/oxfun.py +131 -27
  373. ccxt/pro/p2b.py +88 -22
  374. ccxt/pro/paradex.py +3 -3
  375. ccxt/pro/phemex.py +75 -21
  376. ccxt/pro/poloniex.py +124 -41
  377. ccxt/pro/probit.py +87 -80
  378. ccxt/pro/tradeogre.py +272 -0
  379. ccxt/pro/upbit.py +152 -12
  380. ccxt/pro/vertex.py +8 -3
  381. ccxt/pro/whitebit.py +58 -5
  382. ccxt/pro/woo.py +228 -37
  383. ccxt/pro/woofipro.py +106 -18
  384. ccxt/pro/xt.py +111 -5
  385. ccxt/probit.py +224 -95
  386. ccxt/protobuf/__init__.py +0 -0
  387. ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
  388. ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
  389. ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
  390. ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
  391. ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
  392. ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
  393. ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
  394. ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
  395. ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
  396. ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
  397. ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
  398. ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
  399. ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
  400. ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
  401. ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
  402. ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
  403. ccxt/protobuf/mexc/__init__.py +0 -0
  404. ccxt/ramzinex.py +28 -25
  405. ccxt/sarmayex.py +7 -7
  406. ccxt/sarrafex.py +10 -10
  407. ccxt/static_dependencies/__init__.py +1 -1
  408. ccxt/static_dependencies/lark/py.typed +0 -0
  409. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  410. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  411. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  412. ccxt/tabdeal.py +12 -11
  413. ccxt/test/tests_async.py +261 -57
  414. ccxt/test/tests_helpers.py +1 -3
  415. ccxt/test/tests_init.py +4 -3
  416. ccxt/test/tests_sync.py +261 -57
  417. ccxt/tetherland.py +7 -7
  418. ccxt/timex.py +210 -51
  419. ccxt/tokocrypto.py +167 -47
  420. ccxt/tradeogre.py +266 -31
  421. ccxt/twox.py +7 -7
  422. ccxt/ubitex.py +9 -9
  423. ccxt/upbit.py +568 -165
  424. ccxt/vertex.py +160 -32
  425. ccxt/wallex.py +9 -9
  426. ccxt/wavesexchange.py +165 -30
  427. ccxt/whitebit.py +975 -127
  428. ccxt/woo.py +1917 -1016
  429. ccxt/woofipro.py +432 -141
  430. ccxt/xt.py +649 -193
  431. ccxt/yobit.py +194 -70
  432. ccxt/zaif.py +91 -15
  433. ccxt/zonda.py +151 -36
  434. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.0.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/WHEEL +1 -1
  437. ccxt/abstract/ace.py +0 -15
  438. ccxt/abstract/bitbay.py +0 -53
  439. ccxt/abstract/bitcoincom.py +0 -115
  440. ccxt/abstract/bitfinex2.py +0 -139
  441. ccxt/abstract/bitpanda.py +0 -35
  442. ccxt/abstract/bl3p.py +0 -19
  443. ccxt/abstract/coinlist.py +0 -54
  444. ccxt/abstract/currencycom.py +0 -68
  445. ccxt/abstract/hitbtc3.py +0 -115
  446. ccxt/abstract/idex.py +0 -26
  447. ccxt/abstract/kuna.py +0 -182
  448. ccxt/abstract/lykke.py +0 -29
  449. ccxt/abstract/poloniexfutures.py +0 -48
  450. ccxt/abstract/wazirx.py +0 -30
  451. ccxt/ace.py +0 -1012
  452. ccxt/async_support/ace.py +0 -1012
  453. ccxt/async_support/base/ws/aiohttp_client.py +0 -125
  454. ccxt/async_support/base/ws/fast_client.py +0 -96
  455. ccxt/async_support/bitbay.py +0 -17
  456. ccxt/async_support/bitcoincom.py +0 -17
  457. ccxt/async_support/bitfinex2.py +0 -3552
  458. ccxt/async_support/bitpanda.py +0 -16
  459. ccxt/async_support/bl3p.py +0 -485
  460. ccxt/async_support/coinlist.py +0 -2243
  461. ccxt/async_support/currencycom.py +0 -1950
  462. ccxt/async_support/hitbtc3.py +0 -16
  463. ccxt/async_support/idex.py +0 -1766
  464. ccxt/async_support/kuna.py +0 -1841
  465. ccxt/async_support/lykke.py +0 -1270
  466. ccxt/async_support/poloniexfutures.py +0 -1717
  467. ccxt/async_support/wazirx.py +0 -1224
  468. ccxt/bitbay.py +0 -17
  469. ccxt/bitcoincom.py +0 -17
  470. ccxt/bitfinex2.py +0 -3552
  471. ccxt/bitpanda.py +0 -16
  472. ccxt/bl3p.py +0 -485
  473. ccxt/coinlist.py +0 -2243
  474. ccxt/currencycom.py +0 -1950
  475. ccxt/hitbtc3.py +0 -16
  476. ccxt/idex.py +0 -1766
  477. ccxt/kuna.py +0 -1841
  478. ccxt/lykke.py +0 -1270
  479. ccxt/poloniexfutures.py +0 -1717
  480. ccxt/pro/bitcoincom.py +0 -34
  481. ccxt/pro/bitfinex2.py +0 -1083
  482. ccxt/pro/bitpanda.py +0 -15
  483. ccxt/pro/currencycom.py +0 -536
  484. ccxt/pro/idex.py +0 -672
  485. ccxt/pro/poloniexfutures.py +0 -990
  486. ccxt/pro/wazirx.py +0 -749
  487. ccxt/test/base/__init__.py +0 -29
  488. ccxt/test/base/test_account.py +0 -26
  489. ccxt/test/base/test_balance.py +0 -56
  490. ccxt/test/base/test_borrow_interest.py +0 -35
  491. ccxt/test/base/test_borrow_rate.py +0 -32
  492. ccxt/test/base/test_calculate_fee.py +0 -51
  493. ccxt/test/base/test_crypto.py +0 -127
  494. ccxt/test/base/test_currency.py +0 -76
  495. ccxt/test/base/test_datetime.py +0 -109
  496. ccxt/test/base/test_decimal_to_precision.py +0 -392
  497. ccxt/test/base/test_deep_extend.py +0 -68
  498. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  499. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  500. ccxt/test/base/test_funding_rate_history.py +0 -29
  501. ccxt/test/base/test_last_price.py +0 -31
  502. ccxt/test/base/test_ledger_entry.py +0 -45
  503. ccxt/test/base/test_ledger_item.py +0 -48
  504. ccxt/test/base/test_leverage_tier.py +0 -33
  505. ccxt/test/base/test_liquidation.py +0 -50
  506. ccxt/test/base/test_margin_mode.py +0 -24
  507. ccxt/test/base/test_margin_modification.py +0 -35
  508. ccxt/test/base/test_market.py +0 -193
  509. ccxt/test/base/test_number.py +0 -411
  510. ccxt/test/base/test_ohlcv.py +0 -33
  511. ccxt/test/base/test_open_interest.py +0 -32
  512. ccxt/test/base/test_order.py +0 -64
  513. ccxt/test/base/test_order_book.py +0 -69
  514. ccxt/test/base/test_position.py +0 -60
  515. ccxt/test/base/test_shared_methods.py +0 -353
  516. ccxt/test/base/test_status.py +0 -24
  517. ccxt/test/base/test_throttle.py +0 -126
  518. ccxt/test/base/test_ticker.py +0 -92
  519. ccxt/test/base/test_trade.py +0 -47
  520. ccxt/test/base/test_trading_fee.py +0 -26
  521. ccxt/test/base/test_transaction.py +0 -39
  522. ccxt/test/test_async.py +0 -1649
  523. ccxt/test/test_sync.py +0 -1648
  524. ccxt/wazirx.py +0 -1224
  525. ccxt_ir-4.3.46.0.2.dist-info/RECORD +0 -772
  526. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  527. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info/licenses}/LICENSE.txt +0 -0
  528. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/top_level.txt +0 -0
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.3.46-0.1'
5
+ __version__ = '4.5.0'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -24,8 +24,8 @@ from ccxt.async_support.base.throttler import Throttler
24
24
 
25
25
  # -----------------------------------------------------------------------------
26
26
 
27
- from ccxt.base.errors import BaseError, BadSymbol, BadRequest, BadResponse, ExchangeError, ExchangeNotAvailable, RequestTimeout, NotSupported, NullResponse, InvalidAddress, RateLimitExceeded
28
- from ccxt.base.types import OrderType, OrderSide, OrderRequest, CancellationRequest
27
+ from ccxt.base.errors import BaseError, BadSymbol, BadRequest, BadResponse, ExchangeError, ExchangeNotAvailable, RequestTimeout, NotSupported, NullResponse, InvalidAddress, RateLimitExceeded, OperationFailed
28
+ from ccxt.base.types import ConstructorArgs, OrderType, OrderSide, OrderRequest, CancellationRequest
29
29
 
30
30
  # -----------------------------------------------------------------------------
31
31
 
@@ -34,7 +34,7 @@ from ccxt.base.exchange import Exchange as BaseExchange, ArgumentsRequired
34
34
  # -----------------------------------------------------------------------------
35
35
 
36
36
  from ccxt.async_support.base.ws.functions import inflate, inflate64, gunzip
37
- from ccxt.async_support.base.ws.fast_client import FastClient
37
+ from ccxt.async_support.base.ws.client import Client
38
38
  from ccxt.async_support.base.ws.future import Future
39
39
  from ccxt.async_support.base.ws.order_book import OrderBook, IndexedOrderBook, CountedOrderBook
40
40
 
@@ -54,6 +54,15 @@ __all__ = [
54
54
  ]
55
55
 
56
56
  # -----------------------------------------------------------------------------
57
+ # --- PROTO BUF IMPORTS
58
+ try:
59
+ from ccxt.protobuf.mexc import PushDataV3ApiWrapper_pb2
60
+ from google.protobuf.json_format import MessageToDict
61
+ except ImportError:
62
+ PushDataV3ApiWrapper_pb2 = None
63
+ MessageToDict = None
64
+
65
+ # -----------------------------------------------------------------------------
57
66
 
58
67
 
59
68
  class Exchange(BaseExchange):
@@ -65,26 +74,29 @@ class Exchange(BaseExchange):
65
74
  ping = None
66
75
  newUpdates = True
67
76
  clients = {}
77
+ timeout_on_exit = 250 # needed for: https://github.com/ccxt/ccxt/pull/23470
68
78
 
69
- def __init__(self, config={}):
79
+ def __init__(self, config: ConstructorArgs = {}):
70
80
  if 'asyncio_loop' in config:
71
81
  self.asyncio_loop = config['asyncio_loop']
72
82
  self.aiohttp_trust_env = config.get('aiohttp_trust_env', self.aiohttp_trust_env)
73
83
  self.verify = config.get('verify', self.verify)
74
84
  self.own_session = 'session' not in config
75
85
  self.cafile = config.get('cafile', certifi.where())
86
+ self.throttler = None
76
87
  super(Exchange, self).__init__(config)
77
- self.throttle = None
78
- self.init_rest_rate_limiter()
79
88
  self.markets_loading = None
80
89
  self.reloading_markets = False
81
90
 
82
- def init_rest_rate_limiter(self):
83
- self.throttle = Throttler(self.tokenBucket, self.asyncio_loop)
84
-
85
91
  def get_event_loop(self):
86
92
  return self.asyncio_loop
87
93
 
94
+ def init_throttler(self, cost=None):
95
+ self.throttler = Throttler(self.tokenBucket, self.asyncio_loop)
96
+
97
+ async def throttle(self, cost=None):
98
+ return await self.throttler(cost)
99
+
88
100
  def get_session(self):
89
101
  return self.session
90
102
 
@@ -106,16 +118,20 @@ class Exchange(BaseExchange):
106
118
  self.asyncio_loop = asyncio.get_running_loop()
107
119
  else:
108
120
  self.asyncio_loop = asyncio.get_event_loop()
109
- self.throttle.loop = self.asyncio_loop
121
+ self.throttler.loop = self.asyncio_loop
110
122
 
111
123
  if self.ssl_context is None:
112
124
  # Create our SSL context object with our CA cert file
113
125
  self.ssl_context = ssl.create_default_context(cafile=self.cafile) if self.verify else self.verify
126
+ if (self.ssl_context and self.safe_bool(self.options, 'include_OS_certificates', False)):
127
+ os_default_paths = ssl.get_default_verify_paths()
128
+ if os_default_paths.cafile and os_default_paths.cafile != self.cafile:
129
+ self.ssl_context.load_verify_locations(cafile=os_default_paths.cafile)
114
130
 
115
131
  if self.own_session and self.session is None:
116
132
  # Pass this SSL context to aiohttp and create a TCPConnector
117
- connector = aiohttp.TCPConnector(ssl=self.ssl_context, loop=self.asyncio_loop, enable_cleanup_closed=True)
118
- self.session = aiohttp.ClientSession(loop=self.asyncio_loop, connector=connector, trust_env=self.aiohttp_trust_env)
133
+ self.tcp_connector = aiohttp.TCPConnector(ssl=self.ssl_context, loop=self.asyncio_loop, enable_cleanup_closed=True)
134
+ self.session = aiohttp.ClientSession(loop=self.asyncio_loop, connector=self.tcp_connector, trust_env=self.aiohttp_trust_env)
119
135
 
120
136
  async def close(self):
121
137
  await self.ws_close()
@@ -123,7 +139,17 @@ class Exchange(BaseExchange):
123
139
  if self.own_session:
124
140
  await self.session.close()
125
141
  self.session = None
142
+ await self.close_connector()
126
143
  await self.close_proxy_sessions()
144
+ await self.sleep(self.timeout_on_exit)
145
+
146
+ async def close_connector(self):
147
+ if self.tcp_connector is not None:
148
+ await self.tcp_connector.close()
149
+ self.tcp_connector = None
150
+ if self.aiohttp_socks_connector is not None:
151
+ await self.aiohttp_socks_connector.close()
152
+ self.aiohttp_socks_connector = None
127
153
 
128
154
  async def close_proxy_sessions(self):
129
155
  if self.socks_proxy_sessions is not None:
@@ -141,7 +167,7 @@ class Exchange(BaseExchange):
141
167
  proxyUrl = self.check_proxy_url_settings(url, method, headers, body)
142
168
  if proxyUrl is not None:
143
169
  request_headers.update({'Origin': self.origin})
144
- url = proxyUrl + url
170
+ url = proxyUrl + self.url_encoder_for_proxy_url(url)
145
171
  # proxy agents
146
172
  final_proxy = None # set default
147
173
  proxy_session = None
@@ -153,21 +179,13 @@ class Exchange(BaseExchange):
153
179
  elif socksProxy:
154
180
  if ProxyConnector is None:
155
181
  raise NotSupported(self.id + ' - to use SOCKS proxy with ccxt, you need "aiohttp_socks" module that can be installed by "pip install aiohttp_socks"')
156
- # Create our SSL context object with our CA cert file
157
- self.open() # ensure `asyncio_loop` is set
158
- connector = ProxyConnector.from_url(
159
- socksProxy,
160
- # extra args copied from self.open()
161
- ssl=self.ssl_context,
162
- loop=self.asyncio_loop,
163
- enable_cleanup_closed=True
164
- )
165
182
  # override session
166
183
  if (self.socks_proxy_sessions is None):
167
184
  self.socks_proxy_sessions = {}
168
185
  if (socksProxy not in self.socks_proxy_sessions):
169
- self.socks_proxy_sessions[socksProxy] = aiohttp.ClientSession(loop=self.asyncio_loop, connector=connector, trust_env=self.aiohttp_trust_env)
170
- proxy_session = self.socks_proxy_sessions[socksProxy]
186
+ # Create our SSL context object with our CA cert file
187
+ self.open() # ensure `asyncio_loop` is set
188
+ proxy_session = self.get_socks_proxy_session(socksProxy)
171
189
  # add aiohttp_proxy for python as exclusion
172
190
  elif self.aiohttp_proxy:
173
191
  final_proxy = self.aiohttp_proxy
@@ -222,6 +240,8 @@ class Exchange(BaseExchange):
222
240
  self.last_json_response = json_response
223
241
  if self.verbose:
224
242
  self.log("\nfetch Response:", self.id, method, url, http_status_code, "ResponseHeaders:", headers, "ResponseBody:", http_response)
243
+ if json_response and not isinstance(json_response, list) and self.returnResponseHeaders:
244
+ json_response['responseHeaders'] = headers
225
245
  self.logger.debug("%s %s, Response: %s %s %s", method, url, http_status_code, headers, http_response)
226
246
 
227
247
  except socket.gaierror as e:
@@ -250,6 +270,20 @@ class Exchange(BaseExchange):
250
270
  return http_response
251
271
  return response.content
252
272
 
273
+ def get_socks_proxy_session(self, socksProxy):
274
+ if (self.socks_proxy_sessions is None):
275
+ self.socks_proxy_sessions = {}
276
+ if (socksProxy not in self.socks_proxy_sessions):
277
+ self.aiohttp_socks_connector = ProxyConnector.from_url(
278
+ socksProxy,
279
+ # extra args copied from self.open()
280
+ ssl=self.ssl_context,
281
+ loop=self.asyncio_loop,
282
+ enable_cleanup_closed=True
283
+ )
284
+ self.socks_proxy_sessions[socksProxy] = aiohttp.ClientSession(loop=self.asyncio_loop, connector=self.aiohttp_socks_connector, trust_env=self.aiohttp_trust_env)
285
+ return self.socks_proxy_sessions[socksProxy]
286
+
253
287
  async def load_markets_helper(self, reload=False, params={}):
254
288
  if not reload:
255
289
  if self.markets:
@@ -259,10 +293,34 @@ class Exchange(BaseExchange):
259
293
  currencies = None
260
294
  if self.has['fetchCurrencies'] is True:
261
295
  currencies = await self.fetch_currencies()
296
+ self.options['cachedCurrencies'] = currencies
262
297
  markets = await self.fetch_markets(params)
298
+ if 'cachedCurrencies' in self.options:
299
+ del self.options['cachedCurrencies']
263
300
  return self.set_markets(markets, currencies)
264
301
 
302
+
265
303
  async def load_markets(self, reload=False, params={}):
304
+ """
305
+ Loads and prepares the markets for trading.
306
+
307
+ Args:
308
+ reload (bool): If True, the markets will be reloaded from the exchange.
309
+ params (dict): Additional exchange-specific parameters for the request.
310
+
311
+ Returns:
312
+ dict: A dictionary of markets.
313
+
314
+ Raises:
315
+ Exception: If the markets cannot be loaded or prepared.
316
+
317
+ Notes:
318
+ This method is asynchronous.
319
+ It ensures that the markets are only loaded once, even if called multiple times.
320
+ If the markets are already loaded and `reload` is False or not provided, it returns the existing markets.
321
+ If a reload is in progress, it waits for completion before returning.
322
+ If an error occurs during loading or preparation, an exception is raised.
323
+ """
266
324
  if (reload and not self.reloading_markets) or not self.markets_loading:
267
325
  self.reloading_markets = True
268
326
  coroutine = self.load_markets_helper(reload, params)
@@ -270,6 +328,10 @@ class Exchange(BaseExchange):
270
328
  self.markets_loading = asyncio.ensure_future(coroutine)
271
329
  try:
272
330
  result = await self.markets_loading
331
+ except asyncio.CancelledError as e: # CancelledError is a base exception so we need to catch it explicitly
332
+ self.reloading_markets = False
333
+ self.markets_loading = None
334
+ raise e
273
335
  except Exception as e:
274
336
  self.reloading_markets = False
275
337
  self.markets_loading = None
@@ -365,21 +427,17 @@ class Exchange(BaseExchange):
365
427
  'verbose': self.verbose,
366
428
  'throttle': Throttler(self.tokenBucket, self.asyncio_loop),
367
429
  'asyncio_loop': self.asyncio_loop,
430
+ 'decompressBinary': self.safe_bool(self.options, 'decompressBinary', True),
368
431
  }, ws_options)
369
- self.clients[url] = FastClient(url, on_message, on_error, on_close, on_connected, options)
370
- self.clients[url].proxy = self.get_ws_proxy()
432
+ # we use aiohttp instead of fastClient now because of this
433
+ # https://github.com/ccxt/ccxt/pull/25995
434
+ self.clients[url] = Client(url, on_message, on_error, on_close, on_connected, options)
435
+ # set http/s proxy (socks proxy should be set in other place)
436
+ httpProxy, httpsProxy, socksProxy = self.check_ws_proxy_settings()
437
+ if (httpProxy or httpsProxy):
438
+ self.clients[url].proxy = httpProxy if httpProxy else httpsProxy
371
439
  return self.clients[url]
372
440
 
373
- def get_ws_proxy(self):
374
- httpProxy, httpsProxy, socksProxy = self.check_ws_proxy_settings()
375
- if httpProxy:
376
- return httpProxy
377
- elif httpsProxy:
378
- return httpsProxy
379
- elif socksProxy:
380
- return socksProxy
381
- return None
382
-
383
441
  def delay(self, timeout, method, *args):
384
442
  return self.asyncio_loop.call_later(timeout / 1000, self.spawn, method, *args)
385
443
 
@@ -442,8 +500,13 @@ class Exchange(BaseExchange):
442
500
  if not subscribed:
443
501
  client.subscriptions[subscribe_hash] = subscription or True
444
502
 
503
+ selected_session = self.session
504
+ # http/s proxy is being set in other places
505
+ httpProxy, httpsProxy, socksProxy = self.check_ws_proxy_settings()
506
+ if (socksProxy):
507
+ selected_session = self.get_socks_proxy_session(socksProxy)
445
508
  connected = client.connected if client.connected.done() \
446
- else asyncio.ensure_future(client.connect(self.session, backoff_delay))
509
+ else asyncio.ensure_future(client.connect(selected_session, backoff_delay))
447
510
 
448
511
  def after(fut):
449
512
  # todo: decouple signing from subscriptions
@@ -520,6 +583,31 @@ class Exchange(BaseExchange):
520
583
  return '0e-00'
521
584
  return format(n, 'g')
522
585
 
586
+ def decode_proto_msg(self, data):
587
+ if not MessageToDict:
588
+ raise NotSupported(self.id + ' requires protobuf to decode messages, please install it with `pip install "protobuf==5.29.5"`')
589
+ message = PushDataV3ApiWrapper_pb2.PushDataV3ApiWrapper()
590
+ message.ParseFromString(data)
591
+ dict_msg = MessageToDict(message)
592
+ # {
593
+ # "channel":"spot@public.kline.v3.api.pb@BTCUSDT@Min1",
594
+ # "symbol":"BTCUSDT",
595
+ # "symbolId":"2fb942154ef44a4ab2ef98c8afb6a4a7",
596
+ # "createTime":"1754735110559",
597
+ # "publicSpotKline":{
598
+ # "interval":"Min1",
599
+ # "windowStart":"1754735100",
600
+ # "openingPrice":"117792.45",
601
+ # "closingPrice":"117805.32",
602
+ # "highestPrice":"117814.63",
603
+ # "lowestPrice":"117792.45",
604
+ # "volume":"0.13425465",
605
+ # "amount":"15815.77",
606
+ # "windowEnd":"1754735160"
607
+ # }
608
+ # }
609
+ return dict_msg
610
+
523
611
  # ########################################################################
524
612
  # ########################################################################
525
613
  # ########################################################################
@@ -570,7 +658,7 @@ class Exchange(BaseExchange):
570
658
 
571
659
  async def watch_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}):
572
660
  if self.has['watchLiquidationsForSymbols']:
573
- return self.watch_liquidations_for_symbols([symbol], since, limit, params)
661
+ return await self.watch_liquidations_for_symbols([symbol], since, limit, params)
574
662
  raise NotSupported(self.id + ' watchLiquidations() is not supported yet')
575
663
 
576
664
  async def watch_liquidations_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}):
@@ -587,9 +675,18 @@ class Exchange(BaseExchange):
587
675
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}):
588
676
  raise NotSupported(self.id + ' watchTrades() is not supported yet')
589
677
 
678
+ async def un_watch_orders(self, symbol: Str = None, params={}):
679
+ raise NotSupported(self.id + ' unWatchOrders() is not supported yet')
680
+
681
+ async def un_watch_trades(self, symbol: str, params={}):
682
+ raise NotSupported(self.id + ' unWatchTrades() is not supported yet')
683
+
590
684
  async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}):
591
685
  raise NotSupported(self.id + ' watchTradesForSymbols() is not supported yet')
592
686
 
687
+ async def un_watch_trades_for_symbols(self, symbols: List[str], params={}):
688
+ raise NotSupported(self.id + ' unWatchTradesForSymbols() is not supported yet')
689
+
593
690
  async def watch_my_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}):
594
691
  raise NotSupported(self.id + ' watchMyTradesForSymbols() is not supported yet')
595
692
 
@@ -599,15 +696,27 @@ class Exchange(BaseExchange):
599
696
  async def watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], since: Int = None, limit: Int = None, params={}):
600
697
  raise NotSupported(self.id + ' watchOHLCVForSymbols() is not supported yet')
601
698
 
699
+ async def un_watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], params={}):
700
+ raise NotSupported(self.id + ' unWatchOHLCVForSymbols() is not supported yet')
701
+
602
702
  async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}):
603
703
  raise NotSupported(self.id + ' watchOrderBookForSymbols() is not supported yet')
604
704
 
705
+ async def un_watch_order_book_for_symbols(self, symbols: List[str], params={}):
706
+ raise NotSupported(self.id + ' unWatchOrderBookForSymbols() is not supported yet')
707
+
708
+ async def un_watch_positions(self, symbols: Strings = None, params={}):
709
+ raise NotSupported(self.id + ' unWatchPositions() is not supported yet')
710
+
605
711
  async def fetch_deposit_addresses(self, codes: Strings = None, params={}):
606
712
  raise NotSupported(self.id + ' fetchDepositAddresses() is not supported yet')
607
713
 
608
714
  async def fetch_order_book(self, symbol: str, limit: Int = None, params={}):
609
715
  raise NotSupported(self.id + ' fetchOrderBook() is not supported yet')
610
716
 
717
+ async def fetch_order_book_ws(self, symbol: str, limit: Int = None, params={}):
718
+ raise NotSupported(self.id + ' fetchOrderBookWs() is not supported yet')
719
+
611
720
  async def fetch_margin_mode(self, symbol: str, params={}):
612
721
  if self.has['fetchMarginModes']:
613
722
  marginModes = await self.fetch_margin_modes([symbol], params)
@@ -632,6 +741,9 @@ class Exchange(BaseExchange):
632
741
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}):
633
742
  raise NotSupported(self.id + ' watchOrderBook() is not supported yet')
634
743
 
744
+ async def un_watch_order_book(self, symbol: str, params={}):
745
+ raise NotSupported(self.id + ' unWatchOrderBook() is not supported yet')
746
+
635
747
  async def fetch_time(self, params={}):
636
748
  raise NotSupported(self.id + ' fetchTime() is not supported yet')
637
749
 
@@ -650,6 +762,9 @@ class Exchange(BaseExchange):
650
762
  async def fetch_funding_rates(self, symbols: Strings = None, params={}):
651
763
  raise NotSupported(self.id + ' fetchFundingRates() is not supported yet')
652
764
 
765
+ async def fetch_funding_intervals(self, symbols: Strings = None, params={}):
766
+ raise NotSupported(self.id + ' fetchFundingIntervals() is not supported yet')
767
+
653
768
  async def watch_funding_rate(self, symbol: str, params={}):
654
769
  raise NotSupported(self.id + ' watchFundingRate() is not supported yet')
655
770
 
@@ -662,13 +777,13 @@ class Exchange(BaseExchange):
662
777
  async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}):
663
778
  raise NotSupported(self.id + ' transfer() is not supported yet')
664
779
 
665
- async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
780
+ async def withdraw(self, code: str, amount: float, address: str, tag: Str = None, params={}):
666
781
  raise NotSupported(self.id + ' withdraw() is not supported yet')
667
782
 
668
783
  async def create_deposit_address(self, code: str, params={}):
669
784
  raise NotSupported(self.id + ' createDepositAddress() is not supported yet')
670
785
 
671
- async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
786
+ async def set_leverage(self, leverage: int, symbol: Str = None, params={}):
672
787
  raise NotSupported(self.id + ' setLeverage() is not supported yet')
673
788
 
674
789
  async def fetch_leverage(self, symbol: str, params={}):
@@ -693,6 +808,12 @@ class Exchange(BaseExchange):
693
808
  async def set_margin(self, symbol: str, amount: float, params={}):
694
809
  raise NotSupported(self.id + ' setMargin() is not supported yet')
695
810
 
811
+ async def fetch_long_short_ratio(self, symbol: str, timeframe: Str = None, params={}):
812
+ raise NotSupported(self.id + ' fetchLongShortRatio() is not supported yet')
813
+
814
+ async def fetch_long_short_ratio_history(self, symbol: Str = None, timeframe: Str = None, since: Int = None, limit: Int = None, params={}):
815
+ raise NotSupported(self.id + ' fetchLongShortRatioHistory() is not supported yet')
816
+
696
817
  async def fetch_margin_adjustment_history(self, symbol: Str = None, type: Str = None, since: Num = None, limit: Num = None, params={}):
697
818
  """
698
819
  fetches the history of margin added or reduced from contract isolated positions
@@ -711,25 +832,28 @@ class Exchange(BaseExchange):
711
832
  async def fetch_deposit_addresses_by_network(self, code: str, params={}):
712
833
  raise NotSupported(self.id + ' fetchDepositAddressesByNetwork() is not supported yet')
713
834
 
714
- async def fetch_open_interest_history(self, symbol: str, timeframe='1h', since: Int = None, limit: Int = None, params={}):
835
+ async def fetch_open_interest_history(self, symbol: str, timeframe: str = '1h', since: Int = None, limit: Int = None, params={}):
715
836
  raise NotSupported(self.id + ' fetchOpenInterestHistory() is not supported yet')
716
837
 
717
838
  async def fetch_open_interest(self, symbol: str, params={}):
718
839
  raise NotSupported(self.id + ' fetchOpenInterest() is not supported yet')
719
840
 
841
+ async def fetch_open_interests(self, symbols: Strings = None, params={}):
842
+ raise NotSupported(self.id + ' fetchOpenInterests() is not supported yet')
843
+
720
844
  async def sign_in(self, params={}):
721
845
  raise NotSupported(self.id + ' signIn() is not supported yet')
722
846
 
723
847
  async def fetch_payment_methods(self, params={}):
724
848
  raise NotSupported(self.id + ' fetchPaymentMethods() is not supported yet')
725
849
 
726
- async def fetch_borrow_rate(self, code: str, amount, params={}):
850
+ async def fetch_borrow_rate(self, code: str, amount: float, params={}):
727
851
  raise NotSupported(self.id + ' fetchBorrowRate is deprecated, please use fetchCrossBorrowRate or fetchIsolatedBorrowRate instead')
728
852
 
729
- async def repay_cross_margin(self, code: str, amount, params={}):
853
+ async def repay_cross_margin(self, code: str, amount: float, params={}):
730
854
  raise NotSupported(self.id + ' repayCrossMargin is not support yet')
731
855
 
732
- async def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
856
+ async def repay_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
733
857
  raise NotSupported(self.id + ' repayIsolatedMargin is not support yet')
734
858
 
735
859
  async def borrow_cross_margin(self, code: str, amount: float, params={}):
@@ -738,10 +862,10 @@ class Exchange(BaseExchange):
738
862
  async def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
739
863
  raise NotSupported(self.id + ' borrowIsolatedMargin is not support yet')
740
864
 
741
- async def borrow_margin(self, code: str, amount, symbol: Str = None, params={}):
865
+ async def borrow_margin(self, code: str, amount: float, symbol: Str = None, params={}):
742
866
  raise NotSupported(self.id + ' borrowMargin is deprecated, please use borrowCrossMargin or borrowIsolatedMargin instead')
743
867
 
744
- async def repay_margin(self, code: str, amount, symbol: Str = None, params={}):
868
+ async def repay_margin(self, code: str, amount: float, symbol: Str = None, params={}):
745
869
  raise NotSupported(self.id + ' repayMargin is deprecated, please use repayCrossMargin or repayIsolatedMargin instead')
746
870
 
747
871
  async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}):
@@ -770,14 +894,18 @@ class Exchange(BaseExchange):
770
894
  maxRetries = self.safe_value(options, 'webApiRetries', 10)
771
895
  response = None
772
896
  retry = 0
897
+ shouldBreak = False
773
898
  while(retry < maxRetries):
774
899
  try:
775
900
  response = await getattr(self, endpointMethod)({})
901
+ shouldBreak = True
776
902
  break
777
903
  except Exception as e:
778
904
  retry = retry + 1
779
905
  if retry == maxRetries:
780
906
  raise e
907
+ if shouldBreak:
908
+ break # self is needed because of GO
781
909
  content = response
782
910
  if startRegex is not None:
783
911
  splitted_by_start = content.split(startRegex)
@@ -821,12 +949,30 @@ class Exchange(BaseExchange):
821
949
  if self.enableRateLimit:
822
950
  cost = self.calculate_rate_limiter_cost(api, method, path, params, config)
823
951
  await self.throttle(cost)
952
+ retries = None
953
+ retries, params = self.handle_option_and_params(params, path, 'maxRetriesOnFailure', 0)
954
+ retryDelay = None
955
+ retryDelay, params = self.handle_option_and_params(params, path, 'maxRetriesOnFailureDelay', 0)
824
956
  self.lastRestRequestTimestamp = self.milliseconds()
825
957
  request = self.sign(path, api, method, params, headers, body)
826
958
  self.last_request_headers = request['headers']
827
959
  self.last_request_body = request['body']
828
960
  self.last_request_url = request['url']
829
- return await self.fetch(request['url'], request['method'], request['headers'], request['body'])
961
+ for i in range(0, retries + 1):
962
+ try:
963
+ return await self.fetch(request['url'], request['method'], request['headers'], request['body'])
964
+ except Exception as e:
965
+ if isinstance(e, OperationFailed):
966
+ if i < retries:
967
+ if self.verbose:
968
+ self.log('Request failed with the error: ' + str(e) + ', retrying ' + (i + str(1)) + ' of ' + str(retries) + '...')
969
+ if (retryDelay is not None) and (retryDelay != 0):
970
+ await self.sleep(retryDelay)
971
+ else:
972
+ raise e
973
+ else:
974
+ raise e
975
+ return None # self line is never reached, but exists for c# value return requirement
830
976
 
831
977
  async def request(self, path, api: Any = 'public', method='GET', params={}, headers: Any = None, body: Any = None, config={}):
832
978
  return await self.fetch2(path, api, method, params, headers, body, config)
@@ -859,9 +1005,6 @@ class Exchange(BaseExchange):
859
1005
  await self.cancel_order_ws(id, symbol)
860
1006
  return await self.create_order_ws(symbol, type, side, amount, price, params)
861
1007
 
862
- async def fetch_permissions(self, params={}):
863
- raise NotSupported(self.id + ' fetchPermissions() is not supported yet')
864
-
865
1008
  async def fetch_position(self, symbol: str, params={}):
866
1009
  raise NotSupported(self.id + ' fetchPosition() is not supported yet')
867
1010
 
@@ -992,19 +1135,33 @@ class Exchange(BaseExchange):
992
1135
  else:
993
1136
  raise NotSupported(self.id + ' fetchTicker() is not supported yet')
994
1137
 
1138
+ async def fetch_mark_price(self, symbol: str, params={}):
1139
+ if self.has['fetchMarkPrices']:
1140
+ await self.load_markets()
1141
+ market = self.market(symbol)
1142
+ symbol = market['symbol']
1143
+ tickers = await self.fetch_mark_prices([symbol], params)
1144
+ ticker = self.safe_dict(tickers, symbol)
1145
+ if ticker is None:
1146
+ raise NullResponse(self.id + ' fetchMarkPrices() could not find a ticker for ' + symbol)
1147
+ else:
1148
+ return ticker
1149
+ else:
1150
+ raise NotSupported(self.id + ' fetchMarkPrices() is not supported yet')
1151
+
995
1152
  async def fetch_ticker_ws(self, symbol: str, params={}):
996
1153
  if self.has['fetchTickersWs']:
997
1154
  await self.load_markets()
998
1155
  market = self.market(symbol)
999
1156
  symbol = market['symbol']
1000
- tickers = await self.fetch_ticker_ws(symbol, params)
1157
+ tickers = await self.fetch_tickers_ws([symbol], params)
1001
1158
  ticker = self.safe_dict(tickers, symbol)
1002
1159
  if ticker is None:
1003
- raise NullResponse(self.id + ' fetchTickers() could not find a ticker for ' + symbol)
1160
+ raise NullResponse(self.id + ' fetchTickerWs() could not find a ticker for ' + symbol)
1004
1161
  else:
1005
1162
  return ticker
1006
1163
  else:
1007
- raise NotSupported(self.id + ' fetchTicker() is not supported yet')
1164
+ raise NotSupported(self.id + ' fetchTickerWs() is not supported yet')
1008
1165
 
1009
1166
  async def watch_ticker(self, symbol: str, params={}):
1010
1167
  raise NotSupported(self.id + ' watchTicker() is not supported yet')
@@ -1012,6 +1169,9 @@ class Exchange(BaseExchange):
1012
1169
  async def fetch_tickers(self, symbols: Strings = None, params={}):
1013
1170
  raise NotSupported(self.id + ' fetchTickers() is not supported yet')
1014
1171
 
1172
+ async def fetch_mark_prices(self, symbols: Strings = None, params={}):
1173
+ raise NotSupported(self.id + ' fetchMarkPrices() is not supported yet')
1174
+
1015
1175
  async def fetch_tickers_ws(self, symbols: Strings = None, params={}):
1016
1176
  raise NotSupported(self.id + ' fetchTickers() is not supported yet')
1017
1177
 
@@ -1024,6 +1184,9 @@ class Exchange(BaseExchange):
1024
1184
  async def watch_tickers(self, symbols: Strings = None, params={}):
1025
1185
  raise NotSupported(self.id + ' watchTickers() is not supported yet')
1026
1186
 
1187
+ async def un_watch_tickers(self, symbols: Strings = None, params={}):
1188
+ raise NotSupported(self.id + ' unWatchTickers() is not supported yet')
1189
+
1027
1190
  async def fetch_order(self, id: str, symbol: Str = None, params={}):
1028
1191
  raise NotSupported(self.id + ' fetchOrder() is not supported yet')
1029
1192
 
@@ -1042,7 +1205,19 @@ class Exchange(BaseExchange):
1042
1205
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1043
1206
  raise NotSupported(self.id + ' createOrder() is not supported yet')
1044
1207
 
1045
- async def create_trailing_amount_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingAmount=None, trailingTriggerPrice=None, params={}):
1208
+ async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}):
1209
+ raise NotSupported(self.id + ' createConvertTrade() is not supported yet')
1210
+
1211
+ async def fetch_convert_trade(self, id: str, code: Str = None, params={}):
1212
+ raise NotSupported(self.id + ' fetchConvertTrade() is not supported yet')
1213
+
1214
+ async def fetch_convert_trade_history(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1215
+ raise NotSupported(self.id + ' fetchConvertTradeHistory() is not supported yet')
1216
+
1217
+ async def fetch_position_mode(self, symbol: Str = None, params={}):
1218
+ raise NotSupported(self.id + ' fetchPositionMode() is not supported yet')
1219
+
1220
+ async def create_trailing_amount_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingAmount: Num = None, trailingTriggerPrice: Num = None, params={}):
1046
1221
  """
1047
1222
  create a trailing order by providing the symbol, type, side, amount, price and trailingAmount
1048
1223
  :param str symbol: unified symbol of the market to create an order in
@@ -1064,7 +1239,7 @@ class Exchange(BaseExchange):
1064
1239
  return await self.create_order(symbol, type, side, amount, price, params)
1065
1240
  raise NotSupported(self.id + ' createTrailingAmountOrder() is not supported yet')
1066
1241
 
1067
- async def create_trailing_amount_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingAmount=None, trailingTriggerPrice=None, params={}):
1242
+ async def create_trailing_amount_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingAmount: Num = None, trailingTriggerPrice: Num = None, params={}):
1068
1243
  """
1069
1244
  create a trailing order by providing the symbol, type, side, amount, price and trailingAmount
1070
1245
  :param str symbol: unified symbol of the market to create an order in
@@ -1086,7 +1261,7 @@ class Exchange(BaseExchange):
1086
1261
  return await self.create_order_ws(symbol, type, side, amount, price, params)
1087
1262
  raise NotSupported(self.id + ' createTrailingAmountOrderWs() is not supported yet')
1088
1263
 
1089
- async def create_trailing_percent_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingPercent=None, trailingTriggerPrice=None, params={}):
1264
+ async def create_trailing_percent_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingPercent: Num = None, trailingTriggerPrice: Num = None, params={}):
1090
1265
  """
1091
1266
  create a trailing order by providing the symbol, type, side, amount, price and trailingPercent
1092
1267
  :param str symbol: unified symbol of the market to create an order in
@@ -1108,7 +1283,7 @@ class Exchange(BaseExchange):
1108
1283
  return await self.create_order(symbol, type, side, amount, price, params)
1109
1284
  raise NotSupported(self.id + ' createTrailingPercentOrder() is not supported yet')
1110
1285
 
1111
- async def create_trailing_percent_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingPercent=None, trailingTriggerPrice=None, params={}):
1286
+ async def create_trailing_percent_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingPercent: Num = None, trailingTriggerPrice: Num = None, params={}):
1112
1287
  """
1113
1288
  create a trailing order by providing the symbol, type, side, amount, price and trailingPercent
1114
1289
  :param str symbol: unified symbol of the market to create an order in
@@ -1349,6 +1524,9 @@ class Exchange(BaseExchange):
1349
1524
  async def create_orders(self, orders: List[OrderRequest], params={}):
1350
1525
  raise NotSupported(self.id + ' createOrders() is not supported yet')
1351
1526
 
1527
+ async def edit_orders(self, orders: List[OrderRequest], params={}):
1528
+ raise NotSupported(self.id + ' editOrders() is not supported yet')
1529
+
1352
1530
  async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1353
1531
  raise NotSupported(self.id + ' createOrderWs() is not supported yet')
1354
1532
 
@@ -1435,6 +1613,9 @@ class Exchange(BaseExchange):
1435
1613
  async def fetch_greeks(self, symbol: str, params={}):
1436
1614
  raise NotSupported(self.id + ' fetchGreeks() is not supported yet')
1437
1615
 
1616
+ async def fetch_all_greeks(self, symbols: Strings = None, params={}):
1617
+ raise NotSupported(self.id + ' fetchAllGreeks() is not supported yet')
1618
+
1438
1619
  async def fetch_option_chain(self, code: str, params={}):
1439
1620
  raise NotSupported(self.id + ' fetchOptionChain() is not supported yet')
1440
1621
 
@@ -1455,10 +1636,10 @@ class Exchange(BaseExchange):
1455
1636
  """
1456
1637
  raise NotSupported(self.id + ' fetchDepositsWithdrawals() is not supported yet')
1457
1638
 
1458
- async def fetch_deposits(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1639
+ async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1459
1640
  raise NotSupported(self.id + ' fetchDeposits() is not supported yet')
1460
1641
 
1461
- async def fetch_withdrawals(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1642
+ async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1462
1643
  raise NotSupported(self.id + ' fetchWithdrawals() is not supported yet')
1463
1644
 
1464
1645
  async def fetch_deposits_ws(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
@@ -1557,66 +1738,66 @@ class Exchange(BaseExchange):
1557
1738
 
1558
1739
  async def create_post_only_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1559
1740
  if not self.has['createPostOnlyOrder']:
1560
- raise NotSupported(self.id + 'createPostOnlyOrder() is not supported yet')
1741
+ raise NotSupported(self.id + ' createPostOnlyOrder() is not supported yet')
1561
1742
  query = self.extend(params, {'postOnly': True})
1562
1743
  return await self.create_order(symbol, type, side, amount, price, query)
1563
1744
 
1564
1745
  async def create_post_only_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1565
1746
  if not self.has['createPostOnlyOrderWs']:
1566
- raise NotSupported(self.id + 'createPostOnlyOrderWs() is not supported yet')
1747
+ raise NotSupported(self.id + ' createPostOnlyOrderWs() is not supported yet')
1567
1748
  query = self.extend(params, {'postOnly': True})
1568
1749
  return await self.create_order_ws(symbol, type, side, amount, price, query)
1569
1750
 
1570
1751
  async def create_reduce_only_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1571
1752
  if not self.has['createReduceOnlyOrder']:
1572
- raise NotSupported(self.id + 'createReduceOnlyOrder() is not supported yet')
1753
+ raise NotSupported(self.id + ' createReduceOnlyOrder() is not supported yet')
1573
1754
  query = self.extend(params, {'reduceOnly': True})
1574
1755
  return await self.create_order(symbol, type, side, amount, price, query)
1575
1756
 
1576
1757
  async def create_reduce_only_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1577
1758
  if not self.has['createReduceOnlyOrderWs']:
1578
- raise NotSupported(self.id + 'createReduceOnlyOrderWs() is not supported yet')
1759
+ raise NotSupported(self.id + ' createReduceOnlyOrderWs() is not supported yet')
1579
1760
  query = self.extend(params, {'reduceOnly': True})
1580
1761
  return await self.create_order_ws(symbol, type, side, amount, price, query)
1581
1762
 
1582
- async def create_stop_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, stopPrice: Num = None, params={}):
1763
+ async def create_stop_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, triggerPrice: Num = None, params={}):
1583
1764
  if not self.has['createStopOrder']:
1584
1765
  raise NotSupported(self.id + ' createStopOrder() is not supported yet')
1585
- if stopPrice is None:
1766
+ if triggerPrice is None:
1586
1767
  raise ArgumentsRequired(self.id + ' create_stop_order() requires a stopPrice argument')
1587
- query = self.extend(params, {'stopPrice': stopPrice})
1768
+ query = self.extend(params, {'stopPrice': triggerPrice})
1588
1769
  return await self.create_order(symbol, type, side, amount, price, query)
1589
1770
 
1590
- async def create_stop_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, stopPrice: Num = None, params={}):
1771
+ async def create_stop_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, triggerPrice: Num = None, params={}):
1591
1772
  if not self.has['createStopOrderWs']:
1592
1773
  raise NotSupported(self.id + ' createStopOrderWs() is not supported yet')
1593
- if stopPrice is None:
1774
+ if triggerPrice is None:
1594
1775
  raise ArgumentsRequired(self.id + ' createStopOrderWs() requires a stopPrice argument')
1595
- query = self.extend(params, {'stopPrice': stopPrice})
1776
+ query = self.extend(params, {'stopPrice': triggerPrice})
1596
1777
  return await self.create_order_ws(symbol, type, side, amount, price, query)
1597
1778
 
1598
- async def create_stop_limit_order(self, symbol: str, side: OrderSide, amount: float, price: float, stopPrice: float, params={}):
1779
+ async def create_stop_limit_order(self, symbol: str, side: OrderSide, amount: float, price: float, triggerPrice: float, params={}):
1599
1780
  if not self.has['createStopLimitOrder']:
1600
1781
  raise NotSupported(self.id + ' createStopLimitOrder() is not supported yet')
1601
- query = self.extend(params, {'stopPrice': stopPrice})
1782
+ query = self.extend(params, {'stopPrice': triggerPrice})
1602
1783
  return await self.create_order(symbol, 'limit', side, amount, price, query)
1603
1784
 
1604
- async def create_stop_limit_order_ws(self, symbol: str, side: OrderSide, amount: float, price: float, stopPrice: float, params={}):
1785
+ async def create_stop_limit_order_ws(self, symbol: str, side: OrderSide, amount: float, price: float, triggerPrice: float, params={}):
1605
1786
  if not self.has['createStopLimitOrderWs']:
1606
1787
  raise NotSupported(self.id + ' createStopLimitOrderWs() is not supported yet')
1607
- query = self.extend(params, {'stopPrice': stopPrice})
1788
+ query = self.extend(params, {'stopPrice': triggerPrice})
1608
1789
  return await self.create_order_ws(symbol, 'limit', side, amount, price, query)
1609
1790
 
1610
- async def create_stop_market_order(self, symbol: str, side: OrderSide, amount: float, stopPrice: float, params={}):
1791
+ async def create_stop_market_order(self, symbol: str, side: OrderSide, amount: float, triggerPrice: float, params={}):
1611
1792
  if not self.has['createStopMarketOrder']:
1612
1793
  raise NotSupported(self.id + ' createStopMarketOrder() is not supported yet')
1613
- query = self.extend(params, {'stopPrice': stopPrice})
1794
+ query = self.extend(params, {'stopPrice': triggerPrice})
1614
1795
  return await self.create_order(symbol, 'market', side, amount, None, query)
1615
1796
 
1616
- async def create_stop_market_order_ws(self, symbol: str, side: OrderSide, amount: float, stopPrice: float, params={}):
1797
+ async def create_stop_market_order_ws(self, symbol: str, side: OrderSide, amount: float, triggerPrice: float, params={}):
1617
1798
  if not self.has['createStopMarketOrderWs']:
1618
1799
  raise NotSupported(self.id + ' createStopMarketOrderWs() is not supported yet')
1619
- query = self.extend(params, {'stopPrice': stopPrice})
1800
+ query = self.extend(params, {'stopPrice': triggerPrice})
1620
1801
  return await self.create_order_ws(symbol, 'market', side, amount, None, query)
1621
1802
 
1622
1803
  async def fetch_last_prices(self, symbols: Strings = None, params={}):
@@ -1653,7 +1834,23 @@ class Exchange(BaseExchange):
1653
1834
  else:
1654
1835
  raise NotSupported(self.id + ' fetchFundingRate() is not supported yet')
1655
1836
 
1656
- async def fetch_mark_ohlcv(self, symbol, timeframe='1m', since: Int = None, limit: Int = None, params={}):
1837
+ async def fetch_funding_interval(self, symbol: str, params={}):
1838
+ if self.has['fetchFundingIntervals']:
1839
+ await self.load_markets()
1840
+ market = self.market(symbol)
1841
+ symbol = market['symbol']
1842
+ if not market['contract']:
1843
+ raise BadSymbol(self.id + ' fetchFundingInterval() supports contract markets only')
1844
+ rates = await self.fetch_funding_intervals([symbol], params)
1845
+ rate = self.safe_value(rates, symbol)
1846
+ if rate is None:
1847
+ raise NullResponse(self.id + ' fetchFundingInterval() returned no data for ' + symbol)
1848
+ else:
1849
+ return rate
1850
+ else:
1851
+ raise NotSupported(self.id + ' fetchFundingInterval() is not supported yet')
1852
+
1853
+ async def fetch_mark_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}):
1657
1854
  """
1658
1855
  fetches historical mark price candlestick data containing the open, high, low, and close price of a market
1659
1856
  :param str symbol: unified symbol of the market to fetch OHLCV data for
@@ -1679,7 +1876,7 @@ class Exchange(BaseExchange):
1679
1876
  :param int [since]: timestamp in ms of the earliest candle to fetch
1680
1877
  :param int [limit]: the maximum amount of candles to fetch
1681
1878
  :param dict [params]: extra parameters specific to the exchange API endpoint
1682
- * @returns {} A list of candles ordered, open, high, low, close, None
1879
+ @returns {} A list of candles ordered, open, high, low, close, None
1683
1880
  """
1684
1881
  if self.has['fetchIndexOHLCV']:
1685
1882
  request: dict = {
@@ -1709,7 +1906,7 @@ class Exchange(BaseExchange):
1709
1906
 
1710
1907
  async def fetch_transactions(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1711
1908
  """
1712
- * @deprecated
1909
+ @deprecated
1713
1910
  *DEPRECATED* use fetchDepositsWithdrawals instead
1714
1911
  :param str code: unified currency code for the currency of the deposit/withdrawals, default is None
1715
1912
  :param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
@@ -1722,7 +1919,7 @@ class Exchange(BaseExchange):
1722
1919
  else:
1723
1920
  raise NotSupported(self.id + ' fetchTransactions() is not supported yet')
1724
1921
 
1725
- async def fetch_paginated_call_dynamic(self, method: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}, maxEntriesPerRequest: Int = None):
1922
+ async def fetch_paginated_call_dynamic(self, method: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}, maxEntriesPerRequest: Int = None, removeRepeated=True):
1726
1923
  maxCalls = None
1727
1924
  maxCalls, params = self.handle_option_and_params(params, method, 'paginationCalls', 10)
1728
1925
  maxRetries = None
@@ -1730,10 +1927,12 @@ class Exchange(BaseExchange):
1730
1927
  paginationDirection = None
1731
1928
  paginationDirection, params = self.handle_option_and_params(params, method, 'paginationDirection', 'backward')
1732
1929
  paginationTimestamp = None
1930
+ removeRepeatedOption = removeRepeated
1931
+ removeRepeatedOption, params = self.handle_option_and_params(params, method, 'removeRepeated', removeRepeated)
1733
1932
  calls = 0
1734
1933
  result = []
1735
1934
  errors = 0
1736
- until = self.safe_integer_2(params, 'untill', 'till') # do not omit it from params here
1935
+ until = self.safe_integer_n(params, ['until', 'untill', 'till']) # do not omit it from params here
1737
1936
  maxEntriesPerRequest, params = self.handle_max_entries_per_request_and_params(method, maxEntriesPerRequest, params)
1738
1937
  if (paginationDirection == 'forward'):
1739
1938
  if since is None:
@@ -1776,14 +1975,16 @@ class Exchange(BaseExchange):
1776
1975
  errors = 0
1777
1976
  result = self.array_concat(result, response)
1778
1977
  last = self.safe_value(response, responseLength - 1)
1779
- paginationTimestamp = self.safe_integer(last, 'timestamp') - 1
1978
+ paginationTimestamp = self.safe_integer(last, 'timestamp') + 1
1780
1979
  if (until is not None) and (paginationTimestamp >= until):
1781
1980
  break
1782
1981
  except Exception as e:
1783
1982
  errors += 1
1784
1983
  if errors > maxRetries:
1785
1984
  raise e
1786
- uniqueResults = self.remove_repeated_elements_from_array(result)
1985
+ uniqueResults = result
1986
+ if removeRepeatedOption:
1987
+ uniqueResults = self.remove_repeated_elements_from_array(result)
1787
1988
  key = 0 if (method == 'fetchOHLCV') else 'timestamp'
1788
1989
  return self.filter_by_since_limit(uniqueResults, since, limit, key)
1789
1990
 
@@ -1848,6 +2049,8 @@ class Exchange(BaseExchange):
1848
2049
  i = 0
1849
2050
  errors = 0
1850
2051
  result = []
2052
+ timeframe = self.safe_string(params, 'timeframe')
2053
+ params = self.omit(params, 'timeframe') # reading the timeframe from the method arguments to avoid changing the signature
1851
2054
  while(i < maxCalls):
1852
2055
  try:
1853
2056
  if cursorValue is not None:
@@ -1857,8 +2060,10 @@ class Exchange(BaseExchange):
1857
2060
  response = None
1858
2061
  if method == 'fetchAccounts':
1859
2062
  response = await getattr(self, method)(params)
1860
- elif method == 'getLeverageTiersPaginated':
2063
+ elif method == 'getLeverageTiersPaginated' or method == 'fetchPositions':
1861
2064
  response = await getattr(self, method)(symbol, params)
2065
+ elif method == 'fetchOpenInterestHistory':
2066
+ response = await getattr(self, method)(symbol, timeframe, since, maxEntriesPerRequest, params)
1862
2067
  else:
1863
2068
  response = await getattr(self, method)(symbol, since, maxEntriesPerRequest, params)
1864
2069
  errors = 0
@@ -1871,8 +2076,17 @@ class Exchange(BaseExchange):
1871
2076
  if responseLength == 0:
1872
2077
  break
1873
2078
  result = self.array_concat(result, response)
1874
- last = self.safe_value(response, responseLength - 1)
1875
- cursorValue = self.safe_value(last['info'], cursorReceived)
2079
+ last = self.safe_dict(response, responseLength - 1)
2080
+ # cursorValue = self.safe_value(last['info'], cursorReceived)
2081
+ cursorValue = None # search for the cursor
2082
+ for j in range(0, responseLength):
2083
+ index = responseLength - j - 1
2084
+ entry = self.safe_dict(response, index)
2085
+ info = self.safe_dict(entry, 'info')
2086
+ cursor = self.safe_value(info, cursorReceived)
2087
+ if cursor is not None:
2088
+ cursorValue = cursor
2089
+ break
1876
2090
  if cursorValue is None:
1877
2091
  break
1878
2092
  lastTimestamp = self.safe_integer(last, 'timestamp')
@@ -1929,7 +2143,7 @@ class Exchange(BaseExchange):
1929
2143
  """
1930
2144
  if self.has['fetchPositionsHistory']:
1931
2145
  positions = await self.fetch_positions_history([symbol], since, limit, params)
1932
- return self.safe_dict(positions, 0)
2146
+ return positions
1933
2147
  else:
1934
2148
  raise NotSupported(self.id + ' fetchPositionHistory() is not supported yet')
1935
2149