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,990 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
- # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
-
6
- import ccxt.async_support
7
- from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById
8
- from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Ticker, Trade
9
- from ccxt.async_support.base.ws.client import Client
10
- from typing import List
11
- from ccxt.base.errors import AuthenticationError
12
- from ccxt.base.errors import BadRequest
13
- from ccxt.base.errors import InvalidNonce
14
-
15
-
16
- class poloniexfutures(ccxt.async_support.poloniexfutures):
17
-
18
- def describe(self):
19
- return self.deep_extend(super(poloniexfutures, self).describe(), {
20
- 'has': {
21
- 'ws': True,
22
- 'cancelAllOrdersWs': False,
23
- 'cancelOrdersWs': False,
24
- 'cancelOrderWs': False,
25
- 'createOrderWs': False,
26
- 'editOrderWs': False,
27
- 'fetchBalanceWs': False,
28
- 'fetchOpenOrdersWs': False,
29
- 'fetchOrderWs': False,
30
- 'fetchTradesWs': False,
31
- 'watchOHLCV': False,
32
- 'watchOrderBook': True,
33
- 'watchTicker': True,
34
- 'watchTickers': False,
35
- 'watchTrades': True,
36
- 'watchBalance': True,
37
- 'watchOrders': True,
38
- 'watchMyTrades': False,
39
- 'watchPosition': None,
40
- 'watchPositions': False,
41
- },
42
- 'urls': {
43
- 'api': {
44
- 'ws': 'wss://futures-apiws.poloniex.com/endpoint',
45
- },
46
- },
47
- 'options': {
48
- 'tradesLimit': 1000,
49
- 'ordersLimit': 1000,
50
- 'watchTicker': {
51
- 'method': '/contractMarket/ticker', # can also be /contractMarket/snapshot
52
- },
53
- 'watchOrders': {
54
- 'method': '/contractMarket/tradeOrders', # can also be /contractMarket/advancedOrders
55
- },
56
- 'watchOrderBook': {
57
- 'method': '/contractMarket/level2', # can also be '/contractMarket/level3v2'
58
- 'snapshotDelay': 5,
59
- 'snapshotMaxRetries': 3,
60
- },
61
- 'streamLimit': 5, # called tunnels by poloniexfutures docs
62
- 'streamBySubscriptionsHash': {},
63
- 'streamIndex': -1,
64
- },
65
- 'streaming': {
66
- 'keepAlive': 30000,
67
- 'maxPingPongMisses': 2.0,
68
- },
69
- })
70
-
71
- async def negotiate(self, privateChannel, params={}):
72
- connectId = 'private' if privateChannel else 'public'
73
- urls = self.safe_value(self.options, 'urls', {})
74
- if connectId in urls:
75
- # return urls[connectId]
76
- storedFuture = urls[connectId]
77
- return await storedFuture
78
- # we store an awaitable to the url
79
- # so that multiple calls don't asynchronously
80
- # fetch different urls and overwrite each other
81
- urls[connectId] = self.spawn(self.negotiate_helper, privateChannel, params)
82
- self.options['urls'] = urls
83
- future = urls[connectId]
84
- return await future
85
-
86
- async def negotiate_helper(self, privateChannel, params={}):
87
- response = None
88
- connectId = 'private' if privateChannel else 'public'
89
- try:
90
- if privateChannel:
91
- response = await self.privatePostBulletPrivate(params)
92
- #
93
- # {
94
- # "code": "200000",
95
- # "data": {
96
- # "instanceServers": [
97
- # {
98
- # "pingInterval": 50000,
99
- # "endpoint": "wss://push-private.kucoin.com/endpoint",
100
- # "protocol": "websocket",
101
- # "encrypt": True,
102
- # "pingTimeout": 10000
103
- # }
104
- # ],
105
- # "token": "2neAiuYvAU61ZDXANAGAsiL4-iAExhsBXZxftpOeh_55i3Ysy2q2LEsEWU64mdzUOPusi34M_wGoSf7iNyEWJ1UQy47YbpY4zVdzilNP-Bj3iXzrjjGlWtiYB9J6i9GjsxUuhPw3BlrzazF6ghq4Lzf7scStOz3KkxjwpsOBCH4=.WNQmhZQeUKIkh97KYgU0Lg=="
106
- # }
107
- # }
108
- #
109
- else:
110
- response = await self.publicPostBulletPublic(params)
111
- data = self.safe_value(response, 'data', {})
112
- instanceServers = self.safe_value(data, 'instanceServers', [])
113
- firstInstanceServer = self.safe_value(instanceServers, 0)
114
- pingInterval = self.safe_integer(firstInstanceServer, 'pingInterval')
115
- endpoint = self.safe_string(firstInstanceServer, 'endpoint')
116
- token = self.safe_string(data, 'token')
117
- result = endpoint + '?' + self.urlencode({
118
- 'token': token,
119
- 'privateChannel': privateChannel,
120
- 'connectId': connectId,
121
- })
122
- client = self.client(result)
123
- client.keepAlive = pingInterval
124
- return result
125
- except Exception as e:
126
- future = self.safe_value(self.options['urls'], connectId)
127
- future.reject(e)
128
- del self.options['urls'][connectId]
129
- return None
130
-
131
- def request_id(self):
132
- requestId = self.sum(self.safe_integer(self.options, 'requestId', 0), 1)
133
- self.options['requestId'] = requestId
134
- return requestId
135
-
136
- async def subscribe(self, name: str, isPrivate: bool, symbol: Str = None, subscription=None, params={}):
137
- """
138
- * @ignore
139
- Connects to a websocket channel
140
- :param str name: name of the channel and suscriptionHash
141
- :param bool isPrivate: True for the authenticated url, False for the public url
142
- :param str symbol: is required for all public channels, not required for private channels(except position)
143
- :param dict subscription: subscription parameters
144
- :param dict [params]: extra parameters specific to the poloniex api
145
- :returns dict: data from the websocket stream
146
- """
147
- url = await self.negotiate(isPrivate)
148
- if symbol is not None:
149
- market = self.market(symbol)
150
- marketId = market['id']
151
- name += ':' + marketId
152
- messageHash = name
153
- tunnelId = await self.stream(url, messageHash)
154
- requestId = self.request_id()
155
- subscribe: dict = {
156
- 'id': requestId,
157
- 'type': 'subscribe',
158
- 'topic': name, # Subscribed topic. Some topics support subscribe to the data of multiple trading pairs through ",".
159
- 'privateChannel': isPrivate, # Adopt the private channel or not. Set by default.
160
- 'response': True, # Whether the server needs to return the receipt information of self subscription or not. Set by default.
161
- 'tunnelId': tunnelId,
162
- }
163
- subscriptionRequest: dict = {
164
- 'id': requestId,
165
- }
166
- if subscription is None:
167
- subscription = subscriptionRequest
168
- else:
169
- subscription = self.extend(subscriptionRequest, subscription)
170
- request = self.extend(subscribe, params)
171
- return await self.watch(url, messageHash, request, name, subscriptionRequest)
172
-
173
- def on_close(self, client, error):
174
- self.options['streamBySubscriptionsHash'] = {}
175
- super(poloniexfutures, self).on_close(client, error)
176
-
177
- async def stream(self, url, subscriptionHash):
178
- streamBySubscriptionsHash = self.safe_value(self.options, 'streamBySubscriptionsHash', {})
179
- stream = self.safe_string(streamBySubscriptionsHash, subscriptionHash)
180
- if stream is None:
181
- streamIndex = self.safe_integer(self.options, 'streamIndex', -1)
182
- streamLimit = self.safe_value(self.options, 'streamLimit')
183
- streamIndex = streamIndex + 1
184
- normalizedIndex = streamIndex % streamLimit
185
- self.options['streamIndex'] = streamIndex
186
- streamIndexString = self.number_to_string(normalizedIndex)
187
- stream = 'stream-' + streamIndexString
188
- self.options['streamBySubscriptionsHash'][subscriptionHash] = stream
189
- messageHash = 'tunnel:' + stream
190
- request: dict = {
191
- 'id': messageHash,
192
- 'type': 'openTunnel',
193
- 'newTunnelId': stream,
194
- 'response': True,
195
- }
196
- subscription: dict = {
197
- 'id': messageHash,
198
- 'method': self.handle_new_stream,
199
- }
200
- await self.watch(url, messageHash, request, messageHash, subscription)
201
- return stream
202
-
203
- def handle_order_book_subscription(self, client: Client, message, subscription):
204
- symbol = self.safe_string(subscription, 'symbol')
205
- limit = self.safe_integer(subscription, 'limit')
206
- self.orderbooks[symbol] = self.order_book({}, limit)
207
-
208
- def handle_subscription_status(self, client: Client, message):
209
- #
210
- # {
211
- # "id": "1578090438322",
212
- # "type": "ack"
213
- # }
214
- #
215
- id = self.safe_string(message, 'id')
216
- subscriptionsById = self.index_by(client.subscriptions, 'id')
217
- subscription = self.safe_value(subscriptionsById, id, {})
218
- method = self.safe_value(subscription, 'method')
219
- if method is not None:
220
- method(client, message, subscription)
221
- return message
222
-
223
- def handle_new_stream(self, client: Client, message, subscription):
224
- #
225
- # {
226
- # "id": "1545910840805",
227
- # "type": "ack"
228
- # }
229
- #
230
- messageHash = self.safe_string(message, 'id')
231
- client.resolve(message, messageHash)
232
-
233
- async def watch_ticker(self, symbol: str, params={}) -> Ticker:
234
- """
235
- watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
236
- :see: https://futures-docs.poloniex.com/#get-real-time-symbol-ticker
237
- :param str symbol: unified symbol of the market to fetch the ticker for
238
- :param dict [params]: extra parameters specific to the exchange API endpoint
239
- :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
240
- """
241
- await self.load_markets()
242
- symbol = self.symbol(symbol)
243
- name = '/contractMarket/ticker'
244
- return await self.subscribe(name, False, symbol, None, params)
245
-
246
- async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
247
- """
248
- get the list of most recent trades for a particular symbol
249
- :see: https://futures-docs.poloniex.com/#full-matching-engine-data-level-3
250
- :param str symbol: unified symbol of the market to fetch trades for
251
- :param int [since]: timestamp in ms of the earliest trade to fetch
252
- :param int [limit]: the maximum amount of trades to fetch
253
- :param dict [params]: extra parameters specific to the exchange API endpoint
254
- :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
255
- """
256
- await self.load_markets()
257
- options = self.safe_value(self.options, 'watchTrades')
258
- name = self.safe_string(options, 'method', '/contractMarket/execution') # can also be /contractMarket/snapshot
259
- name, params = self.handle_option_and_params(params, 'method', 'name', name)
260
- symbol = self.symbol(symbol)
261
- trades = await self.subscribe(name, False, symbol, None, params)
262
- if self.newUpdates:
263
- limit = trades.getLimit(symbol, limit)
264
- return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
265
-
266
- async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
267
- """
268
- watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
269
- :see: https://futures-docs.poloniex.com/#level-2-market-data
270
- :param str symbol: unified symbol of the market to fetch the order book for
271
- :param int [limit]: not used by poloniexfutures watchOrderBook
272
- :param dict [params]: extra parameters specific to the exchange API endpoint
273
- :param str [params.method]: the method to use. Defaults to /contractMarket/level2 can also be /contractMarket/level3v2 to receive the raw stream of orders
274
- :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
275
- """
276
- await self.load_markets()
277
- options = self.safe_value(self.options, 'watchOrderBook')
278
- name = self.safe_string(options, 'method', '/contractMarket/level2') # can also be /contractMarket/level2, /contractMarket/level2Depth5:{symbol}, /contractMarket/level2Depth50:{symbol}
279
- name, params = self.handle_option_and_params(params, 'method', 'name', name)
280
- if name == '/contractMarket/level2' and limit is not None:
281
- if limit != 5 and limit != 50:
282
- raise BadRequest(self.id + ' watchOrderBook limit argument must be none, 5 or 50 if using method /contractMarket/level2')
283
- name += 'Depth' + self.number_to_string(limit)
284
- subscription: dict = {
285
- 'symbol': symbol,
286
- 'limit': limit,
287
- 'method': self.handle_order_book_subscription,
288
- }
289
- orderbook = await self.subscribe(name, False, symbol, subscription, params)
290
- return orderbook.limit()
291
-
292
- async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
293
- """
294
- watches information on multiple orders made by the user
295
- :see: https://futures-docs.poloniex.com/#private-messages
296
- :param str symbol: filter by unified market symbol of the market orders were made in
297
- :param int [since]: the earliest time in ms to fetch orders for
298
- :param int [limit]: the maximum number of order structures to retrieve
299
- :param dict [params]: extra parameters specific to the exchange API endpoint
300
- :param str [params.method]: the method to use will default to /contractMarket/tradeOrders. Set to /contractMarket/advancedOrders to watch stop orders
301
- :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
302
- """
303
- await self.load_markets()
304
- options = self.safe_value(self.options, 'watchOrders')
305
- name = self.safe_string(options, 'method', '/contractMarket/tradeOrders')
306
- orders = await self.subscribe(name, True, None, None, params)
307
- if self.newUpdates:
308
- limit = orders.getLimit(symbol, limit)
309
- orders = self.filter_by_symbol_since_limit(orders, symbol, since, limit)
310
- length = len(orders)
311
- if length == 0:
312
- return await self.watch_orders(symbol, since, limit, params)
313
- return orders
314
-
315
- async def watch_balance(self, params={}) -> Balances:
316
- """
317
- watch balance and get the amount of funds available for trading or funds locked in orders
318
- :see: https://futures-docs.poloniex.com/#account-balance-events
319
- :param dict [params]: extra parameters specific to the exchange API endpoint
320
- :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
321
- """
322
- await self.load_markets()
323
- name = '/contractAccount/wallet'
324
- return await self.subscribe(name, True, None, None, params)
325
-
326
- def handle_trade(self, client: Client, message):
327
- #
328
- # {
329
- # "data": {
330
- # "makerUserId": "1410336",
331
- # "symbol": "BTCUSDTPERP",
332
- # "sequence": 267913,
333
- # "side": "buy",
334
- # "size": 2,
335
- # "price": 28409.5,
336
- # "takerOrderId": "6426f9f15782c8000776995f",
337
- # "makerOrderId": "6426f9f141406b0008df976e",
338
- # "takerUserId": "1410880",
339
- # "tradeId": "6426f9f1de029f0001e334dd",
340
- # "ts": 1680275953739092500,
341
- # },
342
- # "subject": "match",
343
- # "topic": "/contractMarket/execution:BTCUSDTPERP",
344
- # "type": "message",
345
- # }
346
- #
347
- data = self.safe_value(message, 'data', {})
348
- marketId = self.safe_string(data, 'symbol')
349
- if marketId is not None:
350
- trade = self.parse_ws_trade(data)
351
- symbol = trade['symbol']
352
- messageHash = '/contractMarket/execution:' + marketId
353
- stored = self.safe_value(self.trades, symbol)
354
- if stored is None:
355
- tradesLimit = self.safe_integer(self.options, 'tradesLimit', 1000)
356
- stored = ArrayCache(tradesLimit)
357
- self.trades[symbol] = stored
358
- stored.append(trade)
359
- client.resolve(stored, messageHash)
360
- return message
361
-
362
- def parse_ws_trade(self, trade, market=None):
363
- #
364
- # handleTrade
365
- #
366
- # {
367
- # "makerUserId": "1410880",
368
- # "symbol": "BTCUSDTPERP",
369
- # "sequence": 731390,
370
- # "side": "sell",
371
- # "size": 2,
372
- # "price": 29372.4,
373
- # "takerOrderId": "644ef0fdd64748000759218a",
374
- # "makerOrderId": "644ef0fd25f4a50007f12fc5",
375
- # "takerUserId": "1410880",
376
- # "tradeId": "644ef0fdde029f0001eec346",
377
- # "ts": 1682895101923194000
378
- # }
379
- #
380
- marketId = self.safe_string(trade, 'symbol')
381
- market = self.safe_market(marketId, market)
382
- timestamp = self.safe_integer_product(trade, 'ts', 0.000001)
383
- return self.safe_trade({
384
- 'info': trade,
385
- 'id': self.safe_string(trade, 'tradeId'),
386
- 'symbol': self.safe_string(market, 'symbol'),
387
- 'timestamp': timestamp,
388
- 'datetime': self.iso8601(timestamp),
389
- 'order': self.safe_string_2(trade, 'takerOrderId', 'makerOrderId'),
390
- 'type': None,
391
- 'side': self.safe_string(trade, 'side'),
392
- 'takerOrMaker': None,
393
- 'price': self.safe_string(trade, 'price'),
394
- 'amount': self.safe_string_2(trade, 'matchSize', 'size'),
395
- 'cost': None,
396
- 'fee': None,
397
- }, market)
398
-
399
- def parse_ws_order_trade(self, trade, market=None):
400
- #
401
- # {
402
- # "symbol": "BTC_USDT",
403
- # "type": "LIMIT",
404
- # "quantity": "1",
405
- # "orderId": "32471407854219264",
406
- # "tradeFee": "0",
407
- # "clientOrderId": "",
408
- # "accountType": "SPOT",
409
- # "feeCurrency": "",
410
- # "eventType": "place",
411
- # "source": "API",
412
- # "side": "BUY",
413
- # "filledQuantity": "0",
414
- # "filledAmount": "0",
415
- # "matchRole": "MAKER",
416
- # "state": "NEW",
417
- # "tradeTime": 0,
418
- # "tradeAmount": "0",
419
- # "orderAmount": "0",
420
- # "createTime": 1648708186922,
421
- # "price": "47112.1",
422
- # "tradeQty": "0",
423
- # "tradePrice": "0",
424
- # "tradeId": "0",
425
- # "ts": 1648708187469
426
- # }
427
- #
428
- timestamp = self.safe_integer(trade, 'tradeTime')
429
- marketId = self.safe_string(trade, 'symbol')
430
- return self.safe_trade({
431
- 'info': trade,
432
- 'id': self.safe_string(trade, 'tradeId'),
433
- 'symbol': self.safe_symbol(marketId, market),
434
- 'timestamp': timestamp,
435
- 'datetime': self.iso8601(timestamp),
436
- 'order': self.safe_string(trade, 'orderId'),
437
- 'type': self.safe_string_lower(trade, 'type'),
438
- 'side': self.safe_string(trade, 'side'),
439
- 'takerOrMaker': self.safe_string_lower(trade, 'matchRole'),
440
- 'price': self.safe_string(trade, 'price'),
441
- 'amount': self.safe_string(trade, 'tradeAmount'), # ? tradeQty?
442
- 'cost': None,
443
- 'fee': {
444
- 'rate': None,
445
- 'cost': self.safe_string(trade, 'tradeFee'),
446
- 'currency': self.safe_string(trade, 'feeCurrency'),
447
- },
448
- }, market)
449
-
450
- def handle_order(self, client: Client, message):
451
- #
452
- # {
453
- # "data": {
454
- # "symbol": "ADAUSDTPERP",
455
- # "orderType": "limit",
456
- # "side": "buy",
457
- # "canceledSize": "1",
458
- # "orderId": "642b4d4c0494cd0007c76813",
459
- # "type": "canceled",
460
- # "orderTime": "1680559436101909048",
461
- # "size": "1",
462
- # "filledSize": "0",
463
- # "marginType": 1,
464
- # "price": "0.25",
465
- # "remainSize": "0",
466
- # "clientOid": "112cbbf1-95a3-4917-957c-d3a87d81f853",
467
- # "status": "done",
468
- # "ts": 1680559677560686600
469
- # },
470
- # "subject": "orderChange",
471
- # "topic": "/contractMarket/tradeOrders",
472
- # "channelType": "private",
473
- # "type": "message",
474
- # "userId": "1139790"
475
- # }
476
- # stop order
477
- # {
478
- # "data": {
479
- # "orderType": "stop",
480
- # "symbol": "BTCUSDTPERP",
481
- # "side": "buy",
482
- # "stopPriceType": "TP",
483
- # "orderId": "64514fe1850d2100074378f6",
484
- # "type": "open",
485
- # "createdAt": 1683050465847,
486
- # "stopPrice": "29000",
487
- # "size": 2,
488
- # "stop": "up",
489
- # "marginType": 0,
490
- # "orderPrice": "28552.9",
491
- # "ts": 1683050465847597300
492
- # },
493
- # "subject": "stopOrder",
494
- # "topic": "/contractMarket/advancedOrders",
495
- # "channelType": "private",
496
- # "id": "64514fe1850d2100074378fa",
497
- # "type": "message",
498
- # "userId": "1160396"
499
- # }
500
- #
501
- data = self.safe_value(message, 'data', {})
502
- orders = self.orders
503
- if orders is None:
504
- limit = self.safe_integer(self.options, 'ordersLimit')
505
- orders = ArrayCacheBySymbolById(limit)
506
- self.orders = orders
507
- messageHash = '/contractMarket/tradeOrders'
508
- parsed = self.parse_ws_order(data)
509
- orders.append(parsed)
510
- client.resolve(orders, messageHash)
511
- return message
512
-
513
- def parse_order_status(self, status: str, type: str):
514
- """
515
- * @ignore
516
- :param str status: "match", "open", "done"
517
- :param str type: "open", "match", "filled", "canceled", "update"
518
- :returns str:
519
- """
520
- types: dict = {
521
- 'canceled': 'canceled',
522
- 'cancel': 'canceled',
523
- 'filled': 'closed',
524
- }
525
- parsedStatus = self.safe_string(types, type)
526
- if parsedStatus is None:
527
- statuses: dict = {
528
- 'open': 'open',
529
- 'match': 'open',
530
- 'done': 'closed',
531
- }
532
- parsedStatus = self.safe_string(statuses, status, status)
533
- return parsedStatus
534
-
535
- def parse_ws_order(self, order, market=None):
536
- #
537
- # {
538
- # "symbol": "ADAUSDTPERP",
539
- # "orderType": "limit",
540
- # "side": "buy",
541
- # "canceledSize": "1",
542
- # "orderId": "642b4d4c0494cd0007c76813",
543
- # "type": "canceled",
544
- # "orderTime": "1680559436101909048",
545
- # "size": "1",
546
- # "filledSize": "0",
547
- # "marginType": 1,
548
- # "price": "0.25",
549
- # "remainSize": "0",
550
- # "clientOid": "112cbbf1-95a3-4917-957c-d3a87d81f853",
551
- # "status": "done",
552
- # "ts": 1680559677560686600
553
- # }
554
- # stop
555
- # {
556
- # "orderType": "stop",
557
- # "symbol": "BTCUSDTPERP",
558
- # "side": "buy",
559
- # "stopPriceType": "TP",
560
- # "orderId": "64514fe1850d2100074378f6",
561
- # "type": "open",
562
- # "createdAt": 1683050465847,
563
- # "stopPrice": "29000",
564
- # "size": 2,
565
- # "stop": "up",
566
- # "marginType": 0,
567
- # "orderPrice": "28552.9",
568
- # "ts": 1683050465847597300
569
- # }
570
- #
571
- id = self.safe_string(order, 'orderId')
572
- clientOrderId = self.safe_string(order, 'clientOid')
573
- marketId = self.safe_string(order, 'symbol')
574
- timestamp = self.safe_integer_product_2(order, 'orderTime', 'ts', 0.000001)
575
- status = self.safe_string(order, 'status')
576
- messageType = self.safe_string(order, 'type')
577
- return self.safe_order({
578
- 'info': order,
579
- 'symbol': self.safe_symbol(marketId, market),
580
- 'id': id,
581
- 'clientOrderId': clientOrderId,
582
- 'timestamp': timestamp,
583
- 'datetime': self.iso8601(timestamp),
584
- 'lastTradeTimestamp': None,
585
- 'type': self.safe_string(order, 'orderType'),
586
- 'timeInForce': None,
587
- 'postOnly': None,
588
- 'side': self.safe_string(order, 'side'),
589
- 'price': self.safe_string_2(order, 'price', 'orderPrice'),
590
- 'stopPrice': self.safe_string(order, 'stopPrice'),
591
- 'triggerPrice': None,
592
- 'amount': self.safe_string(order, 'size'),
593
- 'cost': None,
594
- 'average': None,
595
- 'filled': self.safe_string(order, 'filledSize'),
596
- 'remaining': self.safe_string(order, 'remainSize'),
597
- 'status': self.parse_order_status(status, messageType),
598
- 'fee': None,
599
- 'trades': None,
600
- })
601
-
602
- def handle_ticker(self, client: Client, message):
603
- #
604
- # {
605
- # "subject": "ticker",
606
- # "topic": "/contractMarket/ticker:BTCUSDTPERP",
607
- # "data": {
608
- # "symbol": "BTCUSDTPERP", # Market of the symbol
609
- # "sequence": 45, # Sequence number which is used to judge the continuity of the pushed messages
610
- # "side": "sell", # Transaction side of the last traded taker order
611
- # "price": 3600.00, # Filled price
612
- # "size": 16, # Filled quantity
613
- # "tradeId": "5c9dcf4170744d6f5a3d32fb", # Order ID
614
- # "bestBidSize": 795, # Best bid size
615
- # "bestBidPrice": 3200.00, # Best bid
616
- # "bestAskPrice": 3600.00, # Best ask size
617
- # "bestAskSize": 284, # Best ask
618
- # "ts": 1553846081210004941 # Filled time - nanosecond
619
- # },
620
- # "type": "message",
621
- # }
622
- #
623
- # {
624
- # "topic": "/contractMarket/snapshot:BTCUSDTPERP",
625
- # "subject": "snapshot.24h",
626
- # "data": {
627
- # "volume": 30449670, #24h Volume
628
- # "turnover": 845169919063, #24h Turnover
629
- # "lastPrice": 3551, #Last price
630
- # "priceChgPct": 0.0043, #24h Change
631
- # "ts": 1547697294838004923 #Snapshot time(nanosecond)
632
- # }
633
- # }
634
- #
635
- data = self.safe_value(message, 'data', {})
636
- messageHash = self.safe_string(message, 'topic')
637
- symbol = self.get_symbol_from_topic(messageHash)
638
- if symbol is not None:
639
- ticker = self.parse_ticker(data)
640
- self.tickers[symbol] = ticker
641
- client.resolve(ticker, messageHash)
642
- return message
643
-
644
- def handle_l3_order_book(self, client: Client, message):
645
- #
646
- # {
647
- # "data": {
648
- # "symbol": "BTCUSDTPERP",
649
- # "sequence": 1679593048010,
650
- # "orderId": "6426fec8586b9500089d64d8",
651
- # "clientOid": "14e6ee8e-8757-462c-84db-ed12c2b62f55",
652
- # "ts": 1680277192127513900
653
- # },
654
- # "subject": "received",
655
- # "topic": "/contractMarket/level3v2:BTCUSDTPERP",
656
- # "type": "message"
657
- # }
658
- #
659
- # {
660
- # "data": {
661
- # "symbol": "BTCUSDTPERP",
662
- # "sequence": 1679593047982,
663
- # "side": "sell",
664
- # "orderTime": "1680277191900131371",
665
- # "size": "1",
666
- # "orderId": "6426fec7d32b6e000790268b",
667
- # "price": "28376.4",
668
- # "ts": 1680277191939042300
669
- # },
670
- # "subject": "open",
671
- # "topic": "/contractMarket/level3v2:BTCUSDTPERP",
672
- # "type": "message"
673
- # }
674
- #
675
- # {
676
- # "data": {
677
- # "symbol": "BTCUSDTPERP",
678
- # "reason": "canceled", # or "filled"
679
- # "sequence": 1679593047983,
680
- # "orderId": "6426fec74026fa0008e7046f",
681
- # "ts": 1680277191949842000
682
- # },
683
- # "subject": "done",
684
- # "topic": "/contractMarket/level3v2:BTCUSDTPERP",
685
- # "type": "message"
686
- # }
687
- #
688
- messageHash = self.safe_string(message, 'topic')
689
- subject = self.safe_string(message, 'subject')
690
- if subject == 'received':
691
- return
692
- # At the time of writting self, there is no implementation to easily convert each order into the orderbook so raw messages are returned
693
- client.resolve(message, messageHash)
694
-
695
- def handle_level_2(self, client: Client, message):
696
- # {
697
- # "subject": "level2",
698
- # "topic": "/contractMarket/level2:BTCUSDTPERP",
699
- # "type": "message",
700
- # "data": {
701
- # "sequence": 18, # Sequence number which is used to judge the continuity of pushed messages
702
- # "change": "5000.0,sell,83" # Price, side, quantity
703
- # "timestamp": 1551770400000
704
- # }
705
- # }
706
- topic = self.safe_string(message, 'topic')
707
- isSnapshot = topic.find('Depth') >= 0
708
- if isSnapshot:
709
- self.hande_l2_snapshot(client, message)
710
- return
711
- self.handle_l2_order_book(client, message)
712
-
713
- def handle_l2_order_book(self, client: Client, message):
714
- #
715
- # {
716
- # "id": 1545910660740,
717
- # "type": "subscribe",
718
- # "topic": "/contractMarket/level2:BTCUSDTPERP",
719
- # "response": True
720
- # }
721
- #
722
- # {
723
- # "subject": "level2",
724
- # "topic": "/contractMarket/level2:BTCUSDTPERP",
725
- # "type": "message",
726
- # "data": {
727
- # "sequence": 18, # Sequence number which is used to judge the continuity of pushed messages
728
- # "change": "5000.0,sell,83" # Price, side, quantity
729
- # "timestamp": 1551770400000
730
- # }
731
- # }
732
- #
733
- data = self.safe_value(message, 'data', {})
734
- messageHash = self.safe_string(message, 'topic', '')
735
- symbol = self.get_symbol_from_topic(messageHash)
736
- orderBook = self.safe_value(self.orderbooks, symbol)
737
- if orderBook is None:
738
- self.orderbooks[symbol] = self.order_book({})
739
- orderBook = self.orderbooks[symbol]
740
- orderBook['symbol'] = symbol
741
- nonce = self.safe_integer(orderBook, 'nonce')
742
- if nonce is None:
743
- cacheLength = len(orderBook.cache)
744
- snapshotDelay = self.handle_option('watchOrderBook', 'snapshotDelay', 5)
745
- if cacheLength == snapshotDelay:
746
- limit = 0
747
- self.spawn(self.load_order_book, client, messageHash, symbol, limit, {})
748
- orderBook.cache.append(data)
749
- return
750
- try:
751
- self.handle_delta(orderBook, data)
752
- client.resolve(orderBook, messageHash)
753
- except Exception as e:
754
- del self.orderbooks[symbol]
755
- client.reject(e, messageHash)
756
-
757
- def hande_l2_snapshot(self, client: Client, message):
758
- #
759
- # {
760
- # "type": "message",
761
- # "topic": "/contractMarket/level2Depth5:BTCUSDTPERP",
762
- # "subject": "level2",
763
- # "data": {
764
- # "asks": [
765
- # ["9993", "3"],
766
- # ["9992", "3"],
767
- # ["9991", "47"],
768
- # ["9990", "32"],
769
- # ["9989", "8"]
770
- # ],
771
- # "bids": [
772
- # ["9988", "56"],
773
- # ["9987", "15"],
774
- # ["9986", "100"],
775
- # ["9985", "10"],
776
- # ["9984", "10"]
777
- # ],
778
- # "timestamp": 1682993050531,
779
- # }
780
- # }
781
- #
782
- data = self.safe_value(message, 'data', {})
783
- messageHash = self.safe_string(message, 'topic', '')
784
- symbol = self.get_symbol_from_topic(messageHash)
785
- timestamp = self.safe_integer(data, 'timestamp')
786
- snapshot = self.parse_order_book(data, symbol, timestamp, 'bids', 'asks')
787
- orderbook = self.order_book(snapshot)
788
- self.orderbooks[symbol] = orderbook
789
- client.resolve(orderbook, messageHash)
790
-
791
- def get_symbol_from_topic(self, topic: str):
792
- splitTopic = topic.split(':')
793
- marketId = self.safe_string(splitTopic, 1)
794
- return self.safe_symbol(marketId)
795
-
796
- def get_cache_index(self, orderbook, cache):
797
- firstDelta = self.safe_value(cache, 0)
798
- nonce = self.safe_integer(orderbook, 'nonce')
799
- firstDeltaSequence = self.safe_integer(firstDelta, 'sequence')
800
- if firstDeltaSequence > nonce + 1:
801
- return -1
802
- for i in range(0, len(cache)):
803
- delta = cache[i]
804
- sequence = self.safe_integer(delta, 'sequence')
805
- if nonce == sequence - 1:
806
- return i
807
- return len(cache)
808
-
809
- def handle_delta(self, orderbook, delta):
810
- #
811
- # {
812
- # sequence: 123677914,
813
- # lastSequence: 123677913,
814
- # change: '80.36,buy,4924',
815
- # changes: ['80.19,buy,0',"80.15,buy,10794"],
816
- # timestamp: 1715643483528
817
- # },
818
- #
819
- sequence = self.safe_integer(delta, 'sequence')
820
- lastSequence = self.safe_integer(delta, 'lastSequence')
821
- nonce = self.safe_integer(orderbook, 'nonce')
822
- if nonce > sequence:
823
- return
824
- if nonce != lastSequence:
825
- raise InvalidNonce(self.id + ' watchOrderBook received an out-of-order nonce')
826
- changes = self.safe_list(delta, 'changes')
827
- for i in range(0, len(changes)):
828
- change = changes[i]
829
- splitChange = change.split(',')
830
- price = self.safe_number(splitChange, 0)
831
- side = self.safe_string(splitChange, 1)
832
- size = self.safe_number(splitChange, 2)
833
- orderBookSide = orderbook['bids'] if (side == 'buy') else orderbook['asks']
834
- orderBookSide.store(price, size)
835
- timestamp = self.safe_integer(delta, 'timestamp')
836
- orderbook['timestamp'] = timestamp
837
- orderbook['datetime'] = self.iso8601(timestamp)
838
- orderbook['nonce'] = sequence
839
-
840
- def handle_balance(self, client: Client, message):
841
- #
842
- # {
843
- # "data": {
844
- # "currency": "USDT",
845
- # "availableBalance": "4.0000000000",
846
- # "timestamp": "1680557568670"
847
- # },
848
- # "subject": "availableBalance.change",
849
- # "topic": "/contractAccount/wallet",
850
- # "channelType": "private",
851
- # "id": "642b4600cae86800074b5ab7",
852
- # "type": "message",
853
- # "userId": "1139790"
854
- # }
855
- #
856
- # {
857
- # "data": {
858
- # "currency": "USDT",
859
- # "orderMargin": "0.0000000000",
860
- # "timestamp": "1680558743307"
861
- # },
862
- # "subject": "orderMargin.change",
863
- # "topic": "/contractAccount/wallet",
864
- # "channelType": "private",
865
- # "id": "642b4a97b58e360007c3a237",
866
- # "type": "message",
867
- # "userId": "1139790"
868
- # }
869
- #
870
- data = self.safe_value(message, 'data', [])
871
- messageHash = '/contractAccount/wallet'
872
- currencyId = self.safe_string(data, 'currency')
873
- currency = self.currency(currencyId)
874
- code = currency['code']
875
- self.balance[code] = self.parse_ws_balance(data)
876
- client.resolve(self.balance[code], messageHash)
877
- return message
878
-
879
- def parse_ws_balance(self, response):
880
- #
881
- # {
882
- # "currency": "USDT",
883
- # "availableBalance": "4.0000000000",
884
- # "timestamp": "1680557568670"
885
- # }
886
- #
887
- # {
888
- # "currency": "USDT",
889
- # "orderMargin": "0.0000000000",
890
- # "timestamp": "1680558743307"
891
- # }
892
- #
893
- timestamp = self.safe_integer(response, 'timestamp')
894
- result: dict = {
895
- 'info': response,
896
- 'timestamp': timestamp,
897
- 'datetime': self.iso8601(timestamp),
898
- }
899
- currencyId = self.safe_string(response, 'currency')
900
- code = self.safe_currency_code(currencyId)
901
- newAccount = self.account()
902
- newAccount['free'] = self.safe_string(response, 'availableBalance')
903
- result[code] = newAccount
904
- return self.safe_balance(result)
905
-
906
- def handle_system_status(self, client: Client, message):
907
- #
908
- # {
909
- # "id": "1578090234088", # connectId
910
- # "type": "welcome",
911
- # }
912
- #
913
- return message
914
-
915
- def handle_subject(self, client: Client, message):
916
- subject = self.safe_string(message, 'subject')
917
- methods: dict = {
918
- 'auth': self.handle_authenticate,
919
- 'received': self.handle_l3_order_book,
920
- 'open': self.handle_l3_order_book,
921
- 'update': self.handle_l3_order_book,
922
- 'done': self.handle_l3_order_book,
923
- 'level2': self.handle_level_2,
924
- 'ticker': self.handle_ticker,
925
- 'snapshot.24h': self.handle_ticker,
926
- 'match': self.handle_trade,
927
- 'orderChange': self.handle_order,
928
- 'stopOrder': self.handle_order,
929
- 'availableBalance.change': self.handle_balance,
930
- 'orderMargin.change': self.handle_balance,
931
- }
932
- method = self.safe_value(methods, subject)
933
- if method is not None:
934
- method(client, message)
935
-
936
- def ping(self, client: Client):
937
- id = str(self.request_id())
938
- return {
939
- 'id': id,
940
- 'type': 'ping',
941
- }
942
-
943
- def handle_pong(self, client: Client, message):
944
- client.lastPong = self.milliseconds()
945
- return message
946
-
947
- def handle_error_message(self, client: Client, message):
948
- #
949
- # {
950
- # "code": 404,
951
- # "data": "tunnel stream-0 is not exist",
952
- # "id": "3",
953
- # "type": "error"
954
- # }
955
- #
956
- client.reject(message)
957
-
958
- def handle_message(self, client: Client, message):
959
- type = self.safe_string(message, 'type')
960
- methods: dict = {
961
- 'welcome': self.handle_system_status,
962
- 'ack': self.handle_subscription_status,
963
- 'message': self.handle_subject,
964
- 'pong': self.handle_pong,
965
- 'error': self.handle_error_message,
966
- }
967
- method = self.safe_value(methods, type)
968
- if method is not None:
969
- method(client, message)
970
-
971
- def handle_authenticate(self, client, message):
972
- #
973
- # {
974
- # "success": True,
975
- # "ret_msg": '',
976
- # "op": "auth",
977
- # "conn_id": "ce3dpomvha7dha97tvp0-2xh"
978
- # }
979
- #
980
- data = self.safe_value(message, 'data')
981
- success = self.safe_value(data, 'success')
982
- messageHash = 'authenticated'
983
- if success:
984
- client.resolve(message, messageHash)
985
- else:
986
- error = AuthenticationError(self.id + ' ' + self.json(message))
987
- client.reject(error, messageHash)
988
- if messageHash in client.subscriptions:
989
- del client.subscriptions[messageHash]
990
- return message