ccxt-ir 4.3.46.0.3__py2.py3-none-any.whl → 4.5.1__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 +8 -8
  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 +10 -10
  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 +32 -38
  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 +32 -27
  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 +34 -30
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +15 -14
  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 +30 -36
  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 +29 -24
  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 +32 -28
  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 +13 -12
  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.1.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.1.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.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.1.dist-info/licenses}/LICENSE.txt +0 -0
  529. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,7 @@
1
1
  import collections
2
+ import logging
2
3
 
4
+ logger = logging.getLogger(__name__)
3
5
 
4
6
  class Delegate:
5
7
  def __init__(self, name, delegated):
@@ -23,6 +25,7 @@ class BaseCache(list):
23
25
  __contains__ = Delegate('__contains__', '_deque')
24
26
  __reversed__ = Delegate('__reversed__', '_deque')
25
27
  clear = Delegate('clear', '_deque')
28
+ pop = Delegate('pop', '_deque')
26
29
 
27
30
  def __init__(self, max_size=None):
28
31
  super(BaseCache, self).__init__()
@@ -150,7 +153,10 @@ class ArrayCacheBySymbolById(ArrayCache):
150
153
  if len(self._deque) == self._deque.maxlen:
151
154
  delete_item = self._deque.popleft()
152
155
  self._index.popleft()
153
- del self.hashmap[delete_item['symbol']][delete_item['id']]
156
+ try:
157
+ del self.hashmap[delete_item['symbol']][delete_item['id']]
158
+ except Exception as e:
159
+ logger.error(f"Error deleting item from hashmap: {delete_item}. Error:{e}")
154
160
  self._deque.append(item)
155
161
  self._index.append(item['id'])
156
162
  if self._clear_all_updates:
@@ -184,7 +190,7 @@ class ArrayCacheBySymbolBySide(ArrayCache):
184
190
  if reference != item:
185
191
  reference.update(item)
186
192
  item = reference
187
- index = self._index.index(item['side'])
193
+ index = self._index.index(item['symbol'] + item['side'])
188
194
  del self._deque[index]
189
195
  del self._index[index]
190
196
  else:
@@ -194,7 +200,7 @@ class ArrayCacheBySymbolBySide(ArrayCache):
194
200
  self._index.popleft()
195
201
  del self.hashmap[delete_item['symbol']][delete_item['side']]
196
202
  self._deque.append(item)
197
- self._index.append(item['side'])
203
+ self._index.append(item['symbol'] + item['side'])
198
204
  if self._clear_all_updates:
199
205
  self._clear_all_updates = False
200
206
  self._clear_updates_by_symbol.clear()
@@ -1,16 +1,28 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- from asyncio import sleep, ensure_future, wait_for, TimeoutError
4
- from .functions import milliseconds, iso8601, deep_extend
5
- from ccxt import NetworkError, RequestTimeout, NotSupported
3
+ orjson = None
4
+ try:
5
+ import orjson as orjson
6
+ except ImportError:
7
+ pass
8
+
9
+ import json
10
+
11
+ from asyncio import sleep, ensure_future, wait_for, TimeoutError, BaseEventLoop, Future as asyncioFuture
12
+ from .functions import milliseconds, iso8601, deep_extend, is_json_encoded_object
13
+ from ccxt import NetworkError, RequestTimeout
6
14
  from ccxt.async_support.base.ws.future import Future
15
+ from ccxt.async_support.base.ws.functions import gunzip, inflate
16
+ from typing import Dict
17
+
18
+ from aiohttp import WSMsgType
7
19
 
8
20
 
9
21
  class Client(object):
10
22
 
11
23
  url = None
12
24
  ws = None
13
- futures = {}
25
+ futures: Dict[str, Future] = {}
14
26
  options = {} # ws-specific options
15
27
  subscriptions = {}
16
28
  rejections = {}
@@ -30,14 +42,15 @@ class Client(object):
30
42
  maxPingPongMisses = 2.0 # how many missed pongs to raise a timeout
31
43
  lastPong = None
32
44
  ping = None # ping-function if defined
45
+ proxy = None
33
46
  verbose = False # verbose output
34
47
  gunzip = False
35
48
  inflate = False
36
49
  throttle = None
37
50
  connecting = False
38
- asyncio_loop = None
51
+ asyncio_loop: BaseEventLoop = None
39
52
  ping_looper = None
40
- receive_looper = None
53
+ decompressBinary = True # decompress binary messages by default
41
54
 
42
55
  def __init__(self, url, on_message_callback, on_error_callback, on_close_callback, on_connected_callback, config={}):
43
56
  defaults = {
@@ -80,7 +93,7 @@ class Client(object):
80
93
  return result
81
94
 
82
95
  def reject(self, result, message_hash=None):
83
- if message_hash:
96
+ if message_hash is not None:
84
97
  if message_hash in self.futures:
85
98
  future = self.futures[message_hash]
86
99
  future.reject(result)
@@ -93,19 +106,41 @@ class Client(object):
93
106
  self.reject(result, message_hash)
94
107
  return result
95
108
 
96
- async def receive_loop(self):
109
+ def receive_loop(self):
97
110
  if self.verbose:
98
111
  self.log(iso8601(milliseconds()), 'receive loop')
99
- while not self.closed():
100
- try:
101
- message = await self.receive()
102
- # self.log(iso8601(milliseconds()), 'received', message)
103
- self.handle_message(message)
104
- except Exception as e:
105
- error = NetworkError(str(e))
106
- if self.verbose:
107
- self.log(iso8601(milliseconds()), 'receive_loop', 'Exception', error)
108
- self.reset(error)
112
+ if not self.closed():
113
+ # let's drain the aiohttp buffer to avoid latency
114
+ if len(self.buffer) > 1:
115
+ size_delta = 0
116
+ while len(self.buffer) > 1:
117
+ message, size = self.buffer.popleft()
118
+ size_delta += size
119
+ self.handle_message(message)
120
+ # we must update the size of the last message inside WebSocketDataQueue
121
+ # self.receive() calls WebSocketDataQueue.read() that calls WebSocketDataQueue._read_from_buffer()
122
+ # which updates the size of the buffer, the _size will overflow and pause the transport
123
+ # make sure to set the enviroment variable AIOHTTP_NO_EXTENSIONS=Y to check
124
+ # print(self.connection._conn.protocol._payload._size)
125
+ self.buffer[0] = (self.buffer[0][0], self.buffer[0][1] + size_delta)
126
+
127
+ task = self.asyncio_loop.create_task(self.receive())
128
+
129
+ def after_interrupt(resolved: asyncioFuture):
130
+ exception = resolved.exception()
131
+ if exception is None:
132
+ self.handle_message(resolved.result())
133
+ self.asyncio_loop.call_soon(self.receive_loop)
134
+ else:
135
+ error = NetworkError(str(exception))
136
+ if self.verbose:
137
+ self.log(iso8601(milliseconds()), 'receive_loop', 'Exception', error)
138
+ self.reject(error)
139
+
140
+ task.add_done_callback(after_interrupt)
141
+ else:
142
+ # connection got terminated after the connection was made and before the receive loop ran
143
+ self.on_close(1006)
109
144
 
110
145
  async def open(self, session, backoff_delay=0):
111
146
  # exponential backoff for consequent connections if necessary
@@ -126,7 +161,7 @@ class Client(object):
126
161
  self.on_connected_callback(self)
127
162
  # run both loops forever
128
163
  self.ping_looper = ensure_future(self.ping_loop(), loop=self.asyncio_loop)
129
- self.receive_looper = ensure_future(self.receive_loop(), loop=self.asyncio_loop)
164
+ self.asyncio_loop.call_soon(self.receive_loop)
130
165
  except TimeoutError:
131
166
  # connection timeout
132
167
  error = RequestTimeout('Connection timeout')
@@ -140,6 +175,13 @@ class Client(object):
140
175
  self.log(iso8601(milliseconds()), 'NetworkError', error)
141
176
  self.on_error(error)
142
177
 
178
+ @property
179
+ def buffer(self):
180
+ # looks like they exposed it in C
181
+ # this means we can bypass it
182
+ # https://github.com/aio-libs/aiohttp/blob/master/aiohttp/_websocket/reader_c.pxd#L53C24-L53C31
183
+ return self.connection._conn.protocol._payload._buffer
184
+
143
185
  def connect(self, session, backoff_delay=0):
144
186
  if not self.connection and not self.connecting:
145
187
  self.connecting = True
@@ -150,7 +192,7 @@ class Client(object):
150
192
  if self.verbose:
151
193
  self.log(iso8601(milliseconds()), 'on_error', error)
152
194
  self.error = error
153
- self.reset(error)
195
+ self.reject(error)
154
196
  self.on_error_callback(self, error)
155
197
  if not self.closed():
156
198
  ensure_future(self.close(1006), loop=self.asyncio_loop)
@@ -159,35 +201,128 @@ class Client(object):
159
201
  if self.verbose:
160
202
  self.log(iso8601(milliseconds()), 'on_close', code)
161
203
  if not self.error:
162
- self.reset(NetworkError('Connection closed by remote server, closing code ' + str(code)))
204
+ self.reject(NetworkError('Connection closed by remote server, closing code ' + str(code)))
163
205
  self.on_close_callback(self, code)
164
- if not self.closed():
165
- ensure_future(self.close(code), loop=self.asyncio_loop)
206
+ ensure_future(self.aiohttp_close(), loop=self.asyncio_loop)
166
207
 
167
- def reset(self, error):
168
- self.reject(error)
208
+ def log(self, *args):
209
+ print(*args)
169
210
 
170
- async def ping_loop(self):
171
- if self.verbose:
172
- self.log(iso8601(milliseconds()), 'ping loop')
211
+ def closed(self):
212
+ return (self.connection is None) or self.connection.closed
173
213
 
174
214
  def receive(self):
175
- raise NotSupported('receive() not implemented')
215
+ return self.connection.receive()
216
+
217
+ # helper method for binary and text messages
218
+ def handle_text_or_binary_message(self, data):
219
+ if self.verbose:
220
+ self.log(iso8601(milliseconds()), 'message', data)
221
+ if isinstance(data, bytes):
222
+ if self.decompressBinary:
223
+ data = data.decode()
224
+ # decoded = json.loads(data) if is_json_encoded_object(data) else data
225
+ decode = None
226
+ if is_json_encoded_object(data):
227
+ if orjson is None:
228
+ decode = json.loads(data)
229
+ else:
230
+ decode = orjson.loads(data)
231
+ else:
232
+ decode = data
233
+ self.on_message_callback(self, decode)
176
234
 
177
235
  def handle_message(self, message):
178
- raise NotSupported('handle_message() not implemented')
236
+ # self.log(iso8601(milliseconds()), message)
237
+ if message.type == WSMsgType.TEXT:
238
+ self.handle_text_or_binary_message(message.data)
239
+ elif message.type == WSMsgType.BINARY:
240
+ data = message.data
241
+ if self.gunzip:
242
+ data = gunzip(data)
243
+ elif self.inflate:
244
+ data = inflate(data)
245
+ self.handle_text_or_binary_message(data)
246
+ # autoping is responsible for automatically replying with pong
247
+ # to a ping incoming from a server, we have to disable autoping
248
+ # with aiohttp's websockets and respond with pong manually
249
+ # otherwise aiohttp's websockets client won't trigger WSMsgType.PONG
250
+ elif message.type == WSMsgType.PING:
251
+ if self.verbose:
252
+ self.log(iso8601(milliseconds()), 'ping', message)
253
+ ensure_future(self.connection.pong(message.data), loop=self.asyncio_loop)
254
+ elif message.type == WSMsgType.PONG:
255
+ self.lastPong = milliseconds()
256
+ if self.verbose:
257
+ self.log(iso8601(milliseconds()), 'pong', message)
258
+ pass
259
+ elif message.type == WSMsgType.CLOSE:
260
+ if self.verbose:
261
+ self.log(iso8601(milliseconds()), 'close', self.closed(), message)
262
+ self.on_close(message.data)
263
+ elif message.type == WSMsgType.ERROR:
264
+ if self.verbose:
265
+ self.log(iso8601(milliseconds()), 'error', message)
266
+ error = NetworkError(str(message))
267
+ self.on_error(error)
179
268
 
180
- def closed(self):
181
- raise NotSupported('closed() not implemented')
269
+ def create_connection(self, session):
270
+ # autoping is responsible for automatically replying with pong
271
+ # to a ping incoming from a server, we have to disable autoping
272
+ # with aiohttp's websockets and respond with pong manually
273
+ # otherwise aiohttp's websockets client won't trigger WSMsgType.PONG
274
+ # call aenter here to simulate async with otherwise we get the error "await not called with future"
275
+ # if connecting to a non-existent endpoint
276
+ if (self.proxy):
277
+ return session.ws_connect(self.url, autoping=False, autoclose=False, headers=self.options.get('headers'), proxy=self.proxy, max_msg_size=10485760).__aenter__()
278
+ return session.ws_connect(self.url, autoping=False, autoclose=False, headers=self.options.get('headers'), max_msg_size=10485760).__aenter__()
182
279
 
183
280
  async def send(self, message):
184
- raise NotSupported('send() not implemented')
281
+ if self.verbose:
282
+ self.log(iso8601(milliseconds()), 'sending', message)
283
+ send_msg = None
284
+ if isinstance(message, str):
285
+ send_msg = message
286
+ else:
287
+ if orjson is None:
288
+ send_msg = json.dumps(message, separators=(',', ':'))
289
+ else:
290
+ send_msg = orjson.dumps(message).decode('utf-8')
291
+ return await self.connection.send_str(send_msg)
185
292
 
186
293
  async def close(self, code=1000):
187
- raise NotSupported('close() not implemented')
294
+ if self.verbose:
295
+ self.log(iso8601(milliseconds()), 'closing', code)
296
+ for future in self.futures.values():
297
+ future.cancel()
298
+ await self.aiohttp_close()
188
299
 
189
- def create_connection(self, session):
190
- raise NotSupported('create_connection() not implemented')
300
+ async def aiohttp_close(self):
301
+ if not self.closed():
302
+ await self.connection.close()
303
+ # these will end automatically once self.closed() = True
304
+ # so we don't need to cancel them
305
+ if self.ping_looper:
306
+ self.ping_looper.cancel()
191
307
 
192
- def log(self, *args):
193
- print(*args)
308
+ async def ping_loop(self):
309
+ if self.verbose:
310
+ self.log(iso8601(milliseconds()), 'ping loop')
311
+ while self.keepAlive and not self.closed():
312
+ now = milliseconds()
313
+ self.lastPong = now if self.lastPong is None else self.lastPong
314
+ if (self.lastPong + self.keepAlive * self.maxPingPongMisses) < now:
315
+ self.on_error(RequestTimeout('Connection to ' + self.url + ' timed out due to a ping-pong keepalive missing on time'))
316
+ # the following ping-clause is not necessary with aiohttp's built-in ws
317
+ # since it has a heartbeat option (see create_connection above)
318
+ # however some exchanges require a text-type ping message
319
+ # therefore we need this clause anyway
320
+ else:
321
+ if self.ping:
322
+ try:
323
+ await self.send(self.ping(self))
324
+ except Exception as e:
325
+ self.on_error(e)
326
+ else:
327
+ await self.connection.ping()
328
+ await sleep(self.keepAlive / 1000)
@@ -1,10 +1,10 @@
1
1
  import asyncio
2
- from ccxt import ExchangeClosedByUser
3
2
 
3
+ # Test by running:
4
+ # - python python/ccxt/pro/test/base/test_close.py
5
+ # - python python/ccxt/pro/test/base/test_future.py
4
6
  class Future(asyncio.Future):
5
7
 
6
- is_race_future = False
7
-
8
8
  def resolve(self, result=None):
9
9
  if not self.done():
10
10
  self.set_result(result)
@@ -16,43 +16,31 @@ class Future(asyncio.Future):
16
16
  @classmethod
17
17
  def race(cls, futures):
18
18
  future = Future()
19
- for f in futures:
20
- f.is_race_future = True
21
19
  coro = asyncio.wait(futures, return_when=asyncio.FIRST_COMPLETED)
22
20
  task = asyncio.create_task(coro)
23
21
 
24
22
  def callback(done):
25
- try:
26
- complete, pending = done.result()
27
- # check for exceptions
28
- for i, f in enumerate(complete):
29
- try:
30
- f.result()
31
- except ExchangeClosedByUser as e:
32
- if len(pending) == 0 and i == len(complete) - 1:
33
- future.reject(e)
34
- # wait for all the sub promises to be reject before rejecting future
35
- continue
36
- except asyncio.CancelledError as e:
37
- continue
38
- except Exception as e:
39
- future.reject(e)
40
- return
41
- # no exceptions return first result
42
- futures_list = list(complete)
43
-
44
- are_all_canceled = all([f.cancelled() for f in futures_list])
45
- if are_all_canceled:
46
- future.reject(ExchangeClosedByUser('Connection closed by the user'))
47
- return
48
-
49
- first = futures_list[0]
50
-
51
- first_result = first.result()
52
- future.resolve(first_result)
53
- except asyncio.CancelledError as e:
54
- future.reject(e)
55
- except Exception as e:
56
- future.reject(e)
23
+ complete, _ = done.result()
24
+ # check for exceptions
25
+ exceptions = []
26
+ cancelled = False
27
+ for f in complete:
28
+ if f.cancelled():
29
+ cancelled = True
30
+ else:
31
+ err = f.exception()
32
+ if err:
33
+ exceptions.append(err)
34
+ # if any exceptions return with first exception
35
+ if future.cancelled():
36
+ return
37
+ if len(exceptions) > 0:
38
+ future.set_exception(exceptions[0])
39
+ # else return first result
40
+ elif cancelled:
41
+ future.cancel()
42
+ else:
43
+ first_result = list(complete)[0].result()
44
+ future.set_result(first_result)
57
45
  task.add_done_callback(callback)
58
46
  return future
@@ -5,19 +5,21 @@
5
5
 
6
6
  from ccxt.async_support.hitbtc import hitbtc
7
7
  from ccxt.abstract.bequant import ImplicitAPI
8
+ from ccxt.base.types import Any
8
9
 
9
10
 
10
11
  class bequant(hitbtc, ImplicitAPI):
11
12
 
12
- def describe(self):
13
+ def describe(self) -> Any:
13
14
  return self.deep_extend(super(bequant, self).describe(), {
14
15
  'id': 'bequant',
15
16
  'name': 'Bequant',
16
- 'countries': ['MT'], # Malta
17
17
  'pro': True,
18
+ 'countries': ['MT'], # Malta
18
19
  'urls': {
19
- 'logo': 'https://user-images.githubusercontent.com/1294454/55248342-a75dfe00-525a-11e9-8aa2-05e9dca943c6.jpg',
20
+ 'logo': 'https://github.com/user-attachments/assets/0583ef1f-29fe-4b7c-8189-63565a0e2867',
20
21
  'api': {
22
+ # v3
21
23
  'public': 'https://api.bequant.io/api/3',
22
24
  'private': 'https://api.bequant.io/api/3',
23
25
  },