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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (529) hide show
  1. ccxt/__init__.py +39 -35
  2. ccxt/abantether.py +8 -8
  3. ccxt/abstract/alpaca.py +4 -0
  4. ccxt/abstract/apex.py +31 -0
  5. ccxt/abstract/bigone.py +1 -1
  6. ccxt/abstract/binance.py +106 -48
  7. ccxt/abstract/binancecoinm.py +106 -48
  8. ccxt/abstract/binanceus.py +141 -83
  9. ccxt/abstract/binanceusdm.py +106 -48
  10. ccxt/abstract/bingx.py +50 -1
  11. ccxt/abstract/bitbank.py +5 -0
  12. ccxt/abstract/bitfinex.py +136 -65
  13. ccxt/abstract/bitflyer.py +1 -0
  14. ccxt/abstract/bitget.py +67 -0
  15. ccxt/abstract/bitmart.py +19 -1
  16. ccxt/abstract/bitopro.py +1 -0
  17. ccxt/abstract/bitrue.py +68 -68
  18. ccxt/abstract/bitstamp.py +1 -0
  19. ccxt/abstract/blofin.py +30 -0
  20. ccxt/abstract/btcbox.py +2 -0
  21. ccxt/abstract/bybit.py +28 -13
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbaseexchange.py +1 -0
  24. ccxt/abstract/coinbaseinternational.py +1 -1
  25. ccxt/abstract/cryptocom.py +16 -0
  26. ccxt/abstract/cryptomus.py +20 -0
  27. ccxt/abstract/defx.py +69 -0
  28. ccxt/abstract/deribit.py +1 -0
  29. ccxt/abstract/derive.py +117 -0
  30. ccxt/abstract/digifinex.py +1 -0
  31. ccxt/abstract/ellipx.py +25 -0
  32. ccxt/abstract/foxbit.py +26 -0
  33. ccxt/abstract/gate.py +19 -0
  34. ccxt/abstract/gateio.py +19 -0
  35. ccxt/abstract/gemini.py +1 -0
  36. ccxt/abstract/hibachi.py +26 -0
  37. ccxt/abstract/hyperliquid.py +1 -1
  38. ccxt/abstract/independentreserve.py +6 -0
  39. ccxt/abstract/kraken.py +1 -0
  40. ccxt/abstract/krakenfutures.py +4 -0
  41. ccxt/abstract/kucoin.py +10 -0
  42. ccxt/abstract/kucoinfutures.py +18 -0
  43. ccxt/abstract/lbank.py +2 -1
  44. ccxt/abstract/luno.py +1 -0
  45. ccxt/abstract/mexc.py +2 -0
  46. ccxt/abstract/modetrade.py +119 -0
  47. ccxt/abstract/myokx.py +349 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +25 -0
  50. ccxt/abstract/okxus.py +349 -0
  51. ccxt/abstract/onetrading.py +0 -12
  52. ccxt/abstract/paradex.py +23 -0
  53. ccxt/abstract/phemex.py +2 -0
  54. ccxt/abstract/poloniex.py +36 -0
  55. ccxt/abstract/tradeogre.py +3 -1
  56. ccxt/abstract/upbit.py +51 -34
  57. ccxt/abstract/whitebit.py +16 -0
  58. ccxt/abstract/woo.py +64 -6
  59. ccxt/abstract/xt.py +10 -5
  60. ccxt/afratether.py +7 -7
  61. ccxt/alpaca.py +828 -51
  62. ccxt/apex.py +1875 -0
  63. ccxt/arzinja.py +7 -7
  64. ccxt/arzplus.py +9 -9
  65. ccxt/ascendex.py +501 -306
  66. ccxt/async_support/__init__.py +39 -35
  67. ccxt/async_support/abantether.py +8 -8
  68. ccxt/async_support/afratether.py +9 -9
  69. ccxt/async_support/alpaca.py +828 -51
  70. ccxt/async_support/apex.py +1875 -0
  71. ccxt/async_support/arzinja.py +10 -10
  72. ccxt/async_support/arzplus.py +12 -12
  73. ccxt/async_support/ascendex.py +502 -306
  74. ccxt/async_support/base/exchange.py +303 -89
  75. ccxt/async_support/base/ws/cache.py +9 -3
  76. ccxt/async_support/base/ws/client.py +173 -38
  77. ccxt/async_support/base/ws/future.py +25 -37
  78. ccxt/async_support/bequant.py +5 -3
  79. ccxt/async_support/bigone.py +279 -144
  80. ccxt/async_support/binance.py +2347 -1158
  81. ccxt/async_support/binancecoinm.py +9 -3
  82. ccxt/async_support/binanceus.py +17 -3
  83. ccxt/async_support/binanceusdm.py +9 -4
  84. ccxt/async_support/bingx.py +2962 -920
  85. ccxt/async_support/bit2c.py +147 -27
  86. ccxt/async_support/bitbank.py +151 -23
  87. ccxt/async_support/bitbns.py +104 -30
  88. ccxt/async_support/bitfinex.py +3291 -1113
  89. ccxt/async_support/bitflyer.py +202 -27
  90. ccxt/async_support/bitget.py +3683 -1538
  91. ccxt/async_support/bithumb.py +195 -38
  92. ccxt/async_support/bitimen.py +12 -12
  93. ccxt/async_support/bitir.py +38 -38
  94. ccxt/async_support/bitmart.py +1288 -350
  95. ccxt/async_support/bitmex.py +260 -75
  96. ccxt/async_support/bitopro.py +262 -62
  97. ccxt/async_support/bitpin.py +17 -16
  98. ccxt/async_support/bitrue.py +459 -290
  99. ccxt/async_support/bitso.py +199 -54
  100. ccxt/async_support/bitstamp.py +230 -96
  101. ccxt/async_support/bitteam.py +167 -25
  102. ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
  103. ccxt/async_support/bitvavo.py +213 -49
  104. ccxt/async_support/blockchaincom.py +160 -46
  105. ccxt/async_support/blofin.py +502 -120
  106. ccxt/async_support/btcalpha.py +169 -31
  107. ccxt/async_support/btcbox.py +292 -23
  108. ccxt/async_support/btcmarkets.py +211 -58
  109. ccxt/async_support/btcturk.py +161 -38
  110. ccxt/async_support/bybit.py +1775 -1030
  111. ccxt/async_support/cex.py +1440 -1303
  112. ccxt/async_support/coinbase.py +724 -212
  113. ccxt/async_support/coinbaseadvanced.py +2 -1
  114. ccxt/async_support/coinbaseexchange.py +388 -89
  115. ccxt/async_support/coinbaseinternational.py +412 -57
  116. ccxt/async_support/coincatch.py +177 -78
  117. ccxt/async_support/coincheck.py +135 -19
  118. ccxt/async_support/coinex.py +606 -232
  119. ccxt/async_support/coinmate.py +189 -63
  120. ccxt/async_support/coinmetro.py +195 -54
  121. ccxt/async_support/coinone.py +158 -51
  122. ccxt/async_support/coinsph.py +336 -61
  123. ccxt/async_support/coinspot.py +151 -52
  124. ccxt/async_support/cryptocom.py +661 -111
  125. ccxt/async_support/cryptomus.py +1137 -0
  126. ccxt/async_support/defx.py +2071 -0
  127. ccxt/async_support/delta.py +299 -99
  128. ccxt/async_support/deribit.py +348 -126
  129. ccxt/async_support/derive.py +2572 -0
  130. ccxt/async_support/digifinex.py +430 -214
  131. ccxt/async_support/ellipx.py +2029 -0
  132. ccxt/async_support/eterex.py +10 -10
  133. ccxt/async_support/excoino.py +31 -31
  134. ccxt/async_support/exir.py +14 -14
  135. ccxt/async_support/exmo.py +344 -131
  136. ccxt/async_support/exnovin.py +10 -10
  137. ccxt/async_support/farhadexchange.py +12 -12
  138. ccxt/async_support/fmfwio.py +2 -1
  139. ccxt/async_support/foxbit.py +1935 -0
  140. ccxt/async_support/gate.py +1351 -529
  141. ccxt/async_support/gateio.py +2 -1
  142. ccxt/async_support/gemini.py +144 -39
  143. ccxt/async_support/hashkey.py +152 -109
  144. ccxt/async_support/hibachi.py +2080 -0
  145. ccxt/async_support/hitbtc.py +395 -167
  146. ccxt/async_support/hitobit.py +12 -12
  147. ccxt/async_support/hollaex.py +307 -119
  148. ccxt/async_support/htx.py +851 -383
  149. ccxt/async_support/huobi.py +2 -1
  150. ccxt/async_support/hyperliquid.py +1848 -536
  151. ccxt/async_support/independentreserve.py +288 -15
  152. ccxt/async_support/indodax.py +190 -33
  153. ccxt/async_support/jibitex.py +12 -12
  154. ccxt/async_support/kraken.py +795 -351
  155. ccxt/async_support/krakenfutures.py +214 -62
  156. ccxt/async_support/kucoin.py +715 -396
  157. ccxt/async_support/kucoinfutures.py +652 -89
  158. ccxt/async_support/latoken.py +217 -113
  159. ccxt/async_support/lbank.py +425 -97
  160. ccxt/async_support/luno.py +382 -35
  161. ccxt/async_support/mercado.py +113 -6
  162. ccxt/async_support/mexc.py +874 -437
  163. ccxt/async_support/modetrade.py +2818 -0
  164. ccxt/async_support/myokx.py +54 -0
  165. ccxt/async_support/ndax.py +221 -64
  166. ccxt/async_support/nobitex.py +31 -37
  167. ccxt/async_support/novadax.py +190 -34
  168. ccxt/async_support/oceanex.py +217 -28
  169. ccxt/async_support/okcoin.py +253 -145
  170. ccxt/async_support/okexchange.py +11 -11
  171. ccxt/async_support/okx.py +1088 -351
  172. ccxt/async_support/okxus.py +54 -0
  173. ccxt/async_support/ompfinex.py +25 -24
  174. ccxt/async_support/onetrading.py +213 -392
  175. ccxt/async_support/oxfun.py +245 -166
  176. ccxt/async_support/p2b.py +151 -29
  177. ccxt/async_support/paradex.py +562 -49
  178. ccxt/async_support/paymium.py +82 -19
  179. ccxt/async_support/phemex.py +713 -172
  180. ccxt/async_support/poloniex.py +1602 -283
  181. ccxt/async_support/probit.py +224 -95
  182. ccxt/async_support/ramzinex.py +30 -27
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +14 -13
  186. ccxt/async_support/tetherland.py +9 -9
  187. ccxt/async_support/timex.py +210 -51
  188. ccxt/async_support/tokocrypto.py +167 -47
  189. ccxt/async_support/tradeogre.py +266 -31
  190. ccxt/async_support/twox.py +9 -9
  191. ccxt/async_support/ubitex.py +12 -12
  192. ccxt/async_support/upbit.py +568 -165
  193. ccxt/async_support/vertex.py +160 -32
  194. ccxt/async_support/wallex.py +12 -12
  195. ccxt/async_support/wavesexchange.py +165 -30
  196. ccxt/async_support/whitebit.py +975 -127
  197. ccxt/async_support/woo.py +1918 -1016
  198. ccxt/async_support/woofipro.py +433 -141
  199. ccxt/async_support/xt.py +649 -193
  200. ccxt/async_support/yobit.py +195 -70
  201. ccxt/async_support/zaif.py +91 -15
  202. ccxt/async_support/zonda.py +151 -36
  203. ccxt/base/decimal_to_precision.py +14 -10
  204. ccxt/base/errors.py +49 -18
  205. ccxt/base/exchange.py +1556 -450
  206. ccxt/base/precise.py +10 -0
  207. ccxt/base/types.py +114 -6
  208. ccxt/bequant.py +5 -3
  209. ccxt/bigone.py +279 -144
  210. ccxt/binance.py +2347 -1158
  211. ccxt/binancecoinm.py +9 -3
  212. ccxt/binanceus.py +17 -3
  213. ccxt/binanceusdm.py +9 -4
  214. ccxt/bingx.py +2962 -920
  215. ccxt/bit2c.py +147 -27
  216. ccxt/bitbank.py +151 -23
  217. ccxt/bitbns.py +104 -30
  218. ccxt/bitfinex.py +3290 -1113
  219. ccxt/bitflyer.py +202 -27
  220. ccxt/bitget.py +3683 -1538
  221. ccxt/bithumb.py +194 -38
  222. ccxt/bitimen.py +9 -9
  223. ccxt/bitir.py +35 -35
  224. ccxt/bitmart.py +1288 -350
  225. ccxt/bitmex.py +260 -75
  226. ccxt/bitopro.py +262 -62
  227. ccxt/bitpin.py +15 -14
  228. ccxt/bitrue.py +459 -290
  229. ccxt/bitso.py +199 -54
  230. ccxt/bitstamp.py +230 -96
  231. ccxt/bitteam.py +167 -25
  232. ccxt/{huobijp.py → bittrade.py} +158 -30
  233. ccxt/bitvavo.py +213 -49
  234. ccxt/blockchaincom.py +160 -46
  235. ccxt/blofin.py +502 -120
  236. ccxt/btcalpha.py +169 -31
  237. ccxt/btcbox.py +291 -23
  238. ccxt/btcmarkets.py +211 -58
  239. ccxt/btcturk.py +161 -38
  240. ccxt/bybit.py +1775 -1030
  241. ccxt/cex.py +1439 -1303
  242. ccxt/coinbase.py +724 -212
  243. ccxt/coinbaseadvanced.py +2 -1
  244. ccxt/coinbaseexchange.py +388 -89
  245. ccxt/coinbaseinternational.py +412 -57
  246. ccxt/coincatch.py +177 -78
  247. ccxt/coincheck.py +135 -19
  248. ccxt/coinex.py +606 -232
  249. ccxt/coinmate.py +189 -63
  250. ccxt/coinmetro.py +194 -54
  251. ccxt/coinone.py +158 -51
  252. ccxt/coinsph.py +336 -61
  253. ccxt/coinspot.py +151 -52
  254. ccxt/cryptocom.py +661 -111
  255. ccxt/cryptomus.py +1137 -0
  256. ccxt/defx.py +2070 -0
  257. ccxt/delta.py +299 -99
  258. ccxt/deribit.py +348 -126
  259. ccxt/derive.py +2571 -0
  260. ccxt/digifinex.py +430 -214
  261. ccxt/ellipx.py +2029 -0
  262. ccxt/eterex.py +7 -7
  263. ccxt/excoino.py +29 -29
  264. ccxt/exir.py +11 -11
  265. ccxt/exmo.py +343 -131
  266. ccxt/exnovin.py +8 -8
  267. ccxt/farhadexchange.py +10 -10
  268. ccxt/fmfwio.py +2 -1
  269. ccxt/foxbit.py +1935 -0
  270. ccxt/gate.py +1351 -529
  271. ccxt/gateio.py +2 -1
  272. ccxt/gemini.py +144 -39
  273. ccxt/hashkey.py +152 -109
  274. ccxt/hibachi.py +2079 -0
  275. ccxt/hitbtc.py +395 -167
  276. ccxt/hitobit.py +9 -9
  277. ccxt/hollaex.py +307 -119
  278. ccxt/htx.py +851 -383
  279. ccxt/huobi.py +2 -1
  280. ccxt/hyperliquid.py +1848 -536
  281. ccxt/independentreserve.py +287 -15
  282. ccxt/indodax.py +190 -33
  283. ccxt/jibitex.py +9 -9
  284. ccxt/kraken.py +794 -351
  285. ccxt/krakenfutures.py +214 -62
  286. ccxt/kucoin.py +715 -396
  287. ccxt/kucoinfutures.py +652 -89
  288. ccxt/latoken.py +217 -113
  289. ccxt/lbank.py +425 -97
  290. ccxt/luno.py +382 -35
  291. ccxt/mercado.py +113 -6
  292. ccxt/mexc.py +873 -437
  293. ccxt/modetrade.py +2818 -0
  294. ccxt/myokx.py +54 -0
  295. ccxt/ndax.py +221 -64
  296. ccxt/nobitex.py +29 -35
  297. ccxt/novadax.py +190 -34
  298. ccxt/oceanex.py +217 -28
  299. ccxt/okcoin.py +253 -145
  300. ccxt/okexchange.py +9 -9
  301. ccxt/okx.py +1088 -351
  302. ccxt/okxus.py +54 -0
  303. ccxt/ompfinex.py +22 -21
  304. ccxt/onetrading.py +213 -392
  305. ccxt/oxfun.py +245 -166
  306. ccxt/p2b.py +151 -29
  307. ccxt/paradex.py +562 -49
  308. ccxt/paymium.py +82 -19
  309. ccxt/phemex.py +712 -172
  310. ccxt/poloniex.py +1601 -283
  311. ccxt/pro/__init__.py +76 -17
  312. ccxt/pro/alpaca.py +21 -6
  313. ccxt/pro/apex.py +984 -0
  314. ccxt/pro/ascendex.py +58 -10
  315. ccxt/pro/bequant.py +6 -1
  316. ccxt/pro/binance.py +728 -156
  317. ccxt/pro/binancecoinm.py +6 -2
  318. ccxt/pro/binanceus.py +8 -4
  319. ccxt/pro/binanceusdm.py +7 -2
  320. ccxt/pro/bingx.py +333 -142
  321. ccxt/pro/bitfinex.py +727 -262
  322. ccxt/pro/bitget.py +570 -79
  323. ccxt/pro/bithumb.py +20 -6
  324. ccxt/pro/bitmart.py +216 -87
  325. ccxt/pro/bitmex.py +47 -9
  326. ccxt/pro/bitopro.py +26 -14
  327. ccxt/pro/bitrue.py +22 -22
  328. ccxt/pro/bitstamp.py +54 -21
  329. ccxt/pro/{huobijp.py → bittrade.py} +7 -6
  330. ccxt/pro/bitvavo.py +191 -67
  331. ccxt/pro/blockchaincom.py +21 -8
  332. ccxt/pro/blofin.py +9 -1
  333. ccxt/pro/bybit.py +632 -245
  334. ccxt/pro/cex.py +59 -24
  335. ccxt/pro/coinbase.py +102 -73
  336. ccxt/pro/coinbaseadvanced.py +2 -1
  337. ccxt/pro/coinbaseexchange.py +8 -8
  338. ccxt/pro/coinbaseinternational.py +181 -25
  339. ccxt/pro/coincatch.py +6 -7
  340. ccxt/pro/coincheck.py +11 -6
  341. ccxt/pro/coinex.py +967 -665
  342. ccxt/pro/coinone.py +16 -9
  343. ccxt/pro/cryptocom.py +448 -45
  344. ccxt/pro/defx.py +831 -0
  345. ccxt/pro/deribit.py +150 -14
  346. ccxt/pro/derive.py +704 -0
  347. ccxt/pro/exmo.py +239 -6
  348. ccxt/pro/gate.py +623 -65
  349. ccxt/pro/gateio.py +2 -1
  350. ccxt/pro/gemini.py +27 -11
  351. ccxt/pro/hashkey.py +2 -2
  352. ccxt/pro/hitbtc.py +196 -91
  353. ccxt/pro/hollaex.py +23 -7
  354. ccxt/pro/htx.py +51 -14
  355. ccxt/pro/huobi.py +2 -1
  356. ccxt/pro/hyperliquid.py +591 -27
  357. ccxt/pro/independentreserve.py +9 -6
  358. ccxt/pro/kraken.py +640 -320
  359. ccxt/pro/krakenfutures.py +62 -35
  360. ccxt/pro/kucoin.py +267 -46
  361. ccxt/pro/kucoinfutures.py +165 -21
  362. ccxt/pro/lbank.py +102 -21
  363. ccxt/pro/luno.py +12 -8
  364. ccxt/pro/mexc.py +877 -111
  365. ccxt/pro/modetrade.py +1271 -0
  366. ccxt/pro/myokx.py +38 -0
  367. ccxt/pro/ndax.py +15 -2
  368. ccxt/pro/okcoin.py +23 -4
  369. ccxt/pro/okx.py +573 -98
  370. ccxt/pro/okxus.py +38 -0
  371. ccxt/pro/onetrading.py +30 -13
  372. ccxt/pro/oxfun.py +131 -27
  373. ccxt/pro/p2b.py +88 -22
  374. ccxt/pro/paradex.py +3 -3
  375. ccxt/pro/phemex.py +75 -21
  376. ccxt/pro/poloniex.py +124 -41
  377. ccxt/pro/probit.py +87 -80
  378. ccxt/pro/tradeogre.py +272 -0
  379. ccxt/pro/upbit.py +152 -12
  380. ccxt/pro/vertex.py +8 -3
  381. ccxt/pro/whitebit.py +58 -5
  382. ccxt/pro/woo.py +228 -37
  383. ccxt/pro/woofipro.py +106 -18
  384. ccxt/pro/xt.py +111 -5
  385. ccxt/probit.py +224 -95
  386. ccxt/protobuf/__init__.py +0 -0
  387. ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
  388. ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
  389. ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
  390. ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
  391. ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
  392. ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
  393. ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
  394. ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
  395. ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
  396. ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
  397. ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
  398. ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
  399. ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
  400. ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
  401. ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
  402. ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
  403. ccxt/protobuf/mexc/__init__.py +0 -0
  404. ccxt/ramzinex.py +28 -25
  405. ccxt/sarmayex.py +7 -7
  406. ccxt/sarrafex.py +10 -10
  407. ccxt/static_dependencies/__init__.py +1 -1
  408. ccxt/static_dependencies/lark/py.typed +0 -0
  409. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  410. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  411. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  412. ccxt/tabdeal.py +12 -11
  413. ccxt/test/tests_async.py +261 -57
  414. ccxt/test/tests_helpers.py +1 -3
  415. ccxt/test/tests_init.py +4 -3
  416. ccxt/test/tests_sync.py +261 -57
  417. ccxt/tetherland.py +7 -7
  418. ccxt/timex.py +210 -51
  419. ccxt/tokocrypto.py +167 -47
  420. ccxt/tradeogre.py +266 -31
  421. ccxt/twox.py +7 -7
  422. ccxt/ubitex.py +9 -9
  423. ccxt/upbit.py +568 -165
  424. ccxt/vertex.py +160 -32
  425. ccxt/wallex.py +9 -9
  426. ccxt/wavesexchange.py +165 -30
  427. ccxt/whitebit.py +975 -127
  428. ccxt/woo.py +1917 -1016
  429. ccxt/woofipro.py +432 -141
  430. ccxt/xt.py +649 -193
  431. ccxt/yobit.py +194 -70
  432. ccxt/zaif.py +91 -15
  433. ccxt/zonda.py +151 -36
  434. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.0.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info}/WHEEL +1 -1
  437. ccxt/__test__.py +0 -7
  438. ccxt/abstract/ace.py +0 -15
  439. ccxt/abstract/bitbay.py +0 -53
  440. ccxt/abstract/bitcoincom.py +0 -115
  441. ccxt/abstract/bitfinex2.py +0 -139
  442. ccxt/abstract/bitpanda.py +0 -35
  443. ccxt/abstract/bl3p.py +0 -19
  444. ccxt/abstract/coinlist.py +0 -54
  445. ccxt/abstract/currencycom.py +0 -68
  446. ccxt/abstract/hitbtc3.py +0 -115
  447. ccxt/abstract/idex.py +0 -26
  448. ccxt/abstract/kuna.py +0 -182
  449. ccxt/abstract/lykke.py +0 -29
  450. ccxt/abstract/poloniexfutures.py +0 -48
  451. ccxt/abstract/wazirx.py +0 -30
  452. ccxt/ace.py +0 -1012
  453. ccxt/async_support/ace.py +0 -1012
  454. ccxt/async_support/base/ws/aiohttp_client.py +0 -125
  455. ccxt/async_support/base/ws/fast_client.py +0 -96
  456. ccxt/async_support/bitbay.py +0 -17
  457. ccxt/async_support/bitcoincom.py +0 -17
  458. ccxt/async_support/bitfinex2.py +0 -3552
  459. ccxt/async_support/bitpanda.py +0 -16
  460. ccxt/async_support/bl3p.py +0 -485
  461. ccxt/async_support/coinlist.py +0 -2243
  462. ccxt/async_support/currencycom.py +0 -1950
  463. ccxt/async_support/hitbtc3.py +0 -16
  464. ccxt/async_support/idex.py +0 -1766
  465. ccxt/async_support/kuna.py +0 -1841
  466. ccxt/async_support/lykke.py +0 -1270
  467. ccxt/async_support/poloniexfutures.py +0 -1717
  468. ccxt/async_support/wazirx.py +0 -1224
  469. ccxt/bitbay.py +0 -17
  470. ccxt/bitcoincom.py +0 -17
  471. ccxt/bitfinex2.py +0 -3552
  472. ccxt/bitpanda.py +0 -16
  473. ccxt/bl3p.py +0 -485
  474. ccxt/coinlist.py +0 -2243
  475. ccxt/currencycom.py +0 -1950
  476. ccxt/hitbtc3.py +0 -16
  477. ccxt/idex.py +0 -1766
  478. ccxt/kuna.py +0 -1841
  479. ccxt/lykke.py +0 -1270
  480. ccxt/poloniexfutures.py +0 -1717
  481. ccxt/pro/bitcoincom.py +0 -34
  482. ccxt/pro/bitfinex2.py +0 -1083
  483. ccxt/pro/bitpanda.py +0 -15
  484. ccxt/pro/currencycom.py +0 -536
  485. ccxt/pro/idex.py +0 -672
  486. ccxt/pro/poloniexfutures.py +0 -990
  487. ccxt/pro/wazirx.py +0 -749
  488. ccxt/test/base/__init__.py +0 -29
  489. ccxt/test/base/test_account.py +0 -26
  490. ccxt/test/base/test_balance.py +0 -56
  491. ccxt/test/base/test_borrow_interest.py +0 -35
  492. ccxt/test/base/test_borrow_rate.py +0 -32
  493. ccxt/test/base/test_calculate_fee.py +0 -51
  494. ccxt/test/base/test_crypto.py +0 -127
  495. ccxt/test/base/test_currency.py +0 -76
  496. ccxt/test/base/test_datetime.py +0 -109
  497. ccxt/test/base/test_decimal_to_precision.py +0 -392
  498. ccxt/test/base/test_deep_extend.py +0 -68
  499. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  500. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  501. ccxt/test/base/test_funding_rate_history.py +0 -29
  502. ccxt/test/base/test_last_price.py +0 -31
  503. ccxt/test/base/test_ledger_entry.py +0 -45
  504. ccxt/test/base/test_ledger_item.py +0 -48
  505. ccxt/test/base/test_leverage_tier.py +0 -33
  506. ccxt/test/base/test_liquidation.py +0 -50
  507. ccxt/test/base/test_margin_mode.py +0 -24
  508. ccxt/test/base/test_margin_modification.py +0 -35
  509. ccxt/test/base/test_market.py +0 -193
  510. ccxt/test/base/test_number.py +0 -411
  511. ccxt/test/base/test_ohlcv.py +0 -33
  512. ccxt/test/base/test_open_interest.py +0 -32
  513. ccxt/test/base/test_order.py +0 -64
  514. ccxt/test/base/test_order_book.py +0 -69
  515. ccxt/test/base/test_position.py +0 -60
  516. ccxt/test/base/test_shared_methods.py +0 -353
  517. ccxt/test/base/test_status.py +0 -24
  518. ccxt/test/base/test_throttle.py +0 -126
  519. ccxt/test/base/test_ticker.py +0 -92
  520. ccxt/test/base/test_trade.py +0 -47
  521. ccxt/test/base/test_trading_fee.py +0 -26
  522. ccxt/test/base/test_transaction.py +0 -39
  523. ccxt/test/test_async.py +0 -1649
  524. ccxt/test/test_sync.py +0 -1648
  525. ccxt/wazirx.py +0 -1224
  526. ccxt_ir-4.3.46.0.3.dist-info/RECORD +0 -773
  527. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  528. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info/licenses}/LICENSE.txt +0 -0
  529. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info}/top_level.txt +0 -0
ccxt/pro/probit.py CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  import ccxt.async_support
7
7
  from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById
8
- from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Ticker, Trade
8
+ from ccxt.base.types import Any, Balances, Bool, Int, Order, OrderBook, Str, Ticker, Trade
9
9
  from ccxt.async_support.base.ws.client import Client
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
@@ -14,7 +14,7 @@ from ccxt.base.errors import NotSupported
14
14
 
15
15
  class probit(ccxt.async_support.probit):
16
16
 
17
- def describe(self):
17
+ def describe(self) -> Any:
18
18
  return self.deep_extend(super(probit, self).describe(), {
19
19
  'has': {
20
20
  'ws': True,
@@ -22,6 +22,7 @@ class probit(ccxt.async_support.probit):
22
22
  'watchTicker': True,
23
23
  'watchTickers': False,
24
24
  'watchTrades': True,
25
+ 'watchTradesForSymbols': False,
25
26
  'watchMyTrades': True,
26
27
  'watchOrders': True,
27
28
  'watchOrderBook': True,
@@ -40,38 +41,23 @@ class probit(ccxt.async_support.probit):
40
41
  'filter': 'order_books_l2',
41
42
  'interval': 100, # or 500
42
43
  },
43
- 'watchTrades': {
44
- 'filter': 'recent_trades',
45
- },
46
- 'watchTicker': {
47
- 'filter': 'ticker',
48
- },
49
- 'watchOrders': {
50
- 'channel': 'open_order',
51
- },
52
44
  },
53
45
  'streaming': {
54
46
  },
55
- 'exceptions': {
56
- },
57
47
  })
58
48
 
59
49
  async def watch_balance(self, params={}) -> Balances:
60
50
  """
61
51
  watch balance and get the amount of funds available for trading or funds locked in orders
62
- :see: https://docs-en.probit.com/reference/balance-1
52
+
53
+ https://docs-en.probit.com/reference/balance-1
54
+
63
55
  :param dict [params]: extra parameters specific to the exchange API endpoint
64
56
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
65
57
  """
66
58
  await self.authenticate(params)
67
59
  messageHash = 'balance'
68
- url = self.urls['api']['ws']
69
- subscribe: dict = {
70
- 'type': 'subscribe',
71
- 'channel': 'balance',
72
- }
73
- request = self.extend(subscribe, params)
74
- return await self.watch(url, messageHash, request, messageHash)
60
+ return await self.subscribe_private(messageHash, 'balance', params)
75
61
 
76
62
  def handle_balance(self, client: Client, message):
77
63
  #
@@ -121,15 +107,16 @@ class probit(ccxt.async_support.probit):
121
107
  async def watch_ticker(self, symbol: str, params={}) -> Ticker:
122
108
  """
123
109
  watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
124
- :see: https://docs-en.probit.com/reference/marketdata
110
+
111
+ https://docs-en.probit.com/reference/marketdata
112
+
125
113
  :param str symbol: unified symbol of the market to fetch the ticker for
126
114
  :param dict [params]: extra parameters specific to the exchange API endpoint
127
115
  :param int [params.interval]: Unit time to synchronize market information(ms). Available units: 100, 500
128
116
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
129
117
  """
130
- filter = None
131
- filter, params = self.handle_option_and_params(params, 'watchTicker', 'filter', 'ticker')
132
- return await self.subscribe_order_book(symbol, 'ticker', filter, params)
118
+ channel = 'ticker'
119
+ return await self.subscribe_public('watchTicker', symbol, 'ticker', channel, params)
133
120
 
134
121
  def handle_ticker(self, client: Client, message):
135
122
  #
@@ -162,7 +149,9 @@ class probit(ccxt.async_support.probit):
162
149
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
163
150
  """
164
151
  get the list of most recent trades for a particular symbol
165
- :see: https://docs-en.probit.com/reference/trade_history
152
+
153
+ https://docs-en.probit.com/reference/trade_history
154
+
166
155
  :param str symbol: unified symbol of the market to fetch trades for
167
156
  :param int [since]: timestamp in ms of the earliest trade to fetch
168
157
  :param int [limit]: the maximum amount of trades to fetch
@@ -170,9 +159,9 @@ class probit(ccxt.async_support.probit):
170
159
  :param int [params.interval]: Unit time to synchronize market information(ms). Available units: 100, 500
171
160
  :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
172
161
  """
173
- filter = None
174
- filter, params = self.handle_option_and_params(params, 'watchTrades', 'filter', 'recent_trades')
175
- trades = await self.subscribe_order_book(symbol, 'trades', filter, params)
162
+ channel = 'recent_trades'
163
+ symbol = self.safe_symbol(symbol)
164
+ trades = await self.subscribe_public('watchTrades', symbol, 'trades', channel, params)
176
165
  if self.newUpdates:
177
166
  limit = trades.getLimit(symbol, limit)
178
167
  return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
@@ -202,10 +191,11 @@ class probit(ccxt.async_support.probit):
202
191
  symbol = self.safe_symbol(marketId)
203
192
  market = self.safe_market(marketId)
204
193
  trades = self.safe_value(message, 'recent_trades', [])
205
- reset = self.safe_bool(message, 'reset', False)
194
+ if self.safe_bool(message, 'reset', False):
195
+ return # see comment in handleMessage
206
196
  messageHash = 'trades:' + symbol
207
197
  stored = self.safe_value(self.trades, symbol)
208
- if stored is None or reset:
198
+ if stored is None:
209
199
  limit = self.safe_integer(self.options, 'tradesLimit', 1000)
210
200
  stored = ArrayCache(limit)
211
201
  self.trades[symbol] = stored
@@ -219,6 +209,9 @@ class probit(ccxt.async_support.probit):
219
209
  async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
220
210
  """
221
211
  get the list of trades associated with the user
212
+
213
+ https://docs-en.probit.com/reference/trade_history
214
+
222
215
  :param str symbol: unified symbol of the market to fetch trades for
223
216
  :param int [since]: timestamp in ms of the earliest trade to fetch
224
217
  :param int [limit]: the maximum amount of trades to fetch
@@ -227,19 +220,11 @@ class probit(ccxt.async_support.probit):
227
220
  """
228
221
  await self.load_markets()
229
222
  await self.authenticate(params)
230
- messageHash = 'myTrades'
223
+ messageHash = 'trades'
231
224
  if symbol is not None:
232
- market = self.market(symbol)
233
- symbol = market['symbol']
225
+ symbol = self.safe_symbol(symbol)
234
226
  messageHash = messageHash + ':' + symbol
235
- url = self.urls['api']['ws']
236
- channel = 'trade_history'
237
- message: dict = {
238
- 'type': 'subscribe',
239
- 'channel': channel,
240
- }
241
- request = self.extend(message, params)
242
- trades = await self.watch(url, messageHash, request, channel)
227
+ trades = await self.subscribe_private(messageHash, 'trade_history', params)
243
228
  if self.newUpdates:
244
229
  limit = trades.getLimit(symbol, limit)
245
230
  return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
@@ -268,10 +253,11 @@ class probit(ccxt.async_support.probit):
268
253
  length = len(rawTrades)
269
254
  if length == 0:
270
255
  return
271
- reset = self.safe_bool(message, 'reset', False)
272
- messageHash = 'myTrades'
256
+ if self.safe_bool(message, 'reset', False):
257
+ return # see comment in handleMessage
258
+ messageHash = 'trades'
273
259
  stored = self.myTrades
274
- if (stored is None) or reset:
260
+ if stored is None:
275
261
  limit = self.safe_integer(self.options, 'tradesLimit', 1000)
276
262
  stored = ArrayCacheBySymbolById(limit)
277
263
  self.myTrades = stored
@@ -279,9 +265,15 @@ class probit(ccxt.async_support.probit):
279
265
  tradeSymbols: dict = {}
280
266
  for j in range(0, len(trades)):
281
267
  trade = trades[j]
268
+ # don't include 'executed' state, because it's just blanket state of the trade, emited before actual trade event
269
+ if self.safe_string(trade['info'], 'status') == 'executed':
270
+ continue
282
271
  tradeSymbols[trade['symbol']] = True
283
272
  stored.append(trade)
284
273
  unique = list(tradeSymbols.keys())
274
+ uniqueLength = len(unique)
275
+ if uniqueLength == 0:
276
+ return
285
277
  for i in range(0, len(unique)):
286
278
  symbol = unique[i]
287
279
  symbolSpecificMessageHash = messageHash + ':' + symbol
@@ -291,7 +283,9 @@ class probit(ccxt.async_support.probit):
291
283
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
292
284
  """
293
285
  watches information on an order made by the user
294
- :see: https://docs-en.probit.com/reference/open_order
286
+
287
+ https://docs-en.probit.com/reference/open_order
288
+
295
289
  :param str symbol: unified symbol of the market the order was made in
296
290
  :param int [since]: timestamp in ms of the earliest order to watch
297
291
  :param int [limit]: the maximum amount of orders to watch
@@ -300,20 +294,11 @@ class probit(ccxt.async_support.probit):
300
294
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
301
295
  """
302
296
  await self.authenticate(params)
303
- url = self.urls['api']['ws']
304
297
  messageHash = 'orders'
305
298
  if symbol is not None:
306
- market = self.market(symbol)
307
- symbol = market['symbol']
299
+ symbol = self.safe_symbol(symbol)
308
300
  messageHash = messageHash + ':' + symbol
309
- channel = None
310
- channel, params = self.handle_option_and_params(params, 'watchOrders', 'channel', 'open_order')
311
- subscribe: dict = {
312
- 'type': 'subscribe',
313
- 'channel': channel,
314
- }
315
- request = self.extend(subscribe, params)
316
- orders = await self.watch(url, messageHash, request, channel)
301
+ orders = await self.subscribe_private(messageHash, 'open_order', params)
317
302
  if self.newUpdates:
318
303
  limit = orders.getLimit(symbol, limit)
319
304
  return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
@@ -370,45 +355,57 @@ class probit(ccxt.async_support.probit):
370
355
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
371
356
  """
372
357
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
373
- :see: https://docs-en.probit.com/reference/marketdata
358
+
359
+ https://docs-en.probit.com/reference/marketdata
360
+
374
361
  :param str symbol: unified symbol of the market to fetch the order book for
375
362
  :param int [limit]: the maximum amount of order book entries to return
376
363
  :param dict [params]: extra parameters specific to the exchange API endpoint
377
364
  :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
378
365
  """
379
- filter = None
380
- filter, params = self.handle_option_and_params(params, 'watchOrderBook', 'filter', 'order_books')
381
- orderbook = await self.subscribe_order_book(symbol, 'orderbook', filter, params)
366
+ channel = None
367
+ channel, params = self.handle_option_and_params(params, 'watchOrderBook', 'filter', 'order_books')
368
+ orderbook = await self.subscribe_public('watchOrderBook', symbol, 'orderbook', channel, params)
382
369
  return orderbook.limit()
383
370
 
384
- async def subscribe_order_book(self, symbol: str, messageHash, filter, params={}):
371
+ async def subscribe_private(self, messageHash, channel, params):
372
+ url = self.urls['api']['ws']
373
+ subscribe: dict = {
374
+ 'type': 'subscribe',
375
+ 'channel': channel,
376
+ }
377
+ request = self.extend(subscribe, params)
378
+ subscribeHash = messageHash
379
+ return await self.watch(url, messageHash, request, subscribeHash)
380
+
381
+ async def subscribe_public(self, methodName: str, symbol: str, dataType, filter, params={}):
385
382
  await self.load_markets()
386
383
  market = self.market(symbol)
387
384
  symbol = market['symbol']
388
385
  url = self.urls['api']['ws']
389
386
  client = self.client(url)
390
- interval = None
391
- interval, params = self.handle_option_and_params(params, 'watchOrderBook', 'interval', 100)
392
- subscriptionHash = 'marketdata:' + symbol
393
- messageHash = messageHash + ':' + symbol
387
+ subscribeHash = 'marketdata:' + symbol
388
+ messageHash = dataType + ':' + symbol
394
389
  filters = {}
395
- if subscriptionHash in client.subscriptions:
390
+ if subscribeHash in client.subscriptions:
396
391
  # already subscribed
397
- filters = client.subscriptions[subscriptionHash]
392
+ filters = client.subscriptions[subscribeHash]
398
393
  if not (filter in filters):
399
394
  # resubscribe
400
- del client.subscriptions[subscriptionHash]
395
+ del client.subscriptions[subscribeHash]
401
396
  filters[filter] = True
402
397
  keys = list(filters.keys())
403
- message: dict = {
398
+ interval = None
399
+ interval, params = self.handle_option_and_params(params, methodName, 'interval', 100)
400
+ request: dict = {
401
+ 'type': 'subscribe',
404
402
  'channel': 'marketdata',
405
- 'interval': interval,
406
403
  'market_id': market['id'],
407
- 'type': 'subscribe',
408
404
  'filter': keys,
405
+ 'interval': interval,
409
406
  }
410
- request = self.extend(message, params)
411
- return await self.watch(url, messageHash, request, messageHash, filters)
407
+ request = self.extend(request, params)
408
+ return await self.watch(url, messageHash, request, subscribeHash, filters)
412
409
 
413
410
  def handle_order_book(self, client: Client, message, orderBook):
414
411
  #
@@ -454,7 +451,7 @@ class probit(ccxt.async_support.probit):
454
451
  self.handle_bid_asks(storedBids, bids)
455
452
  self.handle_bid_asks(storedAsks, asks)
456
453
 
457
- def handle_error_message(self, client: Client, message):
454
+ def handle_error_message(self, client: Client, message) -> Bool:
458
455
  #
459
456
  # {
460
457
  # "errorCode": "INVALID_ARGUMENT",
@@ -467,8 +464,12 @@ class probit(ccxt.async_support.probit):
467
464
  code = self.safe_string(message, 'errorCode')
468
465
  errMessage = self.safe_string(message, 'message', '')
469
466
  details = self.safe_value(message, 'details')
470
- # todo - raise properly here
471
- raise ExchangeError(self.id + ' ' + code + ' ' + errMessage + ' ' + self.json(details))
467
+ feedback = self.id + ' ' + code + ' ' + errMessage + ' ' + self.json(details)
468
+ if 'exact' in self.exceptions:
469
+ self.throw_exactly_matched_exception(self.exceptions['exact'], code, feedback)
470
+ if 'broad' in self.exceptions:
471
+ self.throw_broadly_matched_exception(self.exceptions['broad'], errMessage, feedback)
472
+ raise ExchangeError(feedback)
472
473
 
473
474
  def handle_authenticate(self, client: Client, message):
474
475
  #
@@ -477,7 +478,8 @@ class probit(ccxt.async_support.probit):
477
478
  result = self.safe_string(message, 'result')
478
479
  future = client.subscriptions['authenticated']
479
480
  if result == 'ok':
480
- future.resolve(True)
481
+ messageHash = 'authenticated'
482
+ client.resolve(message, messageHash)
481
483
  else:
482
484
  future.reject(message)
483
485
  del client.subscriptions['authenticated']
@@ -487,10 +489,12 @@ class probit(ccxt.async_support.probit):
487
489
  if ticker is not None:
488
490
  self.handle_ticker(client, message)
489
491
  trades = self.safe_value(message, 'recent_trades', [])
490
- if len(trades):
492
+ tradesLength = len(trades)
493
+ if tradesLength:
491
494
  self.handle_trades(client, message)
492
495
  orderBook = self.safe_value_n(message, ['order_books', 'order_books_l1', 'order_books_l2', 'order_books_l3', 'order_books_l4'], [])
493
- if len(orderBook):
496
+ orderBookLength = len(orderBook)
497
+ if orderBookLength:
494
498
  self.handle_order_book(client, message, orderBook)
495
499
 
496
500
  def handle_message(self, client: Client, message):
@@ -503,6 +507,9 @@ class probit(ccxt.async_support.probit):
503
507
  # }
504
508
  # }
505
509
  #
510
+ # Note about 'reset' field
511
+ # 'reset': True field - it happens once after initial subscription, which just returns old items by the moment of subscription(like "fetchMyTrades" does)
512
+ #
506
513
  errorCode = self.safe_string(message, 'errorCode')
507
514
  if errorCode is not None:
508
515
  self.handle_error_message(client, message)
ccxt/pro/tradeogre.py ADDED
@@ -0,0 +1,272 @@
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
8
+ from ccxt.base.types import Any, Int, OrderBook, Trade
9
+ from ccxt.async_support.base.ws.client import Client
10
+ from typing import List
11
+
12
+
13
+ class tradeogre(ccxt.async_support.tradeogre):
14
+
15
+ def describe(self) -> Any:
16
+ return self.deep_extend(super(tradeogre, self).describe(), {
17
+ 'has': {
18
+ 'ws': True,
19
+ 'watchTrades': True,
20
+ 'watchTradesForSymbols': True,
21
+ 'watchOrderBook': True,
22
+ 'watchOrderBookForSymbols': False,
23
+ 'watchOHLCV': False,
24
+ 'watchOHLCVForSymbols': False,
25
+ 'watchOrders': False,
26
+ 'watchMyTrades': False,
27
+ 'watchTicker': False,
28
+ 'watchTickers': False,
29
+ 'watchBidsAsks': False,
30
+ 'watchBalance': False,
31
+ 'createOrderWs': False,
32
+ 'editOrderWs': False,
33
+ 'cancelOrderWs': False,
34
+ 'cancelOrdersWs': False,
35
+ },
36
+ 'urls': {
37
+ 'api': {
38
+ 'ws': 'wss://tradeogre.com:8443',
39
+ },
40
+ },
41
+ 'options': {
42
+ },
43
+ 'streaming': {
44
+ },
45
+ })
46
+
47
+ async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
48
+ """
49
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
50
+
51
+ https://tradeogre.com/help/api
52
+
53
+ :param str symbol: unified symbol of the market to fetch the order book for
54
+ :param int [limit]: the maximum amount of order book entries to return(not used by the exchange)
55
+ :param dict [params]: extra parameters specific to the exchange API endpoint
56
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
57
+ """
58
+ await self.load_markets()
59
+ market = self.market(symbol)
60
+ url = self.urls['api']['ws']
61
+ messageHash = 'orderbook' + ':' + market['symbol']
62
+ request: dict = {
63
+ 'a': 'subscribe',
64
+ 'e': 'book',
65
+ 't': market['id'],
66
+ }
67
+ orderbook = await self.watch(url, messageHash, self.extend(request, params), messageHash)
68
+ return orderbook.limit()
69
+
70
+ def handle_order_book(self, client: Client, message):
71
+ #
72
+ # initial snapshot is fetched with ccxt's fetchOrderBook
73
+ # the feed does not include a snapshot, just the deltas
74
+ #
75
+ # {
76
+ # "e": "book",
77
+ # "t": "ETH-USDT",
78
+ # "s": "10752324",
79
+ # "d": {
80
+ # "bids": {"1787.02497915": "0"},
81
+ # "asks": {}
82
+ # }
83
+ # }
84
+ #
85
+ marketId = self.safe_string(message, 't')
86
+ symbol = self.safe_symbol(marketId)
87
+ if not (symbol in self.orderbooks):
88
+ self.orderbooks[symbol] = self.order_book({})
89
+ storedOrderBook = self.orderbooks[symbol]
90
+ nonce = self.safe_integer(storedOrderBook, 'nonce')
91
+ deltaNonce = self.safe_integer(message, 's')
92
+ messageHash = 'orderbook:' + symbol
93
+ if nonce is None:
94
+ cacheLength = len(storedOrderBook.cache)
95
+ snapshotDelay = self.handle_option('watchOrderBook', 'snapshotDelay', 6)
96
+ if cacheLength == snapshotDelay:
97
+ self.spawn(self.load_order_book, client, messageHash, symbol, None, {})
98
+ storedOrderBook.cache.append(message)
99
+ return
100
+ elif nonce >= deltaNonce:
101
+ return
102
+ self.handle_delta(storedOrderBook, message)
103
+ client.resolve(storedOrderBook, messageHash)
104
+
105
+ def handle_delta(self, orderbook, delta):
106
+ # timestamp = self.milliseconds() # todo check if self is correct
107
+ # orderbook['timestamp'] = timestamp
108
+ # orderbook['datetime'] = self.iso8601(timestamp)
109
+ orderbook['nonce'] = self.safe_integer(delta, 's')
110
+ data = self.safe_dict(delta, 'd', {})
111
+ bids = self.safe_dict(data, 'bids', {})
112
+ asks = self.safe_dict(data, 'asks', {})
113
+ storedBids = orderbook['bids']
114
+ storedAsks = orderbook['asks']
115
+ self.handle_bid_asks(storedBids, bids)
116
+ self.handle_bid_asks(storedAsks, asks)
117
+
118
+ def handle_bid_asks(self, bookSide, bidAsks):
119
+ keys = list(bidAsks.keys())
120
+ for i in range(0, len(keys)):
121
+ price = self.safe_string(keys, i)
122
+ amount = self.safe_number(bidAsks, price)
123
+ bidAsk = [self.parse_number(price), amount]
124
+ bookSide.storeArray(bidAsk)
125
+ # for i in range(0, len(bidAsks)):
126
+ # bidAsk = self.parse_bid_ask(bidAsks[i])
127
+ # bookSide.storeArray(bidAsk)
128
+ # }
129
+
130
+ def get_cache_index(self, orderbook, deltas):
131
+ firstElement = deltas[0]
132
+ firstElementNonce = self.safe_integer(firstElement, 's')
133
+ nonce = self.safe_integer(orderbook, 'nonce')
134
+ if nonce < firstElementNonce:
135
+ return -1
136
+ for i in range(0, len(deltas)):
137
+ delta = deltas[i]
138
+ deltaNonce = self.safe_integer(delta, 's')
139
+ if deltaNonce == nonce:
140
+ return i + 1
141
+ return len(deltas)
142
+
143
+ async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
144
+ """
145
+ watches information on multiple trades made in a market
146
+
147
+ https://tradeogre.com/help/api
148
+
149
+ :param str symbol: unified market symbol of the market trades were made in
150
+ :param int [since]: the earliest time in ms to fetch trades for
151
+ :param int [limit]: the maximum number of trade structures to retrieve
152
+ :param dict [params]: extra parameters specific to the exchange API endpoint
153
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
154
+ """
155
+ await self.load_markets()
156
+ market = self.market(symbol)
157
+ symbol = market['symbol']
158
+ return await self.watch_trades_for_symbols([symbol], since, limit, params)
159
+
160
+ async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
161
+ """
162
+
163
+ https://tradeogre.com/help/api
164
+
165
+ get the list of most recent trades for a list of symbols
166
+ :param str[] symbols: unified symbol of the market to fetch trades for(empty array means all markets)
167
+ :param int [since]: timestamp in ms of the earliest trade to fetch
168
+ :param int [limit]: the maximum amount of trades to fetch
169
+ :param dict [params]: extra parameters specific to the exchange API endpoint
170
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
171
+ """
172
+ await self.load_markets()
173
+ symbols = self.market_symbols(symbols, None, True)
174
+ messageHashes = []
175
+ symbolsLength = 0
176
+ if symbols is not None:
177
+ symbolsLength = len(symbols)
178
+ if symbolsLength > 0:
179
+ for i in range(0, len(symbols)):
180
+ symbol = symbols[i]
181
+ messageHash = 'trades:' + symbol
182
+ messageHashes.append(messageHash)
183
+ else:
184
+ messageHash = 'trades'
185
+ messageHashes.append(messageHash)
186
+ request: dict = {
187
+ 'a': 'subscribe',
188
+ 'e': 'trade',
189
+ 't': '*',
190
+ }
191
+ url = self.urls['api']['ws']
192
+ trades = await self.watch_multiple(url, messageHashes, self.extend(request, params), ['trades'])
193
+ if self.newUpdates:
194
+ first = self.safe_dict(trades, 0)
195
+ tradeSymbol = self.safe_string(first, 'symbol')
196
+ limit = trades.getLimit(tradeSymbol, limit)
197
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
198
+
199
+ def handle_trade(self, client: Client, message):
200
+ #
201
+ # {
202
+ # "e": "trade",
203
+ # "t": "LTC-USDT",
204
+ # "d": {
205
+ # "t": 0,
206
+ # "p": "84.50000000",
207
+ # "q": "1.28471270",
208
+ # "d": "1745392002"
209
+ # }
210
+ # }
211
+ #
212
+ marketId = self.safe_string(message, 't')
213
+ market = self.safe_market(marketId)
214
+ data = self.safe_dict(message, 'd', {})
215
+ symbol = market['symbol']
216
+ if not (symbol in self.trades):
217
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
218
+ stored = ArrayCache(limit)
219
+ self.trades[symbol] = stored
220
+ cache = self.trades[symbol]
221
+ trade = self.parse_ws_trade(data, market)
222
+ cache.append(trade)
223
+ messageHash = 'trades:' + symbol
224
+ client.resolve(cache, messageHash)
225
+ client.resolve(cache, 'trades')
226
+
227
+ def parse_ws_trade(self, trade, market=None):
228
+ #
229
+ # {
230
+ # "t": 0,
231
+ # "p": "84.50000000",
232
+ # "q": "1.28471270",
233
+ # "d": "1745392002"
234
+ # }
235
+ #
236
+ timestamp = self.safe_integer_product(trade, 'd', 1000)
237
+ sideEnum = self.safe_string(trade, 't')
238
+ return self.safe_trade({
239
+ 'info': trade,
240
+ 'id': None,
241
+ 'timestamp': timestamp,
242
+ 'datetime': self.iso8601(timestamp),
243
+ 'symbol': self.safe_string(market, 'symbol'),
244
+ 'order': None,
245
+ 'type': None,
246
+ 'side': self.parse_ws_trade_side(sideEnum),
247
+ 'takerOrMaker': None,
248
+ 'price': self.safe_string(trade, 'p'),
249
+ 'amount': self.safe_string(trade, 'q'),
250
+ 'cost': None,
251
+ 'fee': {
252
+ 'currency': None,
253
+ 'cost': None,
254
+ },
255
+ }, market)
256
+
257
+ def parse_ws_trade_side(self, side):
258
+ sides = {
259
+ '0': 'buy',
260
+ '1': 'sell',
261
+ }
262
+ return self.safe_string(sides, side, side)
263
+
264
+ def handle_message(self, client: Client, message):
265
+ methods: dict = {
266
+ 'book': self.handle_order_book,
267
+ 'trade': self.handle_trade,
268
+ }
269
+ event = self.safe_string(message, 'e')
270
+ method = self.safe_value(methods, event)
271
+ if method is not None:
272
+ method(client, message)