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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (528) hide show
  1. ccxt/__init__.py +39 -35
  2. ccxt/abantether.py +9 -9
  3. ccxt/abstract/alpaca.py +4 -0
  4. ccxt/abstract/apex.py +31 -0
  5. ccxt/abstract/bigone.py +1 -1
  6. ccxt/abstract/binance.py +106 -48
  7. ccxt/abstract/binancecoinm.py +106 -48
  8. ccxt/abstract/binanceus.py +141 -83
  9. ccxt/abstract/binanceusdm.py +106 -48
  10. ccxt/abstract/bingx.py +50 -1
  11. ccxt/abstract/bitbank.py +5 -0
  12. ccxt/abstract/bitfinex.py +136 -65
  13. ccxt/abstract/bitflyer.py +1 -0
  14. ccxt/abstract/bitget.py +67 -0
  15. ccxt/abstract/bitmart.py +19 -1
  16. ccxt/abstract/bitopro.py +1 -0
  17. ccxt/abstract/bitrue.py +68 -68
  18. ccxt/abstract/bitstamp.py +1 -0
  19. ccxt/abstract/blofin.py +30 -0
  20. ccxt/abstract/btcbox.py +2 -0
  21. ccxt/abstract/bybit.py +28 -13
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbaseexchange.py +1 -0
  24. ccxt/abstract/coinbaseinternational.py +1 -1
  25. ccxt/abstract/cryptocom.py +16 -0
  26. ccxt/abstract/cryptomus.py +20 -0
  27. ccxt/abstract/defx.py +69 -0
  28. ccxt/abstract/deribit.py +1 -0
  29. ccxt/abstract/derive.py +117 -0
  30. ccxt/abstract/digifinex.py +1 -0
  31. ccxt/abstract/ellipx.py +25 -0
  32. ccxt/abstract/foxbit.py +26 -0
  33. ccxt/abstract/gate.py +19 -0
  34. ccxt/abstract/gateio.py +19 -0
  35. ccxt/abstract/gemini.py +1 -0
  36. ccxt/abstract/hibachi.py +26 -0
  37. ccxt/abstract/hyperliquid.py +1 -1
  38. ccxt/abstract/independentreserve.py +6 -0
  39. ccxt/abstract/kraken.py +1 -0
  40. ccxt/abstract/krakenfutures.py +4 -0
  41. ccxt/abstract/kucoin.py +10 -0
  42. ccxt/abstract/kucoinfutures.py +18 -0
  43. ccxt/abstract/lbank.py +2 -1
  44. ccxt/abstract/luno.py +1 -0
  45. ccxt/abstract/mexc.py +2 -0
  46. ccxt/abstract/modetrade.py +119 -0
  47. ccxt/abstract/myokx.py +349 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +25 -0
  50. ccxt/abstract/okxus.py +349 -0
  51. ccxt/abstract/onetrading.py +0 -12
  52. ccxt/abstract/paradex.py +23 -0
  53. ccxt/abstract/phemex.py +2 -0
  54. ccxt/abstract/poloniex.py +36 -0
  55. ccxt/abstract/tradeogre.py +3 -1
  56. ccxt/abstract/upbit.py +51 -34
  57. ccxt/abstract/whitebit.py +16 -0
  58. ccxt/abstract/woo.py +64 -6
  59. ccxt/abstract/xt.py +10 -5
  60. ccxt/afratether.py +7 -7
  61. ccxt/alpaca.py +828 -51
  62. ccxt/apex.py +1875 -0
  63. ccxt/arzinja.py +7 -7
  64. ccxt/arzplus.py +9 -9
  65. ccxt/ascendex.py +501 -306
  66. ccxt/async_support/__init__.py +39 -35
  67. ccxt/async_support/abantether.py +10 -10
  68. ccxt/async_support/afratether.py +9 -9
  69. ccxt/async_support/alpaca.py +828 -51
  70. ccxt/async_support/apex.py +1875 -0
  71. ccxt/async_support/arzinja.py +10 -10
  72. ccxt/async_support/arzplus.py +12 -12
  73. ccxt/async_support/ascendex.py +502 -306
  74. ccxt/async_support/base/exchange.py +303 -89
  75. ccxt/async_support/base/ws/cache.py +9 -3
  76. ccxt/async_support/base/ws/client.py +173 -38
  77. ccxt/async_support/base/ws/future.py +25 -37
  78. ccxt/async_support/bequant.py +5 -3
  79. ccxt/async_support/bigone.py +279 -144
  80. ccxt/async_support/binance.py +2347 -1158
  81. ccxt/async_support/binancecoinm.py +9 -3
  82. ccxt/async_support/binanceus.py +17 -3
  83. ccxt/async_support/binanceusdm.py +9 -4
  84. ccxt/async_support/bingx.py +2962 -920
  85. ccxt/async_support/bit2c.py +147 -27
  86. ccxt/async_support/bitbank.py +151 -23
  87. ccxt/async_support/bitbns.py +104 -30
  88. ccxt/async_support/bitfinex.py +3291 -1113
  89. ccxt/async_support/bitflyer.py +202 -27
  90. ccxt/async_support/bitget.py +3683 -1538
  91. ccxt/async_support/bithumb.py +195 -38
  92. ccxt/async_support/bitimen.py +12 -12
  93. ccxt/async_support/bitir.py +38 -38
  94. ccxt/async_support/bitmart.py +1288 -350
  95. ccxt/async_support/bitmex.py +260 -75
  96. ccxt/async_support/bitopro.py +262 -62
  97. ccxt/async_support/bitpin.py +17 -16
  98. ccxt/async_support/bitrue.py +459 -290
  99. ccxt/async_support/bitso.py +199 -54
  100. ccxt/async_support/bitstamp.py +230 -96
  101. ccxt/async_support/bitteam.py +167 -25
  102. ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
  103. ccxt/async_support/bitvavo.py +213 -49
  104. ccxt/async_support/blockchaincom.py +160 -46
  105. ccxt/async_support/blofin.py +502 -120
  106. ccxt/async_support/btcalpha.py +169 -31
  107. ccxt/async_support/btcbox.py +292 -23
  108. ccxt/async_support/btcmarkets.py +211 -58
  109. ccxt/async_support/btcturk.py +161 -38
  110. ccxt/async_support/bybit.py +1775 -1030
  111. ccxt/async_support/cex.py +1440 -1303
  112. ccxt/async_support/coinbase.py +724 -212
  113. ccxt/async_support/coinbaseadvanced.py +2 -1
  114. ccxt/async_support/coinbaseexchange.py +388 -89
  115. ccxt/async_support/coinbaseinternational.py +412 -57
  116. ccxt/async_support/coincatch.py +177 -78
  117. ccxt/async_support/coincheck.py +135 -19
  118. ccxt/async_support/coinex.py +606 -232
  119. ccxt/async_support/coinmate.py +189 -63
  120. ccxt/async_support/coinmetro.py +195 -54
  121. ccxt/async_support/coinone.py +158 -51
  122. ccxt/async_support/coinsph.py +336 -61
  123. ccxt/async_support/coinspot.py +151 -52
  124. ccxt/async_support/cryptocom.py +661 -111
  125. ccxt/async_support/cryptomus.py +1137 -0
  126. ccxt/async_support/defx.py +2071 -0
  127. ccxt/async_support/delta.py +299 -99
  128. ccxt/async_support/deribit.py +348 -126
  129. ccxt/async_support/derive.py +2572 -0
  130. ccxt/async_support/digifinex.py +430 -214
  131. ccxt/async_support/ellipx.py +2029 -0
  132. ccxt/async_support/eterex.py +10 -10
  133. ccxt/async_support/excoino.py +31 -31
  134. ccxt/async_support/exir.py +14 -14
  135. ccxt/async_support/exmo.py +344 -131
  136. ccxt/async_support/exnovin.py +10 -10
  137. ccxt/async_support/farhadexchange.py +12 -12
  138. ccxt/async_support/fmfwio.py +2 -1
  139. ccxt/async_support/foxbit.py +1935 -0
  140. ccxt/async_support/gate.py +1351 -529
  141. ccxt/async_support/gateio.py +2 -1
  142. ccxt/async_support/gemini.py +144 -39
  143. ccxt/async_support/hashkey.py +152 -109
  144. ccxt/async_support/hibachi.py +2080 -0
  145. ccxt/async_support/hitbtc.py +395 -167
  146. ccxt/async_support/hitobit.py +12 -12
  147. ccxt/async_support/hollaex.py +307 -119
  148. ccxt/async_support/htx.py +851 -383
  149. ccxt/async_support/huobi.py +2 -1
  150. ccxt/async_support/hyperliquid.py +1848 -536
  151. ccxt/async_support/independentreserve.py +288 -15
  152. ccxt/async_support/indodax.py +190 -33
  153. ccxt/async_support/jibitex.py +12 -12
  154. ccxt/async_support/kraken.py +795 -351
  155. ccxt/async_support/krakenfutures.py +214 -62
  156. ccxt/async_support/kucoin.py +715 -396
  157. ccxt/async_support/kucoinfutures.py +652 -89
  158. ccxt/async_support/latoken.py +217 -113
  159. ccxt/async_support/lbank.py +425 -97
  160. ccxt/async_support/luno.py +382 -35
  161. ccxt/async_support/mercado.py +113 -6
  162. ccxt/async_support/mexc.py +874 -437
  163. ccxt/async_support/modetrade.py +2818 -0
  164. ccxt/async_support/myokx.py +54 -0
  165. ccxt/async_support/ndax.py +221 -64
  166. ccxt/async_support/nobitex.py +31 -37
  167. ccxt/async_support/novadax.py +190 -34
  168. ccxt/async_support/oceanex.py +217 -28
  169. ccxt/async_support/okcoin.py +253 -145
  170. ccxt/async_support/okexchange.py +11 -11
  171. ccxt/async_support/okx.py +1088 -351
  172. ccxt/async_support/okxus.py +54 -0
  173. ccxt/async_support/ompfinex.py +25 -24
  174. ccxt/async_support/onetrading.py +213 -392
  175. ccxt/async_support/oxfun.py +245 -166
  176. ccxt/async_support/p2b.py +151 -29
  177. ccxt/async_support/paradex.py +562 -49
  178. ccxt/async_support/paymium.py +82 -19
  179. ccxt/async_support/phemex.py +713 -172
  180. ccxt/async_support/poloniex.py +1602 -283
  181. ccxt/async_support/probit.py +224 -95
  182. ccxt/async_support/ramzinex.py +30 -27
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +14 -13
  186. ccxt/async_support/tetherland.py +9 -9
  187. ccxt/async_support/timex.py +210 -51
  188. ccxt/async_support/tokocrypto.py +167 -47
  189. ccxt/async_support/tradeogre.py +266 -31
  190. ccxt/async_support/twox.py +9 -9
  191. ccxt/async_support/ubitex.py +12 -12
  192. ccxt/async_support/upbit.py +568 -165
  193. ccxt/async_support/vertex.py +160 -32
  194. ccxt/async_support/wallex.py +12 -12
  195. ccxt/async_support/wavesexchange.py +165 -30
  196. ccxt/async_support/whitebit.py +975 -127
  197. ccxt/async_support/woo.py +1918 -1016
  198. ccxt/async_support/woofipro.py +433 -141
  199. ccxt/async_support/xt.py +649 -193
  200. ccxt/async_support/yobit.py +195 -70
  201. ccxt/async_support/zaif.py +91 -15
  202. ccxt/async_support/zonda.py +151 -36
  203. ccxt/base/decimal_to_precision.py +14 -10
  204. ccxt/base/errors.py +49 -18
  205. ccxt/base/exchange.py +1556 -450
  206. ccxt/base/precise.py +10 -0
  207. ccxt/base/types.py +114 -6
  208. ccxt/bequant.py +5 -3
  209. ccxt/bigone.py +279 -144
  210. ccxt/binance.py +2347 -1158
  211. ccxt/binancecoinm.py +9 -3
  212. ccxt/binanceus.py +17 -3
  213. ccxt/binanceusdm.py +9 -4
  214. ccxt/bingx.py +2962 -920
  215. ccxt/bit2c.py +147 -27
  216. ccxt/bitbank.py +151 -23
  217. ccxt/bitbns.py +104 -30
  218. ccxt/bitfinex.py +3290 -1113
  219. ccxt/bitflyer.py +202 -27
  220. ccxt/bitget.py +3683 -1538
  221. ccxt/bithumb.py +194 -38
  222. ccxt/bitimen.py +9 -9
  223. ccxt/bitir.py +35 -35
  224. ccxt/bitmart.py +1288 -350
  225. ccxt/bitmex.py +260 -75
  226. ccxt/bitopro.py +262 -62
  227. ccxt/bitpin.py +15 -14
  228. ccxt/bitrue.py +459 -290
  229. ccxt/bitso.py +199 -54
  230. ccxt/bitstamp.py +230 -96
  231. ccxt/bitteam.py +167 -25
  232. ccxt/{huobijp.py → bittrade.py} +158 -30
  233. ccxt/bitvavo.py +213 -49
  234. ccxt/blockchaincom.py +160 -46
  235. ccxt/blofin.py +502 -120
  236. ccxt/btcalpha.py +169 -31
  237. ccxt/btcbox.py +291 -23
  238. ccxt/btcmarkets.py +211 -58
  239. ccxt/btcturk.py +161 -38
  240. ccxt/bybit.py +1775 -1030
  241. ccxt/cex.py +1439 -1303
  242. ccxt/coinbase.py +724 -212
  243. ccxt/coinbaseadvanced.py +2 -1
  244. ccxt/coinbaseexchange.py +388 -89
  245. ccxt/coinbaseinternational.py +412 -57
  246. ccxt/coincatch.py +177 -78
  247. ccxt/coincheck.py +135 -19
  248. ccxt/coinex.py +606 -232
  249. ccxt/coinmate.py +189 -63
  250. ccxt/coinmetro.py +194 -54
  251. ccxt/coinone.py +158 -51
  252. ccxt/coinsph.py +336 -61
  253. ccxt/coinspot.py +151 -52
  254. ccxt/cryptocom.py +661 -111
  255. ccxt/cryptomus.py +1137 -0
  256. ccxt/defx.py +2070 -0
  257. ccxt/delta.py +299 -99
  258. ccxt/deribit.py +348 -126
  259. ccxt/derive.py +2571 -0
  260. ccxt/digifinex.py +430 -214
  261. ccxt/ellipx.py +2029 -0
  262. ccxt/eterex.py +7 -7
  263. ccxt/excoino.py +29 -29
  264. ccxt/exir.py +11 -11
  265. ccxt/exmo.py +343 -131
  266. ccxt/exnovin.py +8 -8
  267. ccxt/farhadexchange.py +10 -10
  268. ccxt/fmfwio.py +2 -1
  269. ccxt/foxbit.py +1935 -0
  270. ccxt/gate.py +1351 -529
  271. ccxt/gateio.py +2 -1
  272. ccxt/gemini.py +144 -39
  273. ccxt/hashkey.py +152 -109
  274. ccxt/hibachi.py +2079 -0
  275. ccxt/hitbtc.py +395 -167
  276. ccxt/hitobit.py +9 -9
  277. ccxt/hollaex.py +307 -119
  278. ccxt/htx.py +851 -383
  279. ccxt/huobi.py +2 -1
  280. ccxt/hyperliquid.py +1848 -536
  281. ccxt/independentreserve.py +287 -15
  282. ccxt/indodax.py +190 -33
  283. ccxt/jibitex.py +9 -9
  284. ccxt/kraken.py +794 -351
  285. ccxt/krakenfutures.py +214 -62
  286. ccxt/kucoin.py +715 -396
  287. ccxt/kucoinfutures.py +652 -89
  288. ccxt/latoken.py +217 -113
  289. ccxt/lbank.py +425 -97
  290. ccxt/luno.py +382 -35
  291. ccxt/mercado.py +113 -6
  292. ccxt/mexc.py +873 -437
  293. ccxt/modetrade.py +2818 -0
  294. ccxt/myokx.py +54 -0
  295. ccxt/ndax.py +221 -64
  296. ccxt/nobitex.py +29 -35
  297. ccxt/novadax.py +190 -34
  298. ccxt/oceanex.py +217 -28
  299. ccxt/okcoin.py +253 -145
  300. ccxt/okexchange.py +9 -9
  301. ccxt/okx.py +1088 -351
  302. ccxt/okxus.py +54 -0
  303. ccxt/ompfinex.py +22 -21
  304. ccxt/onetrading.py +213 -392
  305. ccxt/oxfun.py +245 -166
  306. ccxt/p2b.py +151 -29
  307. ccxt/paradex.py +562 -49
  308. ccxt/paymium.py +82 -19
  309. ccxt/phemex.py +712 -172
  310. ccxt/poloniex.py +1601 -283
  311. ccxt/pro/__init__.py +76 -17
  312. ccxt/pro/alpaca.py +21 -6
  313. ccxt/pro/apex.py +984 -0
  314. ccxt/pro/ascendex.py +58 -10
  315. ccxt/pro/bequant.py +6 -1
  316. ccxt/pro/binance.py +728 -156
  317. ccxt/pro/binancecoinm.py +6 -2
  318. ccxt/pro/binanceus.py +8 -4
  319. ccxt/pro/binanceusdm.py +7 -2
  320. ccxt/pro/bingx.py +333 -142
  321. ccxt/pro/bitfinex.py +727 -262
  322. ccxt/pro/bitget.py +570 -79
  323. ccxt/pro/bithumb.py +20 -6
  324. ccxt/pro/bitmart.py +216 -87
  325. ccxt/pro/bitmex.py +47 -9
  326. ccxt/pro/bitopro.py +26 -14
  327. ccxt/pro/bitrue.py +22 -22
  328. ccxt/pro/bitstamp.py +54 -21
  329. ccxt/pro/{huobijp.py → bittrade.py} +7 -6
  330. ccxt/pro/bitvavo.py +191 -67
  331. ccxt/pro/blockchaincom.py +21 -8
  332. ccxt/pro/blofin.py +9 -1
  333. ccxt/pro/bybit.py +632 -245
  334. ccxt/pro/cex.py +59 -24
  335. ccxt/pro/coinbase.py +102 -73
  336. ccxt/pro/coinbaseadvanced.py +2 -1
  337. ccxt/pro/coinbaseexchange.py +8 -8
  338. ccxt/pro/coinbaseinternational.py +181 -25
  339. ccxt/pro/coincatch.py +6 -7
  340. ccxt/pro/coincheck.py +11 -6
  341. ccxt/pro/coinex.py +967 -665
  342. ccxt/pro/coinone.py +16 -9
  343. ccxt/pro/cryptocom.py +448 -45
  344. ccxt/pro/defx.py +831 -0
  345. ccxt/pro/deribit.py +150 -14
  346. ccxt/pro/derive.py +704 -0
  347. ccxt/pro/exmo.py +239 -6
  348. ccxt/pro/gate.py +623 -65
  349. ccxt/pro/gateio.py +2 -1
  350. ccxt/pro/gemini.py +27 -11
  351. ccxt/pro/hashkey.py +2 -2
  352. ccxt/pro/hitbtc.py +196 -91
  353. ccxt/pro/hollaex.py +23 -7
  354. ccxt/pro/htx.py +51 -14
  355. ccxt/pro/huobi.py +2 -1
  356. ccxt/pro/hyperliquid.py +591 -27
  357. ccxt/pro/independentreserve.py +9 -6
  358. ccxt/pro/kraken.py +640 -320
  359. ccxt/pro/krakenfutures.py +62 -35
  360. ccxt/pro/kucoin.py +267 -46
  361. ccxt/pro/kucoinfutures.py +165 -21
  362. ccxt/pro/lbank.py +102 -21
  363. ccxt/pro/luno.py +12 -8
  364. ccxt/pro/mexc.py +877 -111
  365. ccxt/pro/modetrade.py +1271 -0
  366. ccxt/pro/myokx.py +38 -0
  367. ccxt/pro/ndax.py +15 -2
  368. ccxt/pro/okcoin.py +23 -4
  369. ccxt/pro/okx.py +573 -98
  370. ccxt/pro/okxus.py +38 -0
  371. ccxt/pro/onetrading.py +30 -13
  372. ccxt/pro/oxfun.py +131 -27
  373. ccxt/pro/p2b.py +88 -22
  374. ccxt/pro/paradex.py +3 -3
  375. ccxt/pro/phemex.py +75 -21
  376. ccxt/pro/poloniex.py +124 -41
  377. ccxt/pro/probit.py +87 -80
  378. ccxt/pro/tradeogre.py +272 -0
  379. ccxt/pro/upbit.py +152 -12
  380. ccxt/pro/vertex.py +8 -3
  381. ccxt/pro/whitebit.py +58 -5
  382. ccxt/pro/woo.py +228 -37
  383. ccxt/pro/woofipro.py +106 -18
  384. ccxt/pro/xt.py +111 -5
  385. ccxt/probit.py +224 -95
  386. ccxt/protobuf/__init__.py +0 -0
  387. ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
  388. ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
  389. ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
  390. ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
  391. ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
  392. ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
  393. ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
  394. ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
  395. ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
  396. ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
  397. ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
  398. ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
  399. ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
  400. ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
  401. ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
  402. ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
  403. ccxt/protobuf/mexc/__init__.py +0 -0
  404. ccxt/ramzinex.py +28 -25
  405. ccxt/sarmayex.py +7 -7
  406. ccxt/sarrafex.py +10 -10
  407. ccxt/static_dependencies/__init__.py +1 -1
  408. ccxt/static_dependencies/lark/py.typed +0 -0
  409. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  410. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  411. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  412. ccxt/tabdeal.py +12 -11
  413. ccxt/test/tests_async.py +261 -57
  414. ccxt/test/tests_helpers.py +1 -3
  415. ccxt/test/tests_init.py +4 -3
  416. ccxt/test/tests_sync.py +261 -57
  417. ccxt/tetherland.py +7 -7
  418. ccxt/timex.py +210 -51
  419. ccxt/tokocrypto.py +167 -47
  420. ccxt/tradeogre.py +266 -31
  421. ccxt/twox.py +7 -7
  422. ccxt/ubitex.py +9 -9
  423. ccxt/upbit.py +568 -165
  424. ccxt/vertex.py +160 -32
  425. ccxt/wallex.py +9 -9
  426. ccxt/wavesexchange.py +165 -30
  427. ccxt/whitebit.py +975 -127
  428. ccxt/woo.py +1917 -1016
  429. ccxt/woofipro.py +432 -141
  430. ccxt/xt.py +649 -193
  431. ccxt/yobit.py +194 -70
  432. ccxt/zaif.py +91 -15
  433. ccxt/zonda.py +151 -36
  434. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.0.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/WHEEL +1 -1
  437. ccxt/abstract/ace.py +0 -15
  438. ccxt/abstract/bitbay.py +0 -53
  439. ccxt/abstract/bitcoincom.py +0 -115
  440. ccxt/abstract/bitfinex2.py +0 -139
  441. ccxt/abstract/bitpanda.py +0 -35
  442. ccxt/abstract/bl3p.py +0 -19
  443. ccxt/abstract/coinlist.py +0 -54
  444. ccxt/abstract/currencycom.py +0 -68
  445. ccxt/abstract/hitbtc3.py +0 -115
  446. ccxt/abstract/idex.py +0 -26
  447. ccxt/abstract/kuna.py +0 -182
  448. ccxt/abstract/lykke.py +0 -29
  449. ccxt/abstract/poloniexfutures.py +0 -48
  450. ccxt/abstract/wazirx.py +0 -30
  451. ccxt/ace.py +0 -1012
  452. ccxt/async_support/ace.py +0 -1012
  453. ccxt/async_support/base/ws/aiohttp_client.py +0 -125
  454. ccxt/async_support/base/ws/fast_client.py +0 -96
  455. ccxt/async_support/bitbay.py +0 -17
  456. ccxt/async_support/bitcoincom.py +0 -17
  457. ccxt/async_support/bitfinex2.py +0 -3552
  458. ccxt/async_support/bitpanda.py +0 -16
  459. ccxt/async_support/bl3p.py +0 -485
  460. ccxt/async_support/coinlist.py +0 -2243
  461. ccxt/async_support/currencycom.py +0 -1950
  462. ccxt/async_support/hitbtc3.py +0 -16
  463. ccxt/async_support/idex.py +0 -1766
  464. ccxt/async_support/kuna.py +0 -1841
  465. ccxt/async_support/lykke.py +0 -1270
  466. ccxt/async_support/poloniexfutures.py +0 -1717
  467. ccxt/async_support/wazirx.py +0 -1224
  468. ccxt/bitbay.py +0 -17
  469. ccxt/bitcoincom.py +0 -17
  470. ccxt/bitfinex2.py +0 -3552
  471. ccxt/bitpanda.py +0 -16
  472. ccxt/bl3p.py +0 -485
  473. ccxt/coinlist.py +0 -2243
  474. ccxt/currencycom.py +0 -1950
  475. ccxt/hitbtc3.py +0 -16
  476. ccxt/idex.py +0 -1766
  477. ccxt/kuna.py +0 -1841
  478. ccxt/lykke.py +0 -1270
  479. ccxt/poloniexfutures.py +0 -1717
  480. ccxt/pro/bitcoincom.py +0 -34
  481. ccxt/pro/bitfinex2.py +0 -1083
  482. ccxt/pro/bitpanda.py +0 -15
  483. ccxt/pro/currencycom.py +0 -536
  484. ccxt/pro/idex.py +0 -672
  485. ccxt/pro/poloniexfutures.py +0 -990
  486. ccxt/pro/wazirx.py +0 -749
  487. ccxt/test/base/__init__.py +0 -29
  488. ccxt/test/base/test_account.py +0 -26
  489. ccxt/test/base/test_balance.py +0 -56
  490. ccxt/test/base/test_borrow_interest.py +0 -35
  491. ccxt/test/base/test_borrow_rate.py +0 -32
  492. ccxt/test/base/test_calculate_fee.py +0 -51
  493. ccxt/test/base/test_crypto.py +0 -127
  494. ccxt/test/base/test_currency.py +0 -76
  495. ccxt/test/base/test_datetime.py +0 -109
  496. ccxt/test/base/test_decimal_to_precision.py +0 -392
  497. ccxt/test/base/test_deep_extend.py +0 -68
  498. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  499. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  500. ccxt/test/base/test_funding_rate_history.py +0 -29
  501. ccxt/test/base/test_last_price.py +0 -31
  502. ccxt/test/base/test_ledger_entry.py +0 -45
  503. ccxt/test/base/test_ledger_item.py +0 -48
  504. ccxt/test/base/test_leverage_tier.py +0 -33
  505. ccxt/test/base/test_liquidation.py +0 -50
  506. ccxt/test/base/test_margin_mode.py +0 -24
  507. ccxt/test/base/test_margin_modification.py +0 -35
  508. ccxt/test/base/test_market.py +0 -193
  509. ccxt/test/base/test_number.py +0 -411
  510. ccxt/test/base/test_ohlcv.py +0 -33
  511. ccxt/test/base/test_open_interest.py +0 -32
  512. ccxt/test/base/test_order.py +0 -64
  513. ccxt/test/base/test_order_book.py +0 -69
  514. ccxt/test/base/test_position.py +0 -60
  515. ccxt/test/base/test_shared_methods.py +0 -353
  516. ccxt/test/base/test_status.py +0 -24
  517. ccxt/test/base/test_throttle.py +0 -126
  518. ccxt/test/base/test_ticker.py +0 -92
  519. ccxt/test/base/test_trade.py +0 -47
  520. ccxt/test/base/test_trading_fee.py +0 -26
  521. ccxt/test/base/test_transaction.py +0 -39
  522. ccxt/test/test_async.py +0 -1649
  523. ccxt/test/test_sync.py +0 -1648
  524. ccxt/wazirx.py +0 -1224
  525. ccxt_ir-4.3.46.0.2.dist-info/RECORD +0 -772
  526. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  527. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info/licenses}/LICENSE.txt +0 -0
  528. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/top_level.txt +0 -0
ccxt/pro/bitfinex2.py DELETED
@@ -1,1083 +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, ArrayCacheByTimestamp
8
- import hashlib
9
- from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Ticker, Trade
10
- from ccxt.async_support.base.ws.client import Client
11
- from typing import List
12
- from ccxt.base.errors import ExchangeError
13
- from ccxt.base.errors import AuthenticationError
14
- from ccxt.base.errors import InvalidNonce
15
- from ccxt.base.precise import Precise
16
-
17
-
18
- class bitfinex2(ccxt.async_support.bitfinex2):
19
-
20
- def describe(self):
21
- return self.deep_extend(super(bitfinex2, self).describe(), {
22
- 'has': {
23
- 'ws': True,
24
- 'watchTicker': True,
25
- 'watchTickers': False,
26
- 'watchOrderBook': True,
27
- 'watchTrades': True,
28
- 'watchMyTrades': True,
29
- 'watchBalance': True,
30
- 'watchOHLCV': True,
31
- 'watchOrders': True,
32
- },
33
- 'urls': {
34
- 'api': {
35
- 'ws': {
36
- 'public': 'wss://api-pub.bitfinex.com/ws/2',
37
- 'private': 'wss://api.bitfinex.com/ws/2',
38
- },
39
- },
40
- },
41
- 'options': {
42
- 'watchOrderBook': {
43
- 'prec': 'P0',
44
- 'freq': 'F0',
45
- },
46
- 'ordersLimit': 1000,
47
- 'checksum': True,
48
- },
49
- })
50
-
51
- async def subscribe(self, channel, symbol, params={}):
52
- await self.load_markets()
53
- market = self.market(symbol)
54
- marketId = market['id']
55
- url = self.urls['api']['ws']['public']
56
- client = self.client(url)
57
- messageHash = channel + ':' + marketId
58
- request: dict = {
59
- 'event': 'subscribe',
60
- 'channel': channel,
61
- 'symbol': marketId,
62
- }
63
- result = await self.watch(url, messageHash, self.deep_extend(request, params), messageHash, {'checksum': False})
64
- checksum = self.safe_bool(self.options, 'checksum', True)
65
- if checksum and not client.subscriptions[messageHash]['checksum'] and (channel == 'book'):
66
- client.subscriptions[messageHash]['checksum'] = True
67
- await client.send({
68
- 'event': 'conf',
69
- 'flags': 131072,
70
- })
71
- return result
72
-
73
- async def subscribe_private(self, messageHash):
74
- await self.load_markets()
75
- await self.authenticate()
76
- url = self.urls['api']['ws']['private']
77
- return await self.watch(url, messageHash, None, 1)
78
-
79
- async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
80
- """
81
- watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
82
- :param str symbol: unified symbol of the market to fetch OHLCV data for
83
- :param str timeframe: the length of time each candle represents
84
- :param int [since]: timestamp in ms of the earliest candle to fetch
85
- :param int [limit]: the maximum amount of candles to fetch
86
- :param dict [params]: extra parameters specific to the exchange API endpoint
87
- :returns int[][]: A list of candles ordered, open, high, low, close, volume
88
- """
89
- await self.load_markets()
90
- market = self.market(symbol)
91
- symbol = market['symbol']
92
- interval = self.safe_string(self.timeframes, timeframe, timeframe)
93
- channel = 'candles'
94
- key = 'trade:' + interval + ':' + market['id']
95
- messageHash = channel + ':' + interval + ':' + market['id']
96
- request: dict = {
97
- 'event': 'subscribe',
98
- 'channel': channel,
99
- 'key': key,
100
- }
101
- url = self.urls['api']['ws']['public']
102
- # not using subscribe here because self message has a different format
103
- ohlcv = await self.watch(url, messageHash, self.deep_extend(request, params), messageHash)
104
- if self.newUpdates:
105
- limit = ohlcv.getLimit(symbol, limit)
106
- return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
107
-
108
- def handle_ohlcv(self, client: Client, message, subscription):
109
- #
110
- # initial snapshot
111
- # [
112
- # 341527, # channel id
113
- # [
114
- # [
115
- # 1654705860000, # timestamp
116
- # 1802.6, # open
117
- # 1800.3, # close
118
- # 1802.8, # high
119
- # 1800.3, # low
120
- # 86.49588236 # volume
121
- # ],
122
- # [
123
- # 1654705800000,
124
- # 1803.6,
125
- # 1802.6,
126
- # 1804.9,
127
- # 1802.3,
128
- # 74.6348086
129
- # ],
130
- # [
131
- # 1654705740000,
132
- # 1802.5,
133
- # 1803.2,
134
- # 1804.4,
135
- # 1802.4,
136
- # 23.61801085
137
- # ]
138
- # ]
139
- # ]
140
- #
141
- # update
142
- # [
143
- # 211171,
144
- # [
145
- # 1654705680000,
146
- # 1801,
147
- # 1802.4,
148
- # 1802.9,
149
- # 1800.4,
150
- # 23.91911091
151
- # ]
152
- # ]
153
- #
154
- data = self.safe_value(message, 1, [])
155
- ohlcvs = None
156
- first = self.safe_value(data, 0)
157
- if isinstance(first, list):
158
- # snapshot
159
- ohlcvs = data
160
- else:
161
- # update
162
- ohlcvs = [data]
163
- channel = self.safe_value(subscription, 'channel')
164
- key = self.safe_string(subscription, 'key')
165
- keyParts = key.split(':')
166
- interval = self.safe_string(keyParts, 1)
167
- marketId = key
168
- marketId = marketId.replace('trade:', '')
169
- marketId = marketId.replace(interval + ':', '')
170
- market = self.safe_market(marketId)
171
- timeframe = self.find_timeframe(interval)
172
- symbol = market['symbol']
173
- messageHash = channel + ':' + interval + ':' + marketId
174
- self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
175
- stored = self.safe_value(self.ohlcvs[symbol], timeframe)
176
- if stored is None:
177
- limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
178
- stored = ArrayCacheByTimestamp(limit)
179
- self.ohlcvs[symbol][timeframe] = stored
180
- ohlcvsLength = len(ohlcvs)
181
- for i in range(0, ohlcvsLength):
182
- ohlcv = ohlcvs[ohlcvsLength - i - 1]
183
- parsed = self.parse_ohlcv(ohlcv, market)
184
- stored.append(parsed)
185
- client.resolve(stored, messageHash)
186
-
187
- async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
188
- """
189
- get the list of most recent trades for a particular symbol
190
- :param str symbol: unified symbol of the market to fetch trades for
191
- :param int [since]: timestamp in ms of the earliest trade to fetch
192
- :param int [limit]: the maximum amount of trades to fetch
193
- :param dict [params]: extra parameters specific to the exchange API endpoint
194
- :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
195
- """
196
- trades = await self.subscribe('trades', symbol, params)
197
- if self.newUpdates:
198
- limit = trades.getLimit(symbol, limit)
199
- return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
200
-
201
- async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
202
- """
203
- watches information on multiple trades made by the user
204
- :param str symbol: unified market symbol of the market trades were made in
205
- :param int [since]: the earliest time in ms to fetch trades for
206
- :param int [limit]: the maximum number of trade structures to retrieve
207
- :param dict [params]: extra parameters specific to the exchange API endpoint
208
- :returns dict[]: a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
209
- """
210
- await self.load_markets()
211
- messageHash = 'myTrade'
212
- if symbol is not None:
213
- market = self.market(symbol)
214
- messageHash += ':' + market['id']
215
- trades = await self.subscribe_private(messageHash)
216
- if self.newUpdates:
217
- limit = trades.getLimit(symbol, limit)
218
- return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
219
-
220
- async def watch_ticker(self, symbol: str, params={}) -> Ticker:
221
- """
222
- watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
223
- :param str symbol: unified symbol of the market to fetch the ticker for
224
- :param dict [params]: extra parameters specific to the exchange API endpoint
225
- :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
226
- """
227
- return await self.subscribe('ticker', symbol, params)
228
-
229
- def handle_my_trade(self, client: Client, message, subscription={}):
230
- #
231
- # trade execution
232
- # [
233
- # 0,
234
- # "te", # or tu
235
- # [
236
- # 1133411090,
237
- # "tLTCUST",
238
- # 1655110144598,
239
- # 97084883506,
240
- # 0.1,
241
- # 42.821,
242
- # "EXCHANGE MARKET",
243
- # 42.799,
244
- # -1,
245
- # null,
246
- # null,
247
- # 1655110144596
248
- # ]
249
- # ]
250
- #
251
- name = 'myTrade'
252
- data = self.safe_value(message, 2)
253
- trade = self.parse_ws_trade(data)
254
- symbol = trade['symbol']
255
- market = self.market(symbol)
256
- messageHash = name + ':' + market['id']
257
- if self.myTrades is None:
258
- limit = self.safe_integer(self.options, 'tradesLimit', 1000)
259
- self.myTrades = ArrayCacheBySymbolById(limit)
260
- tradesArray = self.myTrades
261
- tradesArray.append(trade)
262
- self.myTrades = tradesArray
263
- # generic subscription
264
- client.resolve(tradesArray, name)
265
- # specific subscription
266
- client.resolve(tradesArray, messageHash)
267
-
268
- def handle_trades(self, client: Client, message, subscription):
269
- #
270
- # initial snapshot
271
- #
272
- # [
273
- # 188687, # channel id
274
- # [
275
- # [1128060675, 1654701572690, 0.00217533, 1815.3], # id, mts, amount, price
276
- # [1128060665, 1654701551231, -0.00280472, 1814.1],
277
- # [1128060664, 1654701550996, -0.00364444, 1814.1],
278
- # [1128060656, 1654701527730, -0.00265203, 1814.2],
279
- # [1128060647, 1654701505193, 0.00262395, 1815.2],
280
- # [1128060642, 1654701484656, -0.13411443, 1816],
281
- # [1128060641, 1654701484656, -0.00088557, 1816],
282
- # [1128060639, 1654701478326, -0.002, 1816],
283
- # ]
284
- # ]
285
- # update
286
- #
287
- # [
288
- # 360141,
289
- # "te",
290
- # [
291
- # 1128060969, # id
292
- # 1654702500098, # mts
293
- # 0.00325131, # amount positive buy, negative sell
294
- # 1818.5, # price
295
- # ],
296
- # ]
297
- #
298
- #
299
- channel = self.safe_value(subscription, 'channel')
300
- marketId = self.safe_string(subscription, 'symbol')
301
- market = self.safe_market(marketId)
302
- messageHash = channel + ':' + marketId
303
- tradesLimit = self.safe_integer(self.options, 'tradesLimit', 1000)
304
- symbol = market['symbol']
305
- stored = self.safe_value(self.trades, symbol)
306
- if stored is None:
307
- stored = ArrayCache(tradesLimit)
308
- self.trades[symbol] = stored
309
- messageLength = len(message)
310
- if messageLength == 2:
311
- # initial snapshot
312
- trades = self.safe_list(message, 1, [])
313
- # needs to be reversed to make chronological order
314
- length = len(trades)
315
- for i in range(0, length):
316
- index = length - i - 1
317
- parsed = self.parse_ws_trade(trades[index], market)
318
- stored.append(parsed)
319
- else:
320
- # update
321
- type = self.safe_string(message, 1)
322
- if type == 'tu':
323
- # don't resolve for a duplicate update
324
- # since te and tu updates are duplicated on the public stream
325
- return
326
- trade = self.safe_value(message, 2, [])
327
- parsed = self.parse_ws_trade(trade, market)
328
- stored.append(parsed)
329
- client.resolve(stored, messageHash)
330
-
331
- def parse_ws_trade(self, trade, market=None):
332
- #
333
- # [
334
- # 1128060969, # id
335
- # 1654702500098, # mts
336
- # 0.00325131, # amount positive buy, negative sell
337
- # 1818.5, # price
338
- # ]
339
- #
340
- # trade execution
341
- #
342
- # [
343
- # 1133411090, # id
344
- # "tLTCUST", # symbol
345
- # 1655110144598, # create ms
346
- # 97084883506, # order id
347
- # 0.1, # amount
348
- # 42.821, # price
349
- # "EXCHANGE MARKET", # order type
350
- # 42.799, # order price
351
- # -1, # maker
352
- # null, # fee
353
- # null, # fee currency
354
- # 1655110144596 # cid
355
- # ]
356
- #
357
- # trade update
358
- #
359
- # [
360
- # 1133411090,
361
- # "tLTCUST",
362
- # 1655110144598,
363
- # 97084883506,
364
- # 0.1,
365
- # 42.821,
366
- # "EXCHANGE MARKET",
367
- # 42.799,
368
- # -1,
369
- # -0.0002,
370
- # "LTC",
371
- # 1655110144596
372
- # ]
373
- #
374
- numFields = len(trade)
375
- isPublic = numFields <= 8
376
- marketId = self.safe_string(trade, 1) if (not isPublic) else None
377
- market = self.safe_market(marketId, market)
378
- createdKey = 1 if isPublic else 2
379
- priceKey = 3 if isPublic else 5
380
- amountKey = 2 if isPublic else 4
381
- marketId = market['id']
382
- type = self.safe_string(trade, 6)
383
- if type is not None:
384
- if type.find('LIMIT') > -1:
385
- type = 'limit'
386
- elif type.find('MARKET') > -1:
387
- type = 'market'
388
- orderId = self.safe_string(trade, 3) if (not isPublic) else None
389
- id = self.safe_string(trade, 0)
390
- timestamp = self.safe_integer(trade, createdKey)
391
- price = self.safe_string(trade, priceKey)
392
- amountString = self.safe_string(trade, amountKey)
393
- amount = self.parse_number(Precise.string_abs(amountString))
394
- side = None
395
- if amount is not None:
396
- side = 'buy' if Precise.string_gt(amountString, '0') else 'sell'
397
- symbol = self.safe_symbol(marketId, market)
398
- feeValue = self.safe_string(trade, 9)
399
- fee = None
400
- if feeValue is not None:
401
- currencyId = self.safe_string(trade, 10)
402
- code = self.safe_currency_code(currencyId)
403
- fee = {
404
- 'cost': feeValue,
405
- 'currency': code,
406
- }
407
- maker = self.safe_integer(trade, 8)
408
- takerOrMaker = None
409
- if maker is not None:
410
- takerOrMaker = 'taker' if (maker == -1) else 'maker'
411
- return self.safe_trade({
412
- 'info': trade,
413
- 'timestamp': timestamp,
414
- 'datetime': self.iso8601(timestamp),
415
- 'symbol': symbol,
416
- 'id': id,
417
- 'order': orderId,
418
- 'type': type,
419
- 'takerOrMaker': takerOrMaker,
420
- 'side': side,
421
- 'price': price,
422
- 'amount': amount,
423
- 'cost': None,
424
- 'fee': fee,
425
- }, market)
426
-
427
- def handle_ticker(self, client: Client, message, subscription):
428
- #
429
- # [
430
- # 340432, # channel ID
431
- # [
432
- # 236.62, # 1 BID float Price of last highest bid
433
- # 9.0029, # 2 BID_SIZE float Size of the last highest bid
434
- # 236.88, # 3 ASK float Price of last lowest ask
435
- # 7.1138, # 4 ASK_SIZE float Size of the last lowest ask
436
- # -1.02, # 5 DAILY_CHANGE float Amount that the last price has changed since yesterday
437
- # 0, # 6 DAILY_CHANGE_PERC float Amount that the price has changed expressed in percentage terms
438
- # 236.52, # 7 LAST_PRICE float Price of the last trade.
439
- # 5191.36754297, # 8 VOLUME float Daily volume
440
- # 250.01, # 9 HIGH float Daily high
441
- # 220.05, # 10 LOW float Daily low
442
- # ]
443
- # ]
444
- #
445
- ticker = self.safe_value(message, 1)
446
- marketId = self.safe_string(subscription, 'symbol')
447
- market = self.safe_market(marketId)
448
- symbol = self.safe_symbol(marketId)
449
- parsed = self.parse_ws_ticker(ticker, market)
450
- channel = 'ticker'
451
- messageHash = channel + ':' + marketId
452
- self.tickers[symbol] = parsed
453
- client.resolve(parsed, messageHash)
454
-
455
- def parse_ws_ticker(self, ticker, market=None):
456
- #
457
- # [
458
- # 236.62, # 1 BID float Price of last highest bid
459
- # 9.0029, # 2 BID_SIZE float Size of the last highest bid
460
- # 236.88, # 3 ASK float Price of last lowest ask
461
- # 7.1138, # 4 ASK_SIZE float Size of the last lowest ask
462
- # -1.02, # 5 DAILY_CHANGE float Amount that the last price has changed since yesterday
463
- # 0, # 6 DAILY_CHANGE_PERC float Amount that the price has changed expressed in percentage terms
464
- # 236.52, # 7 LAST_PRICE float Price of the last trade.
465
- # 5191.36754297, # 8 VOLUME float Daily volume
466
- # 250.01, # 9 HIGH float Daily high
467
- # 220.05, # 10 LOW float Daily low
468
- # ]
469
- #
470
- market = self.safe_market(None, market)
471
- symbol = market['symbol']
472
- last = self.safe_string(ticker, 6)
473
- change = self.safe_string(ticker, 4)
474
- return self.safe_ticker({
475
- 'symbol': symbol,
476
- 'timestamp': None,
477
- 'datetime': None,
478
- 'high': self.safe_string(ticker, 8),
479
- 'low': self.safe_string(ticker, 9),
480
- 'bid': self.safe_string(ticker, 0),
481
- 'bidVolume': self.safe_string(ticker, 1),
482
- 'ask': self.safe_string(ticker, 2),
483
- 'askVolume': self.safe_string(ticker, 3),
484
- 'vwap': None,
485
- 'open': None,
486
- 'close': last,
487
- 'last': last,
488
- 'previousClose': None,
489
- 'change': change,
490
- 'percentage': self.safe_string(ticker, 5),
491
- 'average': None,
492
- 'baseVolume': self.safe_string(ticker, 7),
493
- 'quoteVolume': None,
494
- 'info': ticker,
495
- }, market)
496
-
497
- async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
498
- """
499
- watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
500
- :param str symbol: unified symbol of the market to fetch the order book for
501
- :param int [limit]: the maximum amount of order book entries to return
502
- :param dict [params]: extra parameters specific to the exchange API endpoint
503
- :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
504
- """
505
- if limit is not None:
506
- if (limit != 25) and (limit != 100):
507
- raise ExchangeError(self.id + ' watchOrderBook limit argument must be None, 25 or 100')
508
- options = self.safe_value(self.options, 'watchOrderBook', {})
509
- prec = self.safe_string(options, 'prec', 'P0')
510
- freq = self.safe_string(options, 'freq', 'F0')
511
- request: dict = {
512
- 'prec': prec, # string, level of price aggregation, 'P0', 'P1', 'P2', 'P3', 'P4', default P0
513
- 'freq': freq, # string, frequency of updates 'F0' = realtime, 'F1' = 2 seconds, default is 'F0'
514
- }
515
- if limit is not None:
516
- request['len'] = limit # string, number of price points, '25', '100', default = '25'
517
- orderbook = await self.subscribe('book', symbol, self.deep_extend(request, params))
518
- return orderbook.limit()
519
-
520
- def handle_order_book(self, client: Client, message, subscription):
521
- #
522
- # first message(snapshot)
523
- #
524
- # [
525
- # 18691, # channel id
526
- # [
527
- # [7364.8, 10, 4.354802], # price, count, size > 0 = bid
528
- # [7364.7, 1, 0.00288831],
529
- # [7364.3, 12, 0.048],
530
- # [7364.9, 3, -0.42028976], # price, count, size < 0 = ask
531
- # [7365, 1, -0.25],
532
- # [7365.5, 1, -0.00371937],
533
- # ]
534
- # ]
535
- #
536
- # subsequent updates
537
- #
538
- # [
539
- # 358169, # channel id
540
- # [
541
- # 1807.1, # price
542
- # 0, # cound
543
- # 1 # size
544
- # ]
545
- # ]
546
- #
547
- marketId = self.safe_string(subscription, 'symbol')
548
- symbol = self.safe_symbol(marketId)
549
- channel = 'book'
550
- messageHash = channel + ':' + marketId
551
- prec = self.safe_string(subscription, 'prec', 'P0')
552
- isRaw = (prec == 'R0')
553
- # if it is an initial snapshot
554
- if not (symbol in self.orderbooks):
555
- limit = self.safe_integer(subscription, 'len')
556
- if isRaw:
557
- # raw order books
558
- self.orderbooks[symbol] = self.indexed_order_book({}, limit)
559
- else:
560
- # P0, P1, P2, P3, P4
561
- self.orderbooks[symbol] = self.counted_order_book({}, limit)
562
- orderbook = self.orderbooks[symbol]
563
- if isRaw:
564
- deltas = message[1]
565
- for i in range(0, len(deltas)):
566
- delta = deltas[i]
567
- delta2 = delta[2]
568
- size = -delta2 if (delta2 < 0) else delta2
569
- side = 'asks' if (delta2 < 0) else 'bids'
570
- bookside = orderbook[side]
571
- idString = self.safe_string(delta, 0)
572
- price = self.safe_float(delta, 1)
573
- bookside.storeArray([price, size, idString])
574
- else:
575
- deltas = message[1]
576
- for i in range(0, len(deltas)):
577
- delta = deltas[i]
578
- amount = self.safe_number(delta, 2)
579
- counter = self.safe_number(delta, 1)
580
- price = self.safe_number(delta, 0)
581
- size = -amount if (amount < 0) else amount
582
- side = 'asks' if (amount < 0) else 'bids'
583
- bookside = orderbook[side]
584
- bookside.storeArray([price, size, counter])
585
- orderbook['symbol'] = symbol
586
- client.resolve(orderbook, messageHash)
587
- else:
588
- orderbook = self.orderbooks[symbol]
589
- deltas = message[1]
590
- orderbookItem = self.orderbooks[symbol]
591
- if isRaw:
592
- price = self.safe_string(deltas, 1)
593
- deltas2 = deltas[2]
594
- size = -deltas2 if (deltas2 < 0) else deltas2
595
- side = 'asks' if (deltas2 < 0) else 'bids'
596
- bookside = orderbookItem[side]
597
- # price = 0 means that you have to remove the order from your book
598
- amount = size if Precise.string_gt(price, '0') else '0'
599
- idString = self.safe_string(deltas, 0)
600
- bookside.storeArray([self.parse_number(price), self.parse_number(amount), idString])
601
- else:
602
- amount = self.safe_string(deltas, 2)
603
- counter = self.safe_string(deltas, 1)
604
- price = self.safe_string(deltas, 0)
605
- size = Precise.string_neg(amount) if Precise.string_lt(amount, '0') else amount
606
- side = 'asks' if Precise.string_lt(amount, '0') else 'bids'
607
- bookside = orderbookItem[side]
608
- bookside.storeArray([self.parse_number(price), self.parse_number(size), self.parse_number(counter)])
609
- client.resolve(orderbook, messageHash)
610
-
611
- def handle_checksum(self, client: Client, message, subscription):
612
- #
613
- # [173904, "cs", -890884919]
614
- #
615
- marketId = self.safe_string(subscription, 'symbol')
616
- symbol = self.safe_symbol(marketId)
617
- channel = 'book'
618
- messageHash = channel + ':' + marketId
619
- book = self.safe_value(self.orderbooks, symbol)
620
- if book is None:
621
- return
622
- depth = 25 # covers the first 25 bids and asks
623
- stringArray = []
624
- bids = book['bids']
625
- asks = book['asks']
626
- prec = self.safe_string(subscription, 'prec', 'P0')
627
- isRaw = (prec == 'R0')
628
- idToCheck = 2 if isRaw else 0
629
- # pepperoni pizza from bitfinex
630
- for i in range(0, depth):
631
- bid = self.safe_value(bids, i)
632
- ask = self.safe_value(asks, i)
633
- if bid is not None:
634
- stringArray.append(self.number_to_string(bids[i][idToCheck]))
635
- stringArray.append(self.number_to_string(bids[i][1]))
636
- if ask is not None:
637
- stringArray.append(self.number_to_string(asks[i][idToCheck]))
638
- aski1 = asks[i][1]
639
- stringArray.append(self.number_to_string(-aski1))
640
- payload = ':'.join(stringArray)
641
- localChecksum = self.crc32(payload, True)
642
- responseChecksum = self.safe_integer(message, 2)
643
- if responseChecksum != localChecksum:
644
- error = InvalidNonce(self.id + ' invalid checksum')
645
- del client.subscriptions[messageHash]
646
- del self.orderbooks[symbol]
647
- client.reject(error, messageHash)
648
-
649
- async def watch_balance(self, params={}) -> Balances:
650
- """
651
- watch balance and get the amount of funds available for trading or funds locked in orders
652
- :param dict [params]: extra parameters specific to the exchange API endpoint
653
- :param str [params.type]: spot or contract if not provided self.options['defaultType'] is used
654
- :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
655
- """
656
- await self.load_markets()
657
- balanceType = self.safe_string(params, 'wallet', 'exchange') # exchange, margin
658
- params = self.omit(params, 'wallet')
659
- messageHash = 'balance:' + balanceType
660
- return await self.subscribe_private(messageHash)
661
-
662
- def handle_balance(self, client: Client, message, subscription):
663
- #
664
- # snapshot(exchange + margin together)
665
- # [
666
- # 0,
667
- # "ws",
668
- # [
669
- # [
670
- # "exchange",
671
- # "LTC",
672
- # 0.05479727,
673
- # 0,
674
- # null,
675
- # "Trading fees for 0.05 LTC(LTCUST) @ 51.872 on BFX(0.2%)",
676
- # null,
677
- # ]
678
- # [
679
- # "margin",
680
- # "USTF0",
681
- # 11.960650700086292,
682
- # 0,
683
- # null,
684
- # "Trading fees for 0.1 LTCF0(LTCF0:USTF0) @ 51.844 on BFX(0.065%)",
685
- # null,
686
- # ],
687
- # ],
688
- # ]
689
- #
690
- # spot
691
- # [
692
- # 0,
693
- # "wu",
694
- # [
695
- # "exchange",
696
- # "LTC", # currency
697
- # 0.06729727, # wallet balance
698
- # 0, # unsettled balance
699
- # 0.06729727, # available balance might be null
700
- # "Exchange 0.4 LTC for UST @ 65.075",
701
- # {
702
- # "reason": "TRADE",
703
- # "order_id": 96596397973,
704
- # "order_id_oppo": 96596632735,
705
- # "trade_price": "65.075",
706
- # "trade_amount": "-0.4",
707
- # "order_cid": 1654636218766,
708
- # "order_gid": null
709
- # }
710
- # ]
711
- # ]
712
- #
713
- # margin
714
- #
715
- # [
716
- # "margin",
717
- # "USTF0",
718
- # 11.960650700086292, # total
719
- # 0,
720
- # 6.776250700086292, # available
721
- # "Trading fees for 0.1 LTCF0(LTCF0:USTF0) @ 51.844 on BFX(0.065%)",
722
- # null
723
- # ]
724
- #
725
- updateType = self.safe_value(message, 1)
726
- data = None
727
- if updateType == 'ws':
728
- data = self.safe_value(message, 2)
729
- else:
730
- data = [self.safe_value(message, 2)]
731
- updatedTypes: dict = {}
732
- for i in range(0, len(data)):
733
- rawBalance = data[i]
734
- currencyId = self.safe_string(rawBalance, 1)
735
- code = self.safe_currency_code(currencyId)
736
- balance = self.parse_ws_balance(rawBalance)
737
- balanceType = self.safe_string(rawBalance, 0)
738
- oldBalance = self.safe_value(self.balance, balanceType, {})
739
- oldBalance[code] = balance
740
- oldBalance['info'] = message
741
- self.balance[balanceType] = self.safe_balance(oldBalance)
742
- updatedTypes[balanceType] = True
743
- updatesKeys = list(updatedTypes.keys())
744
- for i in range(0, len(updatesKeys)):
745
- type = updatesKeys[i]
746
- messageHash = 'balance:' + type
747
- client.resolve(self.balance[type], messageHash)
748
-
749
- def parse_ws_balance(self, balance):
750
- #
751
- # [
752
- # "exchange",
753
- # "LTC",
754
- # 0.05479727, # balance
755
- # 0,
756
- # null, # available null if not calculated yet
757
- # "Trading fees for 0.05 LTC(LTCUST) @ 51.872 on BFX(0.2%)",
758
- # null,
759
- # ]
760
- #
761
- totalBalance = self.safe_string(balance, 2)
762
- availableBalance = self.safe_string(balance, 4)
763
- account = self.account()
764
- if availableBalance is not None:
765
- account['free'] = availableBalance
766
- account['total'] = totalBalance
767
- return account
768
-
769
- def handle_system_status(self, client: Client, message):
770
- #
771
- # {
772
- # "event": "info",
773
- # "version": 2,
774
- # "serverId": "e293377e-7bb7-427e-b28c-5db045b2c1d1",
775
- # "platform": {status: 1}, # 1 for operative, 0 for maintenance
776
- # }
777
- #
778
- return message
779
-
780
- def handle_subscription_status(self, client: Client, message):
781
- #
782
- # {
783
- # "event": "subscribed",
784
- # "channel": "book",
785
- # "chanId": 67473,
786
- # "symbol": "tBTCUSD",
787
- # "prec": "P0",
788
- # "freq": "F0",
789
- # "len": "25",
790
- # "pair": "BTCUSD"
791
- # }
792
- #
793
- channelId = self.safe_string(message, 'chanId')
794
- client.subscriptions[channelId] = message
795
- return message
796
-
797
- async def authenticate(self, params={}):
798
- url = self.urls['api']['ws']['private']
799
- client = self.client(url)
800
- messageHash = 'authenticated'
801
- future = client.future(messageHash)
802
- authenticated = self.safe_value(client.subscriptions, messageHash)
803
- if authenticated is None:
804
- nonce = self.milliseconds()
805
- payload = 'AUTH' + str(nonce)
806
- signature = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha384, 'hex')
807
- event = 'auth'
808
- request: dict = {
809
- 'apiKey': self.apiKey,
810
- 'authSig': signature,
811
- 'authNonce': nonce,
812
- 'authPayload': payload,
813
- 'event': event,
814
- }
815
- message = self.extend(request, params)
816
- self.watch(url, messageHash, message, messageHash)
817
- return await future
818
-
819
- def handle_authentication_message(self, client: Client, message):
820
- messageHash = 'authenticated'
821
- status = self.safe_string(message, 'status')
822
- if status == 'OK':
823
- # we resolve the future here permanently so authentication only happens once
824
- future = self.safe_value(client.futures, messageHash)
825
- future.resolve(True)
826
- else:
827
- error = AuthenticationError(self.json(message))
828
- client.reject(error, messageHash)
829
- # allows further authentication attempts
830
- if messageHash in client.subscriptions:
831
- del client.subscriptions[messageHash]
832
-
833
- async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
834
- """
835
- watches information on multiple orders made by the user
836
- :param str symbol: unified market symbol of the market orders were made in
837
- :param int [since]: the earliest time in ms to fetch orders for
838
- :param int [limit]: the maximum number of order structures to retrieve
839
- :param dict [params]: extra parameters specific to the exchange API endpoint
840
- :returns dict[]: a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
841
- """
842
- await self.load_markets()
843
- messageHash = 'orders'
844
- if symbol is not None:
845
- market = self.market(symbol)
846
- messageHash += ':' + market['id']
847
- orders = await self.subscribe_private(messageHash)
848
- if self.newUpdates:
849
- limit = orders.getLimit(symbol, limit)
850
- return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
851
-
852
- def handle_orders(self, client: Client, message, subscription):
853
- #
854
- # limit order
855
- # [
856
- # 0,
857
- # "on", # ou or oc
858
- # [
859
- # 96923856256, # order id
860
- # null, # gid
861
- # 1655029337026, # cid
862
- # "tLTCUST", # symbol
863
- # 1655029337027, # created timestamp
864
- # 1655029337029, # updated timestamp
865
- # 0.1, # amount
866
- # 0.1, # amount_orig
867
- # "EXCHANGE LIMIT", # order type
868
- # null, # type_prev
869
- # null, # mts_tif
870
- # null, # placeholder
871
- # 0, # flags
872
- # "ACTIVE", # status
873
- # null,
874
- # null,
875
- # 30, # price
876
- # 0, # price average
877
- # 0, # price_trailling
878
- # 0, # price_aux_limit
879
- # null,
880
- # null,
881
- # null,
882
- # 0, # notify
883
- # 0,
884
- # null,
885
- # null,
886
- # null,
887
- # "BFX",
888
- # null,
889
- # null,
890
- # ]
891
- # ]
892
- #
893
- data = self.safe_value(message, 2, [])
894
- messageType = self.safe_string(message, 1)
895
- if self.orders is None:
896
- limit = self.safe_integer(self.options, 'ordersLimit', 1000)
897
- self.orders = ArrayCacheBySymbolById(limit)
898
- orders = self.orders
899
- symbolIds: dict = {}
900
- if messageType == 'os':
901
- snapshotLength = len(data)
902
- if snapshotLength == 0:
903
- return
904
- for i in range(0, len(data)):
905
- value = data[i]
906
- parsed = self.parse_ws_order(value)
907
- symbol = parsed['symbol']
908
- symbolIds[symbol] = True
909
- orders.append(parsed)
910
- else:
911
- parsed = self.parse_ws_order(data)
912
- orders.append(parsed)
913
- symbol = parsed['symbol']
914
- symbolIds[symbol] = True
915
- name = 'orders'
916
- client.resolve(self.orders, name)
917
- keys = list(symbolIds.keys())
918
- for i in range(0, len(keys)):
919
- symbol = keys[i]
920
- market = self.market(symbol)
921
- messageHash = name + ':' + market['id']
922
- client.resolve(self.orders, messageHash)
923
-
924
- def parse_ws_order_status(self, status):
925
- statuses: dict = {
926
- 'ACTIVE': 'open',
927
- 'CANCELED': 'canceled',
928
- 'EXECUTED': 'closed',
929
- 'PARTIALLY': 'open',
930
- }
931
- return self.safe_string(statuses, status, status)
932
-
933
- def parse_ws_order(self, order, market=None):
934
- #
935
- # [
936
- # 97084883506, # order id
937
- # null,
938
- # 1655110144596, # clientOrderId
939
- # "tLTCUST", # symbol
940
- # 1655110144596, # created timestamp
941
- # 1655110144598, # updated timestamp
942
- # 0, # amount
943
- # 0.1, # amount_orig negative if sell order
944
- # "EXCHANGE MARKET", # type
945
- # null,
946
- # null,
947
- # null,
948
- # 0,
949
- # "EXECUTED @ 42.821(0.1)", # status
950
- # null,
951
- # null,
952
- # 42.799, # price
953
- # 42.821, # price average
954
- # 0, # price trailling
955
- # 0, # price_aux_limit
956
- # null,
957
- # null,
958
- # null,
959
- # 0,
960
- # 0,
961
- # null,
962
- # null,
963
- # null,
964
- # "BFX",
965
- # null,
966
- # null,
967
- # {}
968
- # ]
969
- #
970
- id = self.safe_string(order, 0)
971
- clientOrderId = self.safe_string(order, 1)
972
- marketId = self.safe_string(order, 3)
973
- symbol = self.safe_symbol(marketId)
974
- market = self.safe_market(symbol)
975
- amount = self.safe_string(order, 7)
976
- side = 'buy'
977
- if Precise.string_lt(amount, '0'):
978
- amount = Precise.string_abs(amount)
979
- side = 'sell'
980
- remaining = Precise.string_abs(self.safe_string(order, 6))
981
- type = self.safe_string(order, 8)
982
- if type.find('LIMIT') > -1:
983
- type = 'limit'
984
- elif type.find('MARKET') > -1:
985
- type = 'market'
986
- rawState = self.safe_string(order, 13)
987
- stateParts = rawState.split(' ')
988
- trimmedStatus = self.safe_string(stateParts, 0)
989
- status = self.parse_ws_order_status(trimmedStatus)
990
- price = self.safe_string(order, 16)
991
- timestamp = self.safe_integer_2(order, 5, 4)
992
- average = self.safe_string(order, 17)
993
- stopPrice = self.omit_zero(self.safe_string(order, 18))
994
- return self.safe_order({
995
- 'info': order,
996
- 'id': id,
997
- 'clientOrderId': clientOrderId,
998
- 'timestamp': timestamp,
999
- 'datetime': self.iso8601(timestamp),
1000
- 'lastTradeTimestamp': None,
1001
- 'symbol': symbol,
1002
- 'type': type,
1003
- 'side': side,
1004
- 'price': price,
1005
- 'stopPrice': stopPrice,
1006
- 'triggerPrice': stopPrice,
1007
- 'average': average,
1008
- 'amount': amount,
1009
- 'remaining': remaining,
1010
- 'filled': None,
1011
- 'status': status,
1012
- 'fee': None,
1013
- 'cost': None,
1014
- 'trades': None,
1015
- }, market)
1016
-
1017
- def handle_message(self, client: Client, message):
1018
- channelId = self.safe_string(message, 0)
1019
- #
1020
- # [
1021
- # 1231,
1022
- # "hb",
1023
- # ]
1024
- #
1025
- # auth message
1026
- # {
1027
- # "event": "auth",
1028
- # "status": "OK",
1029
- # "chanId": 0,
1030
- # "userId": 3159883,
1031
- # "auth_id": "ac7108e7-2f26-424d-9982-c24700dc02ca",
1032
- # "caps": {
1033
- # "orders": {read: 1, write: 1},
1034
- # "account": {read: 1, write: 1},
1035
- # "funding": {read: 1, write: 1},
1036
- # "history": {read: 1, write: 0},
1037
- # "wallets": {read: 1, write: 1},
1038
- # "withdraw": {read: 0, write: 1},
1039
- # "positions": {read: 1, write: 1},
1040
- # "ui_withdraw": {read: 0, write: 0}
1041
- # }
1042
- # }
1043
- #
1044
- if isinstance(message, list):
1045
- if message[1] == 'hb':
1046
- return # skip heartbeats within subscription channels for now
1047
- subscription = self.safe_value(client.subscriptions, channelId, {})
1048
- channel = self.safe_string(subscription, 'channel')
1049
- name = self.safe_string(message, 1)
1050
- publicMethods: dict = {
1051
- 'book': self.handle_order_book,
1052
- 'cs': self.handle_checksum,
1053
- 'candles': self.handle_ohlcv,
1054
- 'ticker': self.handle_ticker,
1055
- 'trades': self.handle_trades,
1056
- }
1057
- privateMethods: dict = {
1058
- 'os': self.handle_orders,
1059
- 'ou': self.handle_orders,
1060
- 'on': self.handle_orders,
1061
- 'oc': self.handle_orders,
1062
- 'wu': self.handle_balance,
1063
- 'ws': self.handle_balance,
1064
- 'tu': self.handle_my_trade,
1065
- }
1066
- method = None
1067
- if channelId == '0':
1068
- method = self.safe_value(privateMethods, name)
1069
- else:
1070
- method = self.safe_value_2(publicMethods, name, channel)
1071
- if method is not None:
1072
- method(client, message, subscription)
1073
- else:
1074
- event = self.safe_string(message, 'event')
1075
- if event is not None:
1076
- methods: dict = {
1077
- 'info': self.handle_system_status,
1078
- 'subscribed': self.handle_subscription_status,
1079
- 'auth': self.handle_authentication_message,
1080
- }
1081
- method = self.safe_value(methods, event)
1082
- if method is not None:
1083
- method(client, message)