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/apex.py ADDED
@@ -0,0 +1,984 @@
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, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
8
+ import asyncio
9
+ import hashlib
10
+ import json
11
+ from ccxt.base.types import Any, Bool, Int, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
12
+ from ccxt.async_support.base.ws.client import Client
13
+ from typing import List
14
+ from ccxt.base.errors import ExchangeError
15
+ from ccxt.base.errors import AuthenticationError
16
+ from ccxt.base.errors import ArgumentsRequired
17
+
18
+
19
+ class apex(ccxt.async_support.apex):
20
+
21
+ def describe(self) -> Any:
22
+ return self.deep_extend(super(apex, self).describe(), {
23
+ 'has': {
24
+ 'ws': True,
25
+ 'watchTicker': True,
26
+ 'watchTickers': True,
27
+ 'watchOrderBook': True,
28
+ 'watchOrders': True,
29
+ 'watchTrades': True,
30
+ 'watchTradesForSymbols': False,
31
+ 'watchPositions': True,
32
+ 'watchMyTrades': True,
33
+ 'watchBalance': False,
34
+ 'watchOHLCV': True,
35
+ },
36
+ 'urls': {
37
+ 'logo': 'https://omni.apex.exchange/assets/logo_content-CY9uyFbz.svg',
38
+ 'api': {
39
+ 'ws': {
40
+ 'public': 'wss://quote.omni.apex.exchange/realtime_public?v=2',
41
+ 'private': 'wss://quote.omni.apex.exchange/realtime_private?v=2',
42
+ },
43
+ },
44
+ 'test': {
45
+ 'ws': {
46
+ 'public': 'wss://qa-quote.omni.apex.exchange/realtime_public?v=2',
47
+ 'private': 'wss://qa-quote.omni.apex.exchange/realtime_private?v=2',
48
+ },
49
+ },
50
+ 'www': 'https://apex.exchange/',
51
+ 'doc': 'https://api-docs.pro.apex.exchange',
52
+ 'fees': 'https://apex-pro.gitbook.io/apex-pro/apex-omni-live-now/trading-perpetual-contracts/trading-fees',
53
+ 'referral': 'https://omni.apex.exchange/trade',
54
+ },
55
+ 'options': {},
56
+ 'streaming': {
57
+ 'ping': self.ping,
58
+ 'keepAlive': 18000,
59
+ },
60
+ })
61
+
62
+ async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
63
+ """
64
+ watches information on multiple trades made in a market
65
+
66
+ https://api-docs.pro.apex.exchange/#websocket-v3-for-omni-websocket-endpoint
67
+
68
+ :param str symbol: unified market symbol of the market trades were made in
69
+ :param int [since]: the earliest time in ms to fetch trades for
70
+ :param int [limit]: the maximum number of trade structures to retrieve
71
+ :param dict [params]: extra parameters specific to the exchange API endpoint
72
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
73
+ """
74
+ return await self.watch_trades_for_symbols([symbol], since, limit, params)
75
+
76
+ async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
77
+ """
78
+ get the list of most recent trades for a list of symbols
79
+
80
+ https://api-docs.pro.apex.exchange/#websocket-v3-for-omni-websocket-endpoint
81
+
82
+ :param str[] symbols: unified symbol of the market to fetch trades for
83
+ :param int [since]: timestamp in ms of the earliest trade to fetch
84
+ :param int [limit]: the maximum amount of trades to fetch
85
+ :param dict [params]: extra parameters specific to the exchange API endpoint
86
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
87
+ """
88
+ await self.load_markets()
89
+ symbols = self.market_symbols(symbols)
90
+ symbolsLength = len(symbols)
91
+ if symbolsLength == 0:
92
+ raise ArgumentsRequired(self.id + ' watchTradesForSymbols() requires a non-empty array of symbols')
93
+ timeStamp = str(self.milliseconds())
94
+ url = self.urls['api']['ws']['public'] + '&timestamp=' + timeStamp
95
+ topics = []
96
+ messageHashes = []
97
+ for i in range(0, len(symbols)):
98
+ symbol = symbols[i]
99
+ market = self.market(symbol)
100
+ topic = 'recentlyTrade.H.' + market['id2']
101
+ topics.append(topic)
102
+ messageHash = 'trade:' + symbol
103
+ messageHashes.append(messageHash)
104
+ trades = await self.watch_topics(url, messageHashes, topics, params)
105
+ if self.newUpdates:
106
+ first = self.safe_value(trades, 0)
107
+ tradeSymbol = self.safe_string(first, 'symbol')
108
+ limit = trades.getLimit(tradeSymbol, limit)
109
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
110
+
111
+ def handle_trades(self, client: Client, message):
112
+ #
113
+ # {
114
+ # "topic": "recentlyTrade.H.BTCUSDT",
115
+ # "type": "snapshot",
116
+ # "ts": 1672304486868,
117
+ # "data": [
118
+ # {
119
+ # "T": 1672304486865,
120
+ # "s": "BTCUSDT",
121
+ # "S": "Buy",
122
+ # "v": "0.001",
123
+ # "p": "16578.50",
124
+ # "L": "PlusTick",
125
+ # "i": "20f43950-d8dd-5b31-9112-a178eb6023af",
126
+ # "BT": False
127
+ # }
128
+ # ]
129
+ # }
130
+ #
131
+ data = self.safe_value(message, 'data', {})
132
+ topic = self.safe_string(message, 'topic')
133
+ trades = data
134
+ parts = topic.split('.')
135
+ marketId = self.safe_string(parts, 2)
136
+ market = self.safe_market(marketId, None, None)
137
+ symbol = market['symbol']
138
+ stored = self.safe_value(self.trades, symbol)
139
+ if stored is None:
140
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
141
+ stored = ArrayCache(limit)
142
+ self.trades[symbol] = stored
143
+ for j in range(0, len(trades)):
144
+ parsed = self.parse_ws_trade(trades[j], market)
145
+ stored.append(parsed)
146
+ messageHash = 'trade' + ':' + symbol
147
+ client.resolve(stored, messageHash)
148
+
149
+ def parse_ws_trade(self, trade, market=None):
150
+ #
151
+ # public
152
+ # {
153
+ # "T": 1672304486865,
154
+ # "s": "BTCUSDT",
155
+ # "S": "Buy",
156
+ # "v": "0.001",
157
+ # "p": "16578.50",
158
+ # "L": "PlusTick",
159
+ # "i": "20f43950-d8dd-5b31-9112-a178eb6023af",
160
+ # "BT": False
161
+ # }
162
+ #
163
+ id = self.safe_string_n(trade, ['i', 'id', 'v'])
164
+ marketId = self.safe_string_n(trade, ['s', 'symbol'])
165
+ market = self.safe_market(marketId, market, None)
166
+ symbol = market['symbol']
167
+ timestamp = self.safe_integer_n(trade, ['t', 'T', 'createdAt'])
168
+ side = self.safe_string_lower_n(trade, ['S', 'side'])
169
+ price = self.safe_string_n(trade, ['p', 'price'])
170
+ amount = self.safe_string_n(trade, ['q', 'v', 'size'])
171
+ return self.safe_trade({
172
+ 'id': id,
173
+ 'info': trade,
174
+ 'timestamp': timestamp,
175
+ 'datetime': self.iso8601(timestamp),
176
+ 'symbol': symbol,
177
+ 'order': None,
178
+ 'type': None,
179
+ 'side': side,
180
+ 'takerOrMaker': None,
181
+ 'price': price,
182
+ 'amount': amount,
183
+ 'cost': None,
184
+ 'fee': None,
185
+ }, market)
186
+
187
+ async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
188
+ """
189
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
190
+
191
+ https://api-docs.pro.apex.exchange/#websocket-v3-for-omni-websocket-endpoint
192
+
193
+ :param str symbol: unified symbol of the market to fetch the order book for
194
+ :param int [limit]: the maximum amount of order book entries to return.
195
+ :param dict [params]: extra parameters specific to the exchange API endpoint
196
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
197
+ """
198
+ return await self.watch_order_book_for_symbols([symbol], limit, params)
199
+
200
+ async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
201
+ """
202
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
203
+
204
+ https://api-docs.pro.apex.exchange/#websocket-v3-for-omni-websocket-endpoint
205
+
206
+ :param str[] symbols: unified array of symbols
207
+ :param int [limit]: the maximum amount of order book entries to return.
208
+ :param dict [params]: extra parameters specific to the exchange API endpoint
209
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
210
+ """
211
+ await self.load_markets()
212
+ symbolsLength = len(symbols)
213
+ if symbolsLength == 0:
214
+ raise ArgumentsRequired(self.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols')
215
+ symbols = self.market_symbols(symbols)
216
+ timeStamp = str(self.milliseconds())
217
+ url = self.urls['api']['ws']['public'] + '&timestamp=' + timeStamp
218
+ topics = []
219
+ messageHashes = []
220
+ for i in range(0, len(symbols)):
221
+ symbol = symbols[i]
222
+ market = self.market(symbol)
223
+ if limit is None:
224
+ limit = 25
225
+ topic = 'orderBook' + str(limit) + '.H.' + market['id2']
226
+ topics.append(topic)
227
+ messageHash = 'orderbook:' + symbol
228
+ messageHashes.append(messageHash)
229
+ orderbook = await self.watch_topics(url, messageHashes, topics, params)
230
+ return orderbook.limit()
231
+
232
+ async def watch_topics(self, url, messageHashes, topics, params={}):
233
+ request: dict = {
234
+ 'op': 'subscribe',
235
+ 'args': topics,
236
+ }
237
+ message = self.extend(request, params)
238
+ return await self.watch_multiple(url, messageHashes, message, messageHashes)
239
+
240
+ def handle_order_book(self, client: Client, message):
241
+ #
242
+ # {
243
+ # "topic": "orderbook25.H.BTCUSDT",
244
+ # "type": "snapshot",
245
+ # "ts": 1672304484978,
246
+ # "data": {
247
+ # "s": "BTCUSDT",
248
+ # "b": [
249
+ # ...,
250
+ # [
251
+ # "16493.50",
252
+ # "0.006"
253
+ # ],
254
+ # [
255
+ # "16493.00",
256
+ # "0.100"
257
+ # ]
258
+ # ],
259
+ # "a": [
260
+ # [
261
+ # "16611.00",
262
+ # "0.029"
263
+ # ],
264
+ # [
265
+ # "16612.00",
266
+ # "0.213"
267
+ # ],
268
+ # ],
269
+ # "u": 18521288,
270
+ # "seq": 7961638724
271
+ # }
272
+ # }
273
+ #
274
+ type = self.safe_string(message, 'type')
275
+ isSnapshot = (type == 'snapshot')
276
+ data = self.safe_dict(message, 'data', {})
277
+ marketId = self.safe_string(data, 's')
278
+ market = self.safe_market(marketId, None, None)
279
+ symbol = market['symbol']
280
+ timestamp = self.safe_integer_product(message, 'ts', 0.001)
281
+ if not (symbol in self.orderbooks):
282
+ self.orderbooks[symbol] = self.order_book()
283
+ orderbook = self.orderbooks[symbol]
284
+ if isSnapshot:
285
+ snapshot = self.parse_order_book(data, symbol, timestamp, 'b', 'a')
286
+ orderbook.reset(snapshot)
287
+ else:
288
+ asks = self.safe_list(data, 'a', [])
289
+ bids = self.safe_list(data, 'b', [])
290
+ self.handle_deltas(orderbook['asks'], asks)
291
+ self.handle_deltas(orderbook['bids'], bids)
292
+ orderbook['timestamp'] = timestamp
293
+ orderbook['datetime'] = self.iso8601(timestamp)
294
+ messageHash = 'orderbook' + ':' + symbol
295
+ self.orderbooks[symbol] = orderbook
296
+ client.resolve(orderbook, messageHash)
297
+
298
+ def handle_delta(self, bookside, delta):
299
+ bidAsk = self.parse_bid_ask(delta, 0, 1)
300
+ bookside.storeArray(bidAsk)
301
+
302
+ def handle_deltas(self, bookside, deltas):
303
+ for i in range(0, len(deltas)):
304
+ self.handle_delta(bookside, deltas[i])
305
+
306
+ async def watch_ticker(self, symbol: str, params={}) -> Ticker:
307
+ """
308
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
309
+
310
+ https://api-docs.pro.apex.exchange/#websocket-v3-for-omni-websocket-endpoint
311
+
312
+ :param str symbol: unified symbol of the market to fetch the ticker for
313
+ :param dict [params]: extra parameters specific to the exchange API endpoint
314
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
315
+ """
316
+ await self.load_markets()
317
+ market = self.market(symbol)
318
+ symbol = market['symbol']
319
+ timeStamp = str(self.milliseconds())
320
+ url = self.urls['api']['ws']['public'] + '&timestamp=' + timeStamp
321
+ messageHash = 'ticker:' + symbol
322
+ topic = 'instrumentInfo' + '.H.' + market['id2']
323
+ topics = [topic]
324
+ return await self.watch_topics(url, [messageHash], topics, params)
325
+
326
+ async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
327
+ """
328
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
329
+
330
+ https://api-docs.pro.apex.exchange/#websocket-v3-for-omni-websocket-endpoint
331
+
332
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
333
+ :param dict [params]: extra parameters specific to the exchange API endpoint
334
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
335
+ """
336
+ await self.load_markets()
337
+ symbols = self.market_symbols(symbols, None, False)
338
+ messageHashes = []
339
+ timeStamp = str(self.milliseconds())
340
+ url = self.urls['api']['ws']['public'] + '&timestamp=' + timeStamp
341
+ topics = []
342
+ for i in range(0, len(symbols)):
343
+ symbol = symbols[i]
344
+ market = self.market(symbol)
345
+ topic = 'instrumentInfo' + '.H.' + market['id2']
346
+ topics.append(topic)
347
+ messageHash = 'ticker:' + symbol
348
+ messageHashes.append(messageHash)
349
+ ticker = await self.watch_topics(url, messageHashes, topics, params)
350
+ if self.newUpdates:
351
+ result: dict = {}
352
+ result[ticker['symbol']] = ticker
353
+ return result
354
+ return self.filter_by_array(self.tickers, 'symbol', symbols)
355
+
356
+ def handle_ticker(self, client: Client, message):
357
+ # "topic":"instrumentInfo.H.BTCUSDT",
358
+ # "type":"snapshot",
359
+ # "data":{
360
+ # "symbol":"BTCUSDT",
361
+ # "lastPrice":"21572.5",
362
+ # "price24hPcnt":"-0.0194318181818182",
363
+ # "highPrice24h":"25306.5",
364
+ # "lowPrice24h":"17001.5",
365
+ # "turnover24h":"1334891.4545",
366
+ # "volume24h":"64.896",
367
+ # "nextFundingTime":"2022-08-26T08:00:00Z",
368
+ # "oraclePrice":"21412.060000000002752512",
369
+ # "indexPrice":"21409.82",
370
+ # "openInterest":"49.598",
371
+ # "tradeCount":"0",
372
+ # "fundingRate":"0.0000125",
373
+ # "predictedFundingRate":"0.0000125"
374
+ # },
375
+ # "cs":44939063,
376
+ # "ts":1661500091955487
377
+ # }
378
+ topic = self.safe_string(message, 'topic', '')
379
+ updateType = self.safe_string(message, 'type', '')
380
+ data = self.safe_dict(message, 'data', {})
381
+ symbol = None
382
+ parsed = None
383
+ if (updateType == 'snapshot'):
384
+ parsed = self.parse_ticker(data)
385
+ symbol = parsed['symbol']
386
+ elif updateType == 'delta':
387
+ topicParts = topic.split('.')
388
+ topicLength = len(topicParts)
389
+ marketId = self.safe_string(topicParts, topicLength - 1)
390
+ market = self.safe_market(marketId, None, None)
391
+ symbol = market['symbol']
392
+ ticker = self.safe_dict(self.tickers, symbol, {})
393
+ rawTicker = self.safe_dict(ticker, 'info', {})
394
+ merged = self.extend(rawTicker, data)
395
+ parsed = self.parse_ticker(merged)
396
+ timestamp = self.safe_integer_product(message, 'ts', 0.001)
397
+ parsed['timestamp'] = timestamp
398
+ parsed['datetime'] = self.iso8601(timestamp)
399
+ self.tickers[symbol] = parsed
400
+ messageHash = 'ticker:' + symbol
401
+ client.resolve(self.tickers[symbol], messageHash)
402
+
403
+ async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
404
+ """
405
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
406
+
407
+ https://api-docs.pro.apex.exchange/#websocket-v3-for-omni-websocket-endpoint
408
+
409
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
410
+ :param str timeframe: the length of time each candle represents
411
+ :param int [since]: timestamp in ms of the earliest candle to fetch
412
+ :param int [limit]: the maximum amount of candles to fetch
413
+ :param dict [params]: extra parameters specific to the exchange API endpoint
414
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
415
+ """
416
+ params['callerMethodName'] = 'watchOHLCV'
417
+ result = await self.watch_ohlcv_for_symbols([[symbol, timeframe]], since, limit, params)
418
+ return result[symbol][timeframe]
419
+
420
+ async def watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], since: Int = None, limit: Int = None, params={}):
421
+ """
422
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
423
+
424
+ https://api-docs.pro.apex.exchange/#websocket-v3-for-omni-websocket-endpoint
425
+
426
+ :param str[][] symbolsAndTimeframes: array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
427
+ :param int [since]: timestamp in ms of the earliest candle to fetch
428
+ :param int [limit]: the maximum amount of candles to fetch
429
+ :param dict [params]: extra parameters specific to the exchange API endpoint
430
+ :returns dict: A list of candles ordered, open, high, low, close, volume
431
+ """
432
+ await self.load_markets()
433
+ timeStamp = str(self.milliseconds())
434
+ url = self.urls['api']['ws']['public'] + '&timestamp=' + timeStamp
435
+ rawHashes = []
436
+ messageHashes = []
437
+ for i in range(0, len(symbolsAndTimeframes)):
438
+ data = symbolsAndTimeframes[i]
439
+ symbolString = self.safe_string(data, 0)
440
+ market = self.market(symbolString)
441
+ symbolString = market['id2']
442
+ unfiedTimeframe = self.safe_string(data, 1, '1')
443
+ timeframeId = self.safe_string(self.timeframes, unfiedTimeframe, unfiedTimeframe)
444
+ rawHashes.append('candle.' + timeframeId + '.' + symbolString)
445
+ messageHashes.append('ohlcv::' + symbolString + '::' + unfiedTimeframe)
446
+ symbol, timeframe, stored = await self.watch_topics(url, messageHashes, rawHashes, params)
447
+ if self.newUpdates:
448
+ limit = stored.getLimit(symbol, limit)
449
+ filtered = self.filter_by_since_limit(stored, since, limit, 0, True)
450
+ return self.create_ohlcv_object(symbol, timeframe, filtered)
451
+
452
+ def handle_ohlcv(self, client: Client, message):
453
+ #
454
+ # {
455
+ # "topic": "candle.5.BTCUSDT",
456
+ # "data": [
457
+ # {
458
+ # "start": 1672324800000,
459
+ # "end": 1672325099999,
460
+ # "interval": "5",
461
+ # "open": "16649.5",
462
+ # "close": "16677",
463
+ # "high": "16677",
464
+ # "low": "16608",
465
+ # "volume": "2.081",
466
+ # "turnover": "34666.4005",
467
+ # "confirm": False,
468
+ # "timestamp": 1672324988882
469
+ # }
470
+ # ],
471
+ # "ts": 1672324988882,
472
+ # "type": "snapshot"
473
+ # }
474
+ #
475
+ data = self.safe_value(message, 'data', {})
476
+ topic = self.safe_string(message, 'topic')
477
+ topicParts = topic.split('.')
478
+ topicLength = len(topicParts)
479
+ timeframeId = self.safe_string(topicParts, 1)
480
+ timeframe = self.find_timeframe(timeframeId)
481
+ marketId = self.safe_string(topicParts, topicLength - 1)
482
+ isSpot = client.url.find('spot') > -1
483
+ marketType = 'spot' if isSpot else 'contract'
484
+ market = self.safe_market(marketId, None, None, marketType)
485
+ symbol = market['symbol']
486
+ ohlcvsByTimeframe = self.safe_value(self.ohlcvs, symbol)
487
+ if ohlcvsByTimeframe is None:
488
+ self.ohlcvs[symbol] = {}
489
+ if self.safe_value(ohlcvsByTimeframe, timeframe) is None:
490
+ limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
491
+ self.ohlcvs[symbol][timeframe] = ArrayCacheByTimestamp(limit)
492
+ stored = self.ohlcvs[symbol][timeframe]
493
+ for i in range(0, len(data)):
494
+ parsed = self.parse_ws_ohlcv(data[i])
495
+ stored.append(parsed)
496
+ messageHash = 'ohlcv::' + symbol + '::' + timeframe
497
+ resolveData = [symbol, timeframe, stored]
498
+ client.resolve(resolveData, messageHash)
499
+
500
+ def parse_ws_ohlcv(self, ohlcv, market=None) -> list:
501
+ #
502
+ # {
503
+ # "start": 1670363160000,
504
+ # "end": 1670363219999,
505
+ # "interval": "1",
506
+ # "open": "16987.5",
507
+ # "close": "16987.5",
508
+ # "high": "16988",
509
+ # "low": "16987.5",
510
+ # "volume": "23.511",
511
+ # "turnover": "399396.344",
512
+ # "confirm": False,
513
+ # "timestamp": 1670363219614
514
+ # }
515
+ #
516
+ return [
517
+ self.safe_integer(ohlcv, 'start'),
518
+ self.safe_number(ohlcv, 'open'),
519
+ self.safe_number(ohlcv, 'high'),
520
+ self.safe_number(ohlcv, 'low'),
521
+ self.safe_number(ohlcv, 'close'),
522
+ self.safe_number_2(ohlcv, 'volume', 'turnover'),
523
+ ]
524
+
525
+ async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
526
+ """
527
+ watches information on multiple trades made by the user
528
+
529
+ https://api-docs.pro.apex.exchange/#private-websocket
530
+
531
+ :param str symbol: unified market symbol of the market orders were made in
532
+ :param int [since]: the earliest time in ms to fetch orders for
533
+ :param int [limit]: the maximum number of order structures to retrieve
534
+ :param dict [params]: extra parameters specific to the exchange API endpoint
535
+ :param boolean [params.unifiedMargin]: use unified margin account
536
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
537
+ """
538
+ messageHash = 'myTrades'
539
+ await self.load_markets()
540
+ if symbol is not None:
541
+ symbol = self.symbol(symbol)
542
+ messageHash += ':' + symbol
543
+ timeStamp = str(self.milliseconds())
544
+ url = self.urls['api']['ws']['private'] + '&timestamp=' + timeStamp
545
+ await self.authenticate(url)
546
+ trades = await self.watch_topics(url, [messageHash], ['myTrades'], params)
547
+ if self.newUpdates:
548
+ limit = trades.getLimit(symbol, limit)
549
+ return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
550
+
551
+ async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
552
+ """
553
+
554
+ https://api-docs.pro.apex.exchange/#private-websocket
555
+
556
+ watch all open positions
557
+ :param str[] [symbols]: list of unified market symbols
558
+ :param int [since]: the earliest time in ms to fetch positions for
559
+ :param int [limit]: the maximum number of positions to retrieve
560
+ :param dict params: extra parameters specific to the exchange API endpoint
561
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
562
+ """
563
+ await self.load_markets()
564
+ messageHash = ''
565
+ if not self.is_empty(symbols):
566
+ symbols = self.market_symbols(symbols)
567
+ messageHash = '::' + ','.join(symbols)
568
+ timeStamp = str(self.milliseconds())
569
+ url = self.urls['api']['ws']['private'] + '&timestamp=' + timeStamp
570
+ messageHash = 'positions' + messageHash
571
+ client = self.client(url)
572
+ await self.authenticate(url)
573
+ self.set_positions_cache(client, symbols)
574
+ cache = self.positions
575
+ if cache is None:
576
+ snapshot = await client.future('fetchPositionsSnapshot')
577
+ return self.filter_by_symbols_since_limit(snapshot, symbols, since, limit, True)
578
+ topics = ['positions']
579
+ newPositions = await self.watch_topics(url, [messageHash], topics, params)
580
+ if self.newUpdates:
581
+ return newPositions
582
+ return self.filter_by_symbols_since_limit(cache, symbols, since, limit, True)
583
+
584
+ async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
585
+ """
586
+ watches information on multiple orders made by the user
587
+
588
+ https://api-docs.pro.apex.exchange/#private-websocket
589
+
590
+ :param str symbol: unified market symbol of the market orders were made in
591
+ :param int [since]: the earliest time in ms to fetch orders for
592
+ :param int [limit]: the maximum number of order structures to retrieve
593
+ :param dict [params]: extra parameters specific to the exchange API endpoint
594
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
595
+ """
596
+ await self.load_markets()
597
+ messageHash = 'orders'
598
+ if symbol is not None:
599
+ symbol = self.symbol(symbol)
600
+ messageHash += ':' + symbol
601
+ timeStamp = str(self.milliseconds())
602
+ url = self.urls['api']['ws']['private'] + '&timestamp=' + timeStamp
603
+ await self.authenticate(url)
604
+ topics = ['orders']
605
+ orders = await self.watch_topics(url, [messageHash], topics, params)
606
+ if self.newUpdates:
607
+ limit = orders.getLimit(symbol, limit)
608
+ return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
609
+
610
+ def handle_my_trades(self, client: Client, lists):
611
+ # [
612
+ # {
613
+ # "symbol":"ETH-USDT",
614
+ # "side":"BUY",
615
+ # "orderId":"2048046080",
616
+ # "fee":"0.625000",
617
+ # "liquidity":"TAKER",
618
+ # "accountId":"1024000",
619
+ # "createdAt":1652185521361,
620
+ # "isOpen":true,
621
+ # "size":"0.500",
622
+ # "price":"2500.0",
623
+ # "quoteAmount":"1250.0000",
624
+ # "id":"2048000182272",
625
+ # "updatedAt":1652185678345
626
+ # }
627
+ # ]
628
+ if self.myTrades is None:
629
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
630
+ self.myTrades = ArrayCacheBySymbolById(limit)
631
+ trades = self.myTrades
632
+ symbols: dict = {}
633
+ for i in range(0, len(lists)):
634
+ rawTrade = lists[i]
635
+ parsed = None
636
+ parsed = self.parse_ws_trade(rawTrade)
637
+ symbol = parsed['symbol']
638
+ symbols[symbol] = True
639
+ trades.append(parsed)
640
+ keys = list(symbols.keys())
641
+ for i in range(0, len(keys)):
642
+ currentMessageHash = 'myTrades:' + keys[i]
643
+ client.resolve(trades, currentMessageHash)
644
+ # non-symbol specific
645
+ messageHash = 'myTrades'
646
+ client.resolve(trades, messageHash)
647
+
648
+ def handle_order(self, client: Client, lists):
649
+ # [
650
+ # {
651
+ # "symbol":"ETH-USDT",
652
+ # "cumSuccessFillFee":"0.625000",
653
+ # "trailingPercent":"0",
654
+ # "type":"LIMIT",
655
+ # "unfillableAt":1654779600000,
656
+ # "isDeleverage":false,
657
+ # "createdAt":1652185521339,
658
+ # "price":"2500.0",
659
+ # "cumSuccessFillValue":"0",
660
+ # "id":"2048046080",
661
+ # "cancelReason":"",
662
+ # "timeInForce":1,
663
+ # "updatedAt":1652185521392,
664
+ # "limitFee":"0.625000",
665
+ # "side":"BUY",
666
+ # "clientOrderId":"522843990",
667
+ # "triggerPrice":"",
668
+ # "expiresAt":1654779600000,
669
+ # "cumSuccessFillSize":"0",
670
+ # "accountId":"1024000",
671
+ # "size":"0.500",
672
+ # "reduceOnly":false,
673
+ # "isLiquidate":false,
674
+ # "remainingSize":"0.000",
675
+ # "status":"PENDING"
676
+ # }
677
+ # ]
678
+ if self.orders is None:
679
+ limit = self.safe_integer(self.options, 'ordersLimit', 1000)
680
+ self.orders = ArrayCacheBySymbolById(limit)
681
+ orders = self.orders
682
+ symbols: dict = {}
683
+ for i in range(0, len(lists)):
684
+ parsed = None
685
+ parsed = self.parse_order(lists[i])
686
+ symbol = parsed['symbol']
687
+ symbols[symbol] = True
688
+ orders.append(parsed)
689
+ symbolsArray = list(symbols.keys())
690
+ for i in range(0, len(symbolsArray)):
691
+ currentMessageHash = 'orders:' + symbolsArray[i]
692
+ client.resolve(orders, currentMessageHash)
693
+ messageHash = 'orders'
694
+ client.resolve(orders, messageHash)
695
+
696
+ def set_positions_cache(self, client: Client, symbols: Strings = None):
697
+ if self.positions is not None:
698
+ return
699
+ messageHash = 'fetchPositionsSnapshot'
700
+ if not (messageHash in client.futures):
701
+ client.future(messageHash)
702
+ self.spawn(self.load_positions_snapshot, client, messageHash)
703
+
704
+ async def load_positions_snapshot(self, client, messageHash):
705
+ # one ws channel gives positions for all types, for snapshot must load all positions
706
+ fetchFunctions = [
707
+ self.fetch_positions(None),
708
+ ]
709
+ promises = await asyncio.gather(*fetchFunctions)
710
+ self.positions = ArrayCacheBySymbolBySide()
711
+ cache = self.positions
712
+ for i in range(0, len(promises)):
713
+ positions = promises[i]
714
+ for ii in range(0, len(positions)):
715
+ position = positions[ii]
716
+ cache.append(position)
717
+ # don't remove the future from the .futures cache
718
+ future = client.futures[messageHash]
719
+ future.resolve(cache)
720
+ client.resolve(cache, 'positions')
721
+
722
+ def handle_positions(self, client, lists):
723
+ #
724
+ # [
725
+ # {
726
+ # "symbol":"ETH-USDT",
727
+ # "exitPrice":"0",
728
+ # "side":"LONG",
729
+ # "maxSize":"2820.000",
730
+ # "sumOpen":"1.820",
731
+ # "sumClose":"0.000",
732
+ # "netFunding":"0.000000",
733
+ # "entryPrice":"2500.000000000000000000",
734
+ # "accountId":"1024000",
735
+ # "createdAt":1652179377769,
736
+ # "size":"1.820",
737
+ # "realizedPnl":"0",
738
+ # "closedAt":1652185521392,
739
+ # "updatedAt":1652185521392
740
+ # }
741
+ # ]
742
+ #
743
+ # each account is connected to a different endpoint
744
+ # and has exactly one subscriptionhash which is the account type
745
+ if self.positions is None:
746
+ self.positions = ArrayCacheBySymbolBySide()
747
+ cache = self.positions
748
+ newPositions = []
749
+ for i in range(0, len(lists)):
750
+ rawPosition = lists[i]
751
+ position = self.parse_position(rawPosition)
752
+ side = self.safe_string(position, 'side')
753
+ # hacky solution to handle closing positions
754
+ # without crashing, we should handle self properly later
755
+ newPositions.append(position)
756
+ if side is None or side == '':
757
+ # closing update, adding both sides to "reset" both sides
758
+ # since we don't know which side is being closed
759
+ position['side'] = 'long'
760
+ cache.append(position)
761
+ position['side'] = 'short'
762
+ cache.append(position)
763
+ position['side'] = None
764
+ else:
765
+ # regular update
766
+ cache.append(position)
767
+ messageHashes = self.find_message_hashes(client, 'positions::')
768
+ for i in range(0, len(messageHashes)):
769
+ messageHash = messageHashes[i]
770
+ parts = messageHash.split('::')
771
+ symbolsString = parts[1]
772
+ symbols = symbolsString.split(',')
773
+ positions = self.filter_by_array(newPositions, 'symbol', symbols, False)
774
+ if not self.is_empty(positions):
775
+ client.resolve(positions, messageHash)
776
+ client.resolve(newPositions, 'positions')
777
+
778
+ async def authenticate(self, url, params={}):
779
+ self.check_required_credentials()
780
+ timestamp = str(self.milliseconds())
781
+ request_path = '/ws/accounts'
782
+ http_method = 'GET'
783
+ messageString = (timestamp + http_method + request_path)
784
+ signature = self.hmac(self.encode(messageString), self.encode(self.string_to_base64(self.secret)), hashlib.sha256, 'base64')
785
+ messageHash = 'authenticated'
786
+ client = self.client(url)
787
+ future = client.future(messageHash)
788
+ authenticated = self.safe_value(client.subscriptions, messageHash)
789
+ if authenticated is None:
790
+ # auth sign
791
+ request = {
792
+ 'type': 'login',
793
+ 'topics': ['ws_zk_accounts_v3'],
794
+ 'httpMethod': http_method,
795
+ 'requestPath': request_path,
796
+ 'apiKey': self.apiKey,
797
+ 'passphrase': self.password,
798
+ 'timestamp': timestamp,
799
+ 'signature': signature,
800
+ }
801
+ message = {
802
+ 'op': 'login',
803
+ 'args': [json.dumps(request)],
804
+ }
805
+ self.watch(url, messageHash, message, messageHash)
806
+ return await future
807
+
808
+ def handle_error_message(self, client: Client, message) -> Bool:
809
+ #
810
+ # {
811
+ # "success": False,
812
+ # "ret_msg": "error:invalid op",
813
+ # "conn_id": "5e079fdd-9c7f-404d-9dbf-969d650838b5",
814
+ # "request": {op: '', args: null}
815
+ # }
816
+ #
817
+ # auth error
818
+ #
819
+ # {
820
+ # "success": False,
821
+ # "ret_msg": "error:USVC1111",
822
+ # "conn_id": "e73770fb-a0dc-45bd-8028-140e20958090",
823
+ # "request": {
824
+ # "op": "auth",
825
+ # "args": [
826
+ # "9rFT6uR4uz9Imkw4Wx",
827
+ # "1653405853543",
828
+ # "542e71bd85597b4db0290f0ce2d13ed1fd4bb5df3188716c1e9cc69a879f7889"
829
+ # ]
830
+ # }
831
+ #
832
+ # {code: '-10009', desc: "Invalid period!"}
833
+ #
834
+ # {
835
+ # "reqId":"1",
836
+ # "retCode":170131,
837
+ # "retMsg":"Insufficient balance.",
838
+ # "op":"order.create",
839
+ # "data":{
840
+ #
841
+ # },
842
+ # "header":{
843
+ # "X-Bapi-Limit":"20",
844
+ # "X-Bapi-Limit-Status":"19",
845
+ # "X-Bapi-Limit-Reset-Timestamp":"1714236608944",
846
+ # "Traceid":"3d7168a137bf32a947b7e5e6a575ac7f",
847
+ # "Timenow":"1714236608946"
848
+ # },
849
+ # "connId":"cojifin88smerbj9t560-406"
850
+ # }
851
+ #
852
+ code = self.safe_string_n(message, ['code', 'ret_code', 'retCode'])
853
+ try:
854
+ if code is not None and code != '0':
855
+ feedback = self.id + ' ' + self.json(message)
856
+ self.throw_exactly_matched_exception(self.exceptions['exact'], code, feedback)
857
+ msg = self.safe_string_2(message, 'retMsg', 'ret_msg')
858
+ self.throw_broadly_matched_exception(self.exceptions['broad'], msg, feedback)
859
+ raise ExchangeError(feedback)
860
+ success = self.safe_value(message, 'success')
861
+ if success is not None and not success:
862
+ ret_msg = self.safe_string(message, 'ret_msg')
863
+ request = self.safe_value(message, 'request', {})
864
+ op = self.safe_string(request, 'op')
865
+ if op == 'auth':
866
+ raise AuthenticationError('Authentication failed: ' + ret_msg)
867
+ else:
868
+ raise ExchangeError(self.id + ' ' + ret_msg)
869
+ return False
870
+ except Exception as error:
871
+ if isinstance(error, AuthenticationError):
872
+ messageHash = 'authenticated'
873
+ client.reject(error, messageHash)
874
+ if messageHash in client.subscriptions:
875
+ del client.subscriptions[messageHash]
876
+ else:
877
+ messageHash = self.safe_string(message, 'reqId')
878
+ client.reject(error, messageHash)
879
+ return True
880
+
881
+ def handle_message(self, client: Client, message):
882
+ if self.handle_error_message(client, message):
883
+ return
884
+ topic = self.safe_string_2(message, 'topic', 'op', '')
885
+ methods: dict = {
886
+ 'ws_zk_accounts_v3': self.handle_account,
887
+ 'orderBook': self.handle_order_book,
888
+ 'depth': self.handle_order_book,
889
+ 'candle': self.handle_ohlcv,
890
+ 'kline': self.handle_ohlcv,
891
+ 'ticker': self.handle_ticker,
892
+ 'instrumentInfo': self.handle_ticker,
893
+ 'trade': self.handle_trades,
894
+ 'recentlyTrade': self.handle_trades,
895
+ 'pong': self.handle_pong,
896
+ 'auth': self.handle_authenticate,
897
+ }
898
+ exacMethod = self.safe_value(methods, topic)
899
+ if exacMethod is not None:
900
+ exacMethod(client, message)
901
+ return
902
+ keys = list(methods.keys())
903
+ for i in range(0, len(keys)):
904
+ key = keys[i]
905
+ if topic.find(keys[i]) >= 0:
906
+ method = methods[key]
907
+ method(client, message)
908
+ return
909
+ # unified auth acknowledgement
910
+ type = self.safe_string(message, 'type')
911
+ if type == 'AUTH_RESP':
912
+ self.handle_authenticate(client, message)
913
+
914
+ def ping(self, client: Client):
915
+ timeStamp = str(self.milliseconds())
916
+ return {
917
+ 'args': [timeStamp],
918
+ 'op': 'ping',
919
+ }
920
+
921
+ def handle_pong(self, client: Client, message):
922
+ #
923
+ # {
924
+ # "success": True,
925
+ # "ret_msg": "pong",
926
+ # "conn_id": "db3158a0-8960-44b9-a9de-ac350ee13158",
927
+ # "request": {op: "ping", args: null}
928
+ # }
929
+ #
930
+ # {pong: 1653296711335}
931
+ #
932
+ client.lastPong = self.safe_integer(message, 'pong')
933
+ return message
934
+
935
+ def handle_account(self, client: Client, message):
936
+ contents = self.safe_dict(message, 'contents', {})
937
+ fills = self.safe_list(contents, 'fills', [])
938
+ if fills is not None:
939
+ self.handle_my_trades(client, fills)
940
+ positions = self.safe_list(contents, 'positions', [])
941
+ if positions is not None:
942
+ self.handle_positions(client, positions)
943
+ orders = self.safe_list(contents, 'orders', [])
944
+ if orders is not None:
945
+ self.handle_order(client, orders)
946
+
947
+ def handle_authenticate(self, client: Client, message):
948
+ #
949
+ # {
950
+ # "success": True,
951
+ # "ret_msg": '',
952
+ # "op": "auth",
953
+ # "conn_id": "ce3dpomvha7dha97tvp0-2xh"
954
+ # }
955
+ #
956
+ success = self.safe_value(message, 'success')
957
+ code = self.safe_integer(message, 'retCode')
958
+ messageHash = 'authenticated'
959
+ if success or code == 0:
960
+ future = self.safe_value(client.futures, messageHash)
961
+ future.resolve(True)
962
+ else:
963
+ error = AuthenticationError(self.id + ' ' + self.json(message))
964
+ client.reject(error, messageHash)
965
+ if messageHash in client.subscriptions:
966
+ del client.subscriptions[messageHash]
967
+ return message
968
+
969
+ def handle_subscription_status(self, client: Client, message):
970
+ #
971
+ # {
972
+ # "topic": "kline",
973
+ # "event": "sub",
974
+ # "params": {
975
+ # "symbol": "LTCUSDT",
976
+ # "binary": "false",
977
+ # "klineType": "1m",
978
+ # "symbolName": "LTCUSDT"
979
+ # },
980
+ # "code": "0",
981
+ # "msg": "Success"
982
+ # }
983
+ #
984
+ return message