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/currencycom.py DELETED
@@ -1,1950 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
- # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
-
6
- from ccxt.base.exchange import Exchange
7
- from ccxt.abstract.currencycom import ImplicitAPI
8
- import hashlib
9
- from ccxt.base.types import Account, Balances, Currencies, Currency, Int, Leverage, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction
10
- from typing import List
11
- from ccxt.base.errors import ExchangeError
12
- from ccxt.base.errors import AuthenticationError
13
- from ccxt.base.errors import ArgumentsRequired
14
- from ccxt.base.errors import BadRequest
15
- from ccxt.base.errors import BadSymbol
16
- from ccxt.base.errors import InsufficientFunds
17
- from ccxt.base.errors import InvalidOrder
18
- from ccxt.base.errors import OrderNotFound
19
- from ccxt.base.errors import NotSupported
20
- from ccxt.base.errors import DDoSProtection
21
- from ccxt.base.errors import ExchangeNotAvailable
22
- from ccxt.base.errors import InvalidNonce
23
- from ccxt.base.decimal_to_precision import TICK_SIZE
24
- from ccxt.base.precise import Precise
25
-
26
-
27
- class currencycom(Exchange, ImplicitAPI):
28
-
29
- def describe(self):
30
- return self.deep_extend(super(currencycom, self).describe(), {
31
- 'id': 'currencycom',
32
- 'name': 'Currency.com',
33
- 'countries': ['BY'], # Belarus
34
- 'rateLimit': 100,
35
- 'certified': False,
36
- 'pro': True,
37
- 'version': 'v2',
38
- # new metainfo interface
39
- 'has': {
40
- 'CORS': None,
41
- 'spot': True,
42
- 'margin': True,
43
- 'swap': True,
44
- 'future': False,
45
- 'option': False,
46
- 'addMargin': None,
47
- 'cancelAllOrders': None,
48
- 'cancelOrder': True,
49
- 'cancelOrders': None,
50
- 'createDepositAddress': None,
51
- 'createLimitOrder': True,
52
- 'createMarketOrder': True,
53
- 'createOrder': True,
54
- 'createStopLimitOrder': True,
55
- 'createStopMarketOrder': True,
56
- 'createStopOrder': True,
57
- 'editOrder': 'emulated',
58
- 'fetchAccounts': True,
59
- 'fetchBalance': True,
60
- 'fetchBidsAsks': None,
61
- 'fetchBorrowRateHistory': None,
62
- 'fetchCanceledOrders': None,
63
- 'fetchClosedOrder': None,
64
- 'fetchClosedOrders': None,
65
- 'fetchCrossBorrowRate': False,
66
- 'fetchCrossBorrowRates': False,
67
- 'fetchCurrencies': True,
68
- 'fetchDeposit': None,
69
- 'fetchDepositAddress': True,
70
- 'fetchDepositAddresses': False,
71
- 'fetchDepositAddressesByNetwork': False,
72
- 'fetchDeposits': True,
73
- 'fetchDepositsWithdrawals': True,
74
- 'fetchFundingHistory': False,
75
- 'fetchFundingRate': False,
76
- 'fetchFundingRateHistory': False,
77
- 'fetchFundingRates': False,
78
- 'fetchIndexOHLCV': False,
79
- 'fetchIsolatedBorrowRate': False,
80
- 'fetchIsolatedBorrowRates': False,
81
- 'fetchL2OrderBook': True,
82
- 'fetchLedger': True,
83
- 'fetchLedgerEntry': False,
84
- 'fetchLeverage': True,
85
- 'fetchLeverageTiers': False,
86
- 'fetchMarginMode': False,
87
- 'fetchMarkets': True,
88
- 'fetchMarkOHLCV': False,
89
- 'fetchMyTrades': True,
90
- 'fetchOHLCV': True,
91
- 'fetchOpenOrder': None,
92
- 'fetchOpenOrders': True,
93
- 'fetchOrder': True,
94
- 'fetchOrderBook': True,
95
- 'fetchOrderBooks': None,
96
- 'fetchOrders': None,
97
- 'fetchOrderTrades': None,
98
- 'fetchPosition': None,
99
- 'fetchPositionMode': False,
100
- 'fetchPositions': True,
101
- 'fetchPositionsRisk': None,
102
- 'fetchPremiumIndexOHLCV': False,
103
- 'fetchTicker': True,
104
- 'fetchTickers': True,
105
- 'fetchTime': True,
106
- 'fetchTrades': True,
107
- 'fetchTradingFee': False,
108
- 'fetchTradingFees': True,
109
- 'fetchTradingLimits': None,
110
- 'fetchTransactionFee': None,
111
- 'fetchTransactionFees': None,
112
- 'fetchTransactions': 'emulated',
113
- 'fetchTransfers': None,
114
- 'fetchWithdrawal': None,
115
- 'fetchWithdrawals': True,
116
- 'reduceMargin': None,
117
- 'sandbox': True,
118
- 'setLeverage': None,
119
- 'setMarginMode': None,
120
- 'setPositionMode': None,
121
- 'signIn': None,
122
- 'transfer': None,
123
- 'withdraw': None,
124
- },
125
- 'timeframes': {
126
- '1m': '1m',
127
- '5m': '5m',
128
- '10m': '10m',
129
- '15m': '15m',
130
- '30m': '30m',
131
- '1h': '1h',
132
- '4h': '4h',
133
- '1d': '1d',
134
- '1w': '1w',
135
- },
136
- 'hostname': 'backend.currency.com',
137
- 'urls': {
138
- 'logo': 'https://user-images.githubusercontent.com/1294454/83718672-36745c00-a63e-11ea-81a9-677b1f789a4d.jpg',
139
- 'api': {
140
- 'public': 'https://api-adapter.{hostname}/api',
141
- 'private': 'https://api-adapter.{hostname}/api',
142
- 'marketcap': 'https://marketcap.{hostname}/api',
143
- },
144
- 'test': {
145
- 'public': 'https://demo-api-adapter.{hostname}/api',
146
- 'private': 'https://demo-api-adapter.{hostname}/api',
147
- },
148
- 'www': 'https://www.currency.com',
149
- 'referral': 'https://currency.com/trading/signup?c=362jaimv&pid=referral',
150
- 'doc': [
151
- 'https://currency.com/api',
152
- ],
153
- 'fees': 'https://currency.com/fees-charges',
154
- },
155
- # rate-limits are described at: https://currency.com/api-get-started
156
- 'api': {
157
- 'public': {
158
- 'get': {
159
- 'v1/time': 1,
160
- 'v1/exchangeInfo': 1,
161
- 'v1/depth': 1,
162
- 'v1/aggTrades': 1,
163
- 'v1/klines': 1,
164
- 'v1/ticker/24hr': 1,
165
- 'v2/time': 1,
166
- 'v2/exchangeInfo': 1,
167
- 'v2/depth': 1,
168
- 'v2/aggTrades': 1,
169
- 'v2/klines': 1,
170
- 'v2/ticker/24hr': 1,
171
- },
172
- },
173
- 'marketcap': {
174
- 'get': {
175
- 'v1/assets': 1,
176
- 'v1/candles': 1,
177
- 'v1/orderbook': 1,
178
- 'v1/summary': 1,
179
- 'v1/ticker': 1,
180
- 'v1/token/assets': 1,
181
- 'v1/token/orderbook': 1,
182
- 'v1/token/summary': 1,
183
- 'v1/token/ticker': 1,
184
- 'v1/token/trades': 1,
185
- 'v1/token_crypto/OHLC': 1,
186
- 'v1/token_crypto/assets': 1,
187
- 'v1/token_crypto/orderbook': 1,
188
- 'v1/token_crypto/summary': 1,
189
- 'v1/token_crypto/ticker': 1,
190
- 'v1/token_crypto/trades': 1,
191
- 'v1/trades': 1,
192
- },
193
- },
194
- 'private': {
195
- 'get': {
196
- 'v1/account': 1,
197
- 'v1/currencies': 1,
198
- 'v1/deposits': 1,
199
- 'v1/depositAddress': 1,
200
- 'v1/ledger': 1,
201
- 'v1/leverageSettings': 1,
202
- 'v1/myTrades': 1,
203
- 'v1/openOrders': 1,
204
- 'v1/tradingPositions': 1,
205
- 'v1/tradingPositionsHistory': 1,
206
- 'v1/transactions': 1,
207
- 'v1/withdrawals': 1,
208
- 'v2/account': 1,
209
- 'v2/currencies': 1,
210
- 'v2/deposits': 1,
211
- 'v2/depositAddress': 1,
212
- 'v2/ledger': 1,
213
- 'v2/leverageSettings': 1,
214
- 'v2/myTrades': 1,
215
- 'v2/openOrders': 1,
216
- 'v2/tradingPositions': 1,
217
- 'v2/tradingPositionsHistory': 1,
218
- 'v2/transactions': 1,
219
- 'v2/withdrawals': 1,
220
- 'v2/fetchOrder': 1,
221
- },
222
- 'post': {
223
- 'v1/order': 1,
224
- 'v1/updateTradingPosition': 1,
225
- 'v1/updateTradingOrder': 1,
226
- 'v1/closeTradingPosition': 1,
227
- 'v2/order': 1,
228
- 'v2/updateTradingPosition': 1,
229
- 'v2/updateTradingOrder': 1,
230
- 'v2/closeTradingPosition': 1,
231
- },
232
- 'delete': {
233
- 'v1/order': 1,
234
- 'v2/order': 1,
235
- },
236
- },
237
- },
238
- 'fees': {
239
- 'trading': {
240
- 'feeSide': 'get',
241
- 'tierBased': False,
242
- 'percentage': True,
243
- 'taker': self.parse_number('0.002'),
244
- 'maker': self.parse_number('0.002'),
245
- },
246
- },
247
- 'precisionMode': TICK_SIZE,
248
- # exchange-specific options
249
- 'options': {
250
- 'defaultTimeInForce': 'GTC', # 'GTC' = Good To Cancel(default), 'IOC' = Immediate Or Cancel, 'FOK' = Fill Or Kill
251
- 'warnOnFetchOpenOrdersWithoutSymbol': True,
252
- 'recvWindow': 5 * 1000, # 5 sec, default
253
- 'timeDifference': 0, # the difference between system clock and Binance clock
254
- 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
255
- 'parseOrderToPrecision': False, # force amounts and costs in parseOrder to precision
256
- 'newOrderRespType': {
257
- 'market': 'FULL', # 'ACK' for order id, 'RESULT' for full order or 'FULL' for order with fills
258
- 'limit': 'RESULT', # we change it from 'ACK' by default to 'RESULT'
259
- 'stop': 'RESULT',
260
- },
261
- 'leverage_markets_suffix': '_LEVERAGE',
262
- 'collateralCurrencies': ['USD', 'EUR', 'USDT'],
263
- },
264
- 'exceptions': {
265
- 'broad': {
266
- 'FIELD_VALIDATION_ERROR Cancel is available only for LIMIT order': InvalidOrder,
267
- 'API key does not exist': AuthenticationError,
268
- 'Order would trigger immediately.': InvalidOrder,
269
- 'Account has insufficient balance for requested action.': InsufficientFunds,
270
- 'Rest API trading is not enabled.': ExchangeNotAvailable,
271
- 'Combination of parameters invalid': BadRequest,
272
- 'Invalid limit price': BadRequest,
273
- 'Only leverage symbol allowed here:': BadSymbol, # when you fetchLeverage for non-leverage symbols, like 'BTC/USDT' instead of 'BTC/USDT_LEVERAGE': {"code":"-1128","msg":"Only leverage symbol allowed here: BTC/USDT"}
274
- 'market data service is not available': ExchangeNotAvailable, # {"code":"-1021","msg":"market data service is not available"}
275
- 'your time is ahead of server': InvalidNonce, # {"code":"-1021","msg":"your time is ahead of server"}
276
- 'Can not find account': BadRequest, # -1128
277
- 'You mentioned an invalid value for the price parameter': BadRequest, # -1030
278
- },
279
- 'exact': {
280
- '-1000': ExchangeNotAvailable, # {"code":-1000,"msg":"An unknown error occured while processing the request."}
281
- '-1013': InvalidOrder, # createOrder -> 'invalid quantity'/'invalid price'/MIN_NOTIONAL
282
- # '-1021': InvalidNonce, # {"code":"-1021","msg":"your time is ahead of server"} # see above in the broad section
283
- '-1022': AuthenticationError, # {"code":-1022,"msg":"Signature for self request is not valid."}
284
- '-1030': InvalidOrder, # {"code":"-1030","msg":"You mentioned an invalid value for the price parameter."}
285
- '-1100': InvalidOrder, # createOrder(symbol, 1, asdf) -> 'Illegal characters found in parameter 'price'
286
- '-1104': ExchangeError, # Not all sent parameters were read, read 8 parameters but was sent 9
287
- '-1025': AuthenticationError, # {"code":-1025,"msg":"Invalid API-key, IP, or permissions for action"}
288
- '-1128': BadRequest, # {"code":-1128,"msg":"Combination of optional parameters invalid."} | {"code":"-1128","msg":"Combination of parameters invalid"} | {"code":"-1128","msg":"Invalid limit price"} | {"code":"-1128","msg":"Can not find account: null"}
289
- '-2010': ExchangeError, # generic error code for createOrder -> 'Account has insufficient balance for requested action.', {"code":-2010,"msg":"Rest API trading is not enabled."}, etc...
290
- '-2011': OrderNotFound, # cancelOrder(1, 'BTC/USDT') -> 'UNKNOWN_ORDER'
291
- '-2013': OrderNotFound, # fetchOrder(1, 'BTC/USDT') -> 'Order does not exist'
292
- '-2014': AuthenticationError, # {"code":-2014, "msg": "API-key format invalid."}
293
- '-2015': AuthenticationError, # "Invalid API-key, IP, or permissions for action."
294
- },
295
- },
296
- 'commonCurrencies': {
297
- 'ACN': 'Accenture',
298
- 'AMC': 'AMC Entertainment Holdings',
299
- 'BNS': 'Bank of Nova Scotia',
300
- 'CAR': 'Avis Budget Group Inc',
301
- 'CLR': 'Continental Resources',
302
- 'EDU': 'New Oriental Education & Technology Group Inc',
303
- 'ETN': 'Eaton',
304
- 'FOX': 'Fox Corporation',
305
- 'GM': 'General Motors Co',
306
- 'IQ': 'iQIYI',
307
- 'OSK': 'Oshkosh',
308
- 'PLAY': "Dave & Buster's Entertainment",
309
- },
310
- })
311
-
312
- def nonce(self):
313
- return self.milliseconds() - self.options['timeDifference']
314
-
315
- def fetch_time(self, params={}):
316
- """
317
- fetches the current integer timestamp in milliseconds from the exchange server
318
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/timeUsingGET
319
- :param dict [params]: extra parameters specific to the exchange API endpoint
320
- :returns int: the current integer timestamp in milliseconds from the exchange server
321
- """
322
- response = self.publicGetV2Time(params)
323
- #
324
- # {
325
- # "serverTime": 1590998366609
326
- # }
327
- #
328
- return self.safe_integer(response, 'serverTime')
329
-
330
- def fetch_currencies(self, params={}) -> Currencies:
331
- """
332
- fetches all available currencies on an exchange
333
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getCurrenciesUsingGET
334
- :param dict [params]: extra parameters specific to the exchange API endpoint
335
- :returns dict: an associative dictionary of currencies
336
- """
337
- # requires authentication
338
- if not self.check_required_credentials(False):
339
- return None
340
- response = self.privateGetV2Currencies(params)
341
- #
342
- # [
343
- # {
344
- # "name": "Euro",
345
- # "displaySymbol": "EUR.cx",
346
- # "precision": "2",
347
- # "type": "FIAT",
348
- # "minWithdrawal": "90.0",
349
- # "maxWithdrawal": "1.0E+8",
350
- # "commissionMin": "0.02", # some instruments do not have self property
351
- # "commissionPercent": "1.5", # some instruments do not have self property
352
- # "minDeposit": "90.0",
353
- # },
354
- # {
355
- # "name": "Bitcoin",
356
- # "displaySymbol": "BTC",
357
- # "precision": "8",
358
- # "type": "CRYPTO", # only a few major currencies have self value, others like USDT have a value of "TOKEN"
359
- # "minWithdrawal": "0.00020",
360
- # "commissionFixed": "0.00010",
361
- # "minDeposit": "0.00010",
362
- # },
363
- # ]
364
- #
365
- result: dict = {}
366
- for i in range(0, len(response)):
367
- currency = response[i]
368
- id = self.safe_string(currency, 'displaySymbol')
369
- code = self.safe_currency_code(id)
370
- fee = self.safe_number(currency, 'commissionFixed')
371
- result[code] = {
372
- 'id': id,
373
- 'code': code,
374
- 'type': self.safe_string_lower(currency, 'type'),
375
- 'name': self.safe_string(currency, 'name'),
376
- 'active': None,
377
- 'deposit': None,
378
- 'withdraw': None,
379
- 'fee': fee,
380
- 'precision': self.parse_number(self.parse_precision(self.safe_string(currency, 'precision'))),
381
- 'limits': {
382
- 'amount': {
383
- 'min': None,
384
- 'max': None,
385
- },
386
- 'withdraw': {
387
- 'min': self.safe_number(currency, 'minWithdrawal'),
388
- 'max': self.safe_number(currency, 'maxWithdrawal'),
389
- },
390
- 'deposit': {
391
- 'min': self.safe_number(currency, 'minDeposit'),
392
- 'max': None,
393
- },
394
- },
395
- 'info': currency,
396
- }
397
- return result
398
-
399
- def fetch_markets(self, params={}) -> List[Market]:
400
- """
401
- retrieves data on all markets for currencycom
402
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/exchangeInfoUsingGET
403
- :param dict [params]: extra parameters specific to the exchange API endpoint
404
- :returns dict[]: an array of objects representing market data
405
- """
406
- response = self.publicGetV2ExchangeInfo(params)
407
- #
408
- # {
409
- # "timezone": "UTC",
410
- # "serverTime": "1645186287261",
411
- # "rateLimits": [
412
- # {rateLimitType: "REQUEST_WEIGHT", interval: "MINUTE", intervalNum: "1", limit: "1200"},
413
- # {rateLimitType: "ORDERS", interval: "SECOND", intervalNum: "1", limit: "10"},
414
- # {rateLimitType: "ORDERS", interval: "DAY", intervalNum: "1", limit: "864000"},
415
- # ],
416
- # "exchangeFilters": [],
417
- # "symbols": [
418
- # {
419
- # "symbol": "BTC/USDT", # BTC/USDT, BTC/USDT_LEVERAGE
420
- # "name": "Bitcoin / Tether",
421
- # "status": "TRADING", # TRADING, BREAK, HALT
422
- # "baseAsset": "BTC",
423
- # "baseAssetPrecision": "4",
424
- # "quoteAsset": "USDT",
425
- # "quoteAssetId": "USDT", # USDT, USDT_LEVERAGE
426
- # "quotePrecision": "4",
427
- # "orderTypes": ["LIMIT", "MARKET"], # LIMIT, MARKET, STOP
428
- # "filters": [
429
- # {filterType: "LOT_SIZE", minQty: "0.0001", maxQty: "100", stepSize: "0.0001",},
430
- # {filterType: "MIN_NOTIONAL", minNotional: "5",},
431
- # ],
432
- # "marketModes": ["REGULAR"], # CLOSE_ONLY, LONG_ONLY, REGULAR
433
- # "marketType": "SPOT", # SPOT, LEVERAGE
434
- # "longRate": -0.0684932, # LEVERAGE only
435
- # "shortRate": -0.0684932, # LEVERAGE only
436
- # "swapChargeInterval": 1440, # LEVERAGE only
437
- # "country": "",
438
- # "sector": "",
439
- # "industry": "",
440
- # "tradingHours": "UTC; Mon - 22:00, 22:05 -; Tue - 22:00, 22:05 -; Wed - 22:00, 22:05 -; Thu - 22:00, 22:05 -; Fri - 22:00, 23:01 -; Sat - 22:00, 22:05 -; Sun - 21:00, 22:05 -",
441
- # "tickSize": "0.01",
442
- # "tickValue": "403.4405", # not available in BTC/USDT_LEVERAGE, but available in BTC/USD_LEVERAGE
443
- # "exchangeFee": "0.2", # SPOT only
444
- # "tradingFee": 0.075, # LEVERAGE only
445
- # "makerFee": -0.025, # LEVERAGE only
446
- # "takerFee": 0.06, # LEVERAGE only
447
- # "maxSLGap": 50, # LEVERAGE only
448
- # "minSLGap": 1, # LEVERAGE only
449
- # "maxTPGap": 50, # LEVERAGE only
450
- # "minTPGap": 0.5, # LEVERAGE only
451
- # "assetType": "CRYPTOCURRENCY",
452
- # },
453
- # ]
454
- # }
455
- #
456
- if self.options['adjustForTimeDifference']:
457
- self.load_time_difference()
458
- markets = self.safe_value(response, 'symbols', [])
459
- result = []
460
- for i in range(0, len(markets)):
461
- market = markets[i]
462
- id = self.safe_string(market, 'symbol')
463
- baseId = self.safe_string(market, 'baseAsset')
464
- quoteId = self.safe_string(market, 'quoteAsset')
465
- base = self.safe_currency_code(baseId)
466
- quote = self.safe_currency_code(quoteId)
467
- symbol = base + '/' + quote
468
- typeRaw = self.safe_string(market, 'marketType')
469
- spot = (typeRaw == 'SPOT')
470
- futures = False
471
- swap = (typeRaw == 'LEVERAGE')
472
- type = 'swap' if swap else 'spot'
473
- margin = None
474
- if swap:
475
- symbol = symbol.replace(self.options['leverage_markets_suffix'], '')
476
- symbol += ':' + quote
477
- active = self.safe_string(market, 'status') == 'TRADING'
478
- # to set taker & maker fees, we use one from the below data - pairs either have 'exchangeFee' or 'tradingFee', if none of them(rare cases), then they should have 'takerFee & makerFee'
479
- exchangeFee = self.safe_string_2(market, 'exchangeFee', 'tradingFee')
480
- makerFee = self.safe_string(market, 'makerFee', exchangeFee)
481
- takerFee = self.safe_string(market, 'takerFee', exchangeFee)
482
- makerFee = Precise.string_div(makerFee, '100')
483
- takerFee = Precise.string_div(takerFee, '100')
484
- filters = self.safe_value(market, 'filters', [])
485
- filtersByType = self.index_by(filters, 'filterType')
486
- limitPriceMin = None
487
- limitPriceMax = None
488
- precisionPrice = self.safe_number(market, 'tickSize')
489
- if 'PRICE_FILTER' in filtersByType:
490
- filter = self.safe_value(filtersByType, 'PRICE_FILTER', {})
491
- precisionPrice = self.safe_number(filter, 'tickSize')
492
- # PRICE_FILTER reports zero values for maxPrice
493
- # since they updated filter types in November 2018
494
- # https://github.com/ccxt/ccxt/issues/4286
495
- # therefore limits['price']['max'] doesn't have any meaningful value except None
496
- limitPriceMin = self.safe_number(filter, 'minPrice')
497
- maxPrice = self.safe_string(filter, 'maxPrice')
498
- if (maxPrice is not None) and (Precise.string_gt(maxPrice, '0')):
499
- limitPriceMax = maxPrice
500
- precisionAmount = self.parse_number(self.parse_precision(self.safe_string(market, 'baseAssetPrecision')))
501
- limitAmount: dict = {
502
- 'min': None,
503
- 'max': None,
504
- }
505
- if 'LOT_SIZE' in filtersByType:
506
- filter = self.safe_value(filtersByType, 'LOT_SIZE', {})
507
- precisionAmount = self.safe_number(filter, 'stepSize')
508
- limitAmount = {
509
- 'min': self.safe_number(filter, 'minQty'),
510
- 'max': self.safe_number(filter, 'maxQty'),
511
- }
512
- limitMarket: dict = {
513
- 'min': None,
514
- 'max': None,
515
- }
516
- if 'MARKET_LOT_SIZE' in filtersByType:
517
- filter = self.safe_value(filtersByType, 'MARKET_LOT_SIZE', {})
518
- limitMarket = {
519
- 'min': self.safe_number(filter, 'minQty'),
520
- 'max': self.safe_number(filter, 'maxQty'),
521
- }
522
- costMin = None
523
- if 'MIN_NOTIONAL' in filtersByType:
524
- filter = self.safe_value(filtersByType, 'MIN_NOTIONAL', {})
525
- costMin = self.safe_number(filter, 'minNotional')
526
- isContract = swap or futures
527
- result.append({
528
- 'id': id,
529
- 'symbol': symbol,
530
- 'base': base,
531
- 'quote': quote,
532
- 'settle': None,
533
- 'baseId': baseId,
534
- 'quoteId': quoteId,
535
- 'settleId': None,
536
- 'type': type,
537
- 'spot': spot,
538
- 'margin': margin,
539
- 'swap': swap,
540
- 'future': futures,
541
- 'option': False,
542
- 'active': active,
543
- 'contract': isContract,
544
- 'linear': True if isContract else None,
545
- 'inverse': None,
546
- 'taker': self.parse_number(takerFee),
547
- 'maker': self.parse_number(makerFee),
548
- 'contractSize': None,
549
- 'expiry': None,
550
- 'expiryDatetime': None,
551
- 'strike': None,
552
- 'optionType': None,
553
- 'precision': {
554
- 'amount': precisionAmount,
555
- 'price': precisionPrice,
556
- },
557
- 'limits': {
558
- 'leverage': {
559
- 'min': None,
560
- 'max': None,
561
- },
562
- 'amount': limitAmount,
563
- 'market': limitMarket,
564
- 'price': {
565
- 'min': limitPriceMin,
566
- 'max': self.parse_number(limitPriceMax),
567
- },
568
- 'cost': {
569
- 'min': costMin,
570
- 'max': None,
571
- },
572
- },
573
- 'created': None,
574
- 'info': market,
575
- })
576
- return result
577
-
578
- def fetch_accounts(self, params={}) -> List[Account]:
579
- """
580
- fetch all the accounts associated with a profile
581
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/accountUsingGET
582
- :param dict [params]: extra parameters specific to the exchange API endpoint
583
- :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
584
- """
585
- response = self.privateGetV2Account(params)
586
- #
587
- # {
588
- # "makerCommission": "0.20",
589
- # "takerCommission": "0.20",
590
- # "buyerCommission": "0.20",
591
- # "sellerCommission": "0.20",
592
- # "canTrade": True,
593
- # "canWithdraw": True,
594
- # "canDeposit": True,
595
- # "updateTime": "1645266330",
596
- # "userId": "644722",
597
- # "balances": [
598
- # {
599
- # "accountId": "120702016179403605",
600
- # "collateralCurrency": False,
601
- # "asset": "CAKE",
602
- # "free": "3.1",
603
- # "locked": "0.0",
604
- # "default": False,
605
- # },
606
- # {
607
- # "accountId": "109698017713125316",
608
- # "collateralCurrency": True,
609
- # "asset": "USD",
610
- # "free": "17.58632",
611
- # "locked": "0.0",
612
- # "default": True,
613
- # }
614
- # ]
615
- # }
616
- #
617
- accounts = self.safe_value(response, 'balances', [])
618
- result = []
619
- for i in range(0, len(accounts)):
620
- account = accounts[i]
621
- accountId = self.safe_string(account, 'accountId') # must be string, because the numeric value is far too big for integer, and causes bugs
622
- currencyId = self.safe_string(account, 'asset')
623
- currencyCode = self.safe_currency_code(currencyId)
624
- result.append({
625
- 'id': accountId,
626
- 'type': None,
627
- 'currency': currencyCode,
628
- 'info': account,
629
- })
630
- return result
631
-
632
- def fetch_trading_fees(self, params={}) -> TradingFees:
633
- """
634
- fetch the trading fees for multiple markets
635
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/accountUsingGET
636
- :param dict [params]: extra parameters specific to the exchange API endpoint
637
- :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
638
- """
639
- self.load_markets()
640
- response = self.privateGetV2Account(params)
641
- #
642
- # {
643
- # "makerCommission": "0.20",
644
- # "takerCommission": "0.20",
645
- # "buyerCommission": "0.20",
646
- # "sellerCommission": "0.20",
647
- # "canTrade": True,
648
- # "canWithdraw": True,
649
- # "canDeposit": True,
650
- # "updateTime": "1645738976",
651
- # "userId": "-1924114235",
652
- # "balances": []
653
- # }
654
- #
655
- makerFee = self.safe_number(response, 'makerCommission')
656
- takerFee = self.safe_number(response, 'takerCommission')
657
- result: dict = {}
658
- for i in range(0, len(self.symbols)):
659
- symbol = self.symbols[i]
660
- result[symbol] = {
661
- 'info': response,
662
- 'symbol': symbol,
663
- 'maker': makerFee,
664
- 'taker': takerFee,
665
- 'percentage': True,
666
- 'tierBased': False,
667
- }
668
- return result
669
-
670
- def parse_balance(self, response, type=None):
671
- #
672
- # {
673
- # "makerCommission":0.20,
674
- # "takerCommission":0.20,
675
- # "buyerCommission":0.20,
676
- # "sellerCommission":0.20,
677
- # "canTrade":true,
678
- # "canWithdraw":true,
679
- # "canDeposit":true,
680
- # "updateTime":1591056268,
681
- # "balances":[
682
- # {
683
- # "accountId":5470306579272368,
684
- # "collateralCurrency":true,
685
- # "asset":"ETH",
686
- # "free":0.0,
687
- # "locked":0.0,
688
- # "default":false,
689
- # },
690
- # ]
691
- # }
692
- #
693
- result: dict = {'info': response}
694
- balances = self.safe_value(response, 'balances', [])
695
- for i in range(0, len(balances)):
696
- balance = balances[i]
697
- currencyId = self.safe_string(balance, 'asset')
698
- code = self.safe_currency_code(currencyId)
699
- account = self.account()
700
- account['free'] = self.safe_string(balance, 'free')
701
- account['used'] = self.safe_string(balance, 'locked')
702
- result[code] = account
703
- return self.safe_balance(result)
704
-
705
- def fetch_balance(self, params={}) -> Balances:
706
- """
707
- query for balance and get the amount of funds available for trading or funds locked in orders
708
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/accountUsingGET
709
- :param dict [params]: extra parameters specific to the exchange API endpoint
710
- :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
711
- """
712
- self.load_markets()
713
- response = self.privateGetV2Account(params)
714
- #
715
- # {
716
- # "makerCommission": "0.20",
717
- # "takerCommission": "0.20",
718
- # "buyerCommission": "0.20",
719
- # "sellerCommission": "0.20",
720
- # "canTrade": True,
721
- # "canWithdraw": True,
722
- # "canDeposit": True,
723
- # "updateTime": "1645266330",
724
- # "userId": "644722",
725
- # "balances": [
726
- # {
727
- # "accountId": "120702016179403605",
728
- # "collateralCurrency": False,
729
- # "asset": "CAKE",
730
- # "free": "1.784",
731
- # "locked": "0.0",
732
- # "default": False,
733
- # },
734
- # {
735
- # "accountId": "109698017413175316",
736
- # "collateralCurrency": True,
737
- # "asset": "USD",
738
- # "free": "7.58632",
739
- # "locked": "0.0",
740
- # "default": True,
741
- # }
742
- # ]
743
- # }
744
- #
745
- return self.parse_balance(response)
746
-
747
- def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
748
- """
749
- fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
750
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/depthUsingGET
751
- :param str symbol: unified symbol of the market to fetch the order book for
752
- :param int [limit]: the maximum amount of order book entries to return
753
- :param dict [params]: extra parameters specific to the exchange API endpoint
754
- :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
755
- """
756
- self.load_markets()
757
- market = self.market(symbol)
758
- request: dict = {
759
- 'symbol': market['id'],
760
- }
761
- if limit is not None:
762
- request['limit'] = limit # default 100, max 1000, valid limits 5, 10, 20, 50, 100, 500, 1000, 5000
763
- response = self.publicGetV2Depth(self.extend(request, params))
764
- #
765
- # {
766
- # "lastUpdateId":1590999849037,
767
- # "asks":[
768
- # [0.02495,60.0345],
769
- # [0.02496,34.1],
770
- # ...
771
- # ],
772
- # "bids":[
773
- # [0.02487,72.4144854],
774
- # [0.02486,24.043],
775
- # ...
776
- # ]
777
- # }
778
- #
779
- orderbook = self.parse_order_book(response, symbol)
780
- orderbook['nonce'] = self.safe_integer(response, 'lastUpdateId')
781
- return orderbook
782
-
783
- def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
784
- #
785
- # fetchTicker
786
- #
787
- # {
788
- # "symbol":"ETH/BTC",
789
- # "priceChange":"0.00030",
790
- # "priceChangePercent":"1.21",
791
- # "weightedAvgPrice":"0.02481",
792
- # "prevClosePrice":"0.02447",
793
- # "lastPrice":"0.02477",
794
- # "lastQty":"60.0",
795
- # "bidPrice":"0.02477",
796
- # "askPrice":"0.02484",
797
- # "openPrice":"0.02447",
798
- # "highPrice":"0.02524",
799
- # "lowPrice":"0.02438",
800
- # "volume":"11.97",
801
- # "quoteVolume":"0.298053",
802
- # "openTime":1590969600000,
803
- # "closeTime":1591000072693
804
- # }
805
- #
806
- # fetchTickers
807
- #
808
- # {
809
- # "symbol": "SHIB/USD_LEVERAGE",
810
- # "weightedAvgPrice": "0.000027595",
811
- # "lastPrice": "0.00002737",
812
- # "lastQty": "1.11111111E8",
813
- # "bidPrice": "0.00002737",
814
- # "askPrice": "0.00002782",
815
- # "highPrice": "0.00002896",
816
- # "lowPrice": "0.00002738",
817
- # "volume": "16472160000",
818
- # "quoteVolume": "454796.3376",
819
- # "openTime": "1645187472000",
820
- # "closeTime": "1645273872000",
821
- # }
822
- #
823
- # ws:marketData.subscribe
824
- #
825
- # {
826
- # "symbolName":"TXN",
827
- # "bid":139.85,
828
- # "bidQty":2500,
829
- # "ofr":139.92000000000002,
830
- # "ofrQty":2500,
831
- # "timestamp":1597850971558
832
- # }
833
- #
834
- timestamp = self.safe_integer_2(ticker, 'closeTime', 'timestamp')
835
- marketId = self.safe_string_2(ticker, 'symbol', 'symbolName')
836
- market = self.safe_market(marketId, market, '/')
837
- last = self.safe_string(ticker, 'lastPrice')
838
- return self.safe_ticker({
839
- 'symbol': market['symbol'],
840
- 'timestamp': timestamp,
841
- 'datetime': self.iso8601(timestamp),
842
- 'high': self.safe_string(ticker, 'highPrice'),
843
- 'low': self.safe_string(ticker, 'lowPrice'),
844
- 'bid': self.safe_string_2(ticker, 'bidPrice', 'bid'),
845
- 'bidVolume': self.safe_string(ticker, 'bidQty'),
846
- 'ask': self.safe_string_2(ticker, 'askPrice', 'ofr'),
847
- 'askVolume': self.safe_string(ticker, 'ofrQty'),
848
- 'vwap': self.safe_string(ticker, 'weightedAvgPrice'),
849
- 'open': self.safe_string(ticker, 'openPrice'),
850
- 'close': last,
851
- 'last': last,
852
- 'previousClose': self.safe_string(ticker, 'prevClosePrice'), # previous day close
853
- 'change': self.safe_string(ticker, 'priceChange'),
854
- 'percentage': self.safe_string(ticker, 'priceChangePercent'),
855
- 'average': None,
856
- 'baseVolume': self.safe_string(ticker, 'volume'),
857
- 'quoteVolume': self.safe_string(ticker, 'quoteVolume'),
858
- 'info': ticker,
859
- }, market)
860
-
861
- def fetch_ticker(self, symbol: str, params={}) -> Ticker:
862
- """
863
- fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
864
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/ticker_24hrUsingGET
865
- :param str symbol: unified symbol of the market to fetch the ticker for
866
- :param dict [params]: extra parameters specific to the exchange API endpoint
867
- :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
868
- """
869
- self.load_markets()
870
- market = self.market(symbol)
871
- request: dict = {
872
- 'symbol': market['id'],
873
- }
874
- response = self.publicGetV2Ticker24hr(self.extend(request, params))
875
- #
876
- # {
877
- # "symbol":"ETH/BTC",
878
- # "priceChange":"0.00030",
879
- # "priceChangePercent":"1.21",
880
- # "weightedAvgPrice":"0.02481",
881
- # "prevClosePrice":"0.02447",
882
- # "lastPrice":"0.02477",
883
- # "lastQty":"60.0",
884
- # "bidPrice":"0.02477",
885
- # "askPrice":"0.02484",
886
- # "openPrice":"0.02447",
887
- # "highPrice":"0.02524",
888
- # "lowPrice":"0.02438",
889
- # "volume":"11.97",
890
- # "quoteVolume":"0.298053",
891
- # "openTime":1590969600000,
892
- # "closeTime":1591000072693
893
- # }
894
- #
895
- return self.parse_ticker(response, market)
896
-
897
- def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
898
- """
899
- fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
900
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/ticker_24hrUsingGET
901
- :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
902
- :param dict [params]: extra parameters specific to the exchange API endpoint
903
- :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
904
- """
905
- self.load_markets()
906
- response = self.publicGetV2Ticker24hr(params)
907
- #
908
- # [
909
- # {
910
- # "symbol": "SHIB/USD_LEVERAGE",
911
- # "weightedAvgPrice": "0.000027595",
912
- # "lastPrice": "0.00002737",
913
- # "lastQty": "1.11111111E8",
914
- # "bidPrice": "0.00002737",
915
- # "askPrice": "0.00002782",
916
- # "highPrice": "0.00002896",
917
- # "lowPrice": "0.00002738",
918
- # "volume": "16472160000",
919
- # "quoteVolume": "454796.3376",
920
- # "openTime": "1645187472000",
921
- # "closeTime": "1645273872000",
922
- # }
923
- # ]
924
- #
925
- return self.parse_tickers(response, symbols)
926
-
927
- def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
928
- #
929
- # [
930
- # 1590971040000,
931
- # "0.02454",
932
- # "0.02456",
933
- # "0.02452",
934
- # "0.02456",
935
- # 249
936
- # ]
937
- #
938
- return [
939
- self.safe_integer(ohlcv, 0),
940
- self.safe_number(ohlcv, 1),
941
- self.safe_number(ohlcv, 2),
942
- self.safe_number(ohlcv, 3),
943
- self.safe_number(ohlcv, 4),
944
- self.safe_number(ohlcv, 5),
945
- ]
946
-
947
- def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
948
- """
949
- fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
950
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/klinesUsingGET
951
- :param str symbol: unified symbol of the market to fetch OHLCV data for
952
- :param str timeframe: the length of time each candle represents
953
- :param int [since]: timestamp in ms of the earliest candle to fetch
954
- :param int [limit]: the maximum amount of candles to fetch
955
- :param dict [params]: extra parameters specific to the exchange API endpoint
956
- :returns int[][]: A list of candles ordered, open, high, low, close, volume
957
- """
958
- self.load_markets()
959
- market = self.market(symbol)
960
- request: dict = {
961
- 'symbol': market['id'],
962
- 'interval': self.safe_string(self.timeframes, timeframe, timeframe),
963
- }
964
- if since is not None:
965
- request['startTime'] = since
966
- if limit is not None:
967
- request['limit'] = min(limit, 1000) # default 500, max 1000
968
- response = self.publicGetV2Klines(self.extend(request, params))
969
- #
970
- # [
971
- # [1590971040000,"0.02454","0.02456","0.02452","0.02456",249],
972
- # [1590971100000,"0.02455","0.02457","0.02452","0.02456",300],
973
- # [1590971160000,"0.02455","0.02456","0.02453","0.02454",286],
974
- # ]
975
- #
976
- return self.parse_ohlcvs(response, market, timeframe, since, limit)
977
-
978
- def parse_trade(self, trade: dict, market: Market = None) -> Trade:
979
- #
980
- # fetchTrades(public aggregate trades)
981
- #
982
- # {
983
- # "a":"1658318071", # Aggregate tradeId
984
- # "p":"0.02476", # Price
985
- # "q":"0.0", # Official doc says: "Quantity(should be ignored)"
986
- # "T":"1591001423382", # Epoch timestamp in MS
987
- # "m":false # Was the buyer the maker
988
- # }
989
- #
990
- # createOrder fills(private)
991
- #
992
- # {
993
- # "price": "9807.05",
994
- # "qty": "0.01",
995
- # "commission": "0",
996
- # "commissionAsset": "dUSD"
997
- # }
998
- #
999
- # fetchMyTrades
1000
- #
1001
- # {
1002
- # "symbol": "DOGE/USD",
1003
- # "id": "116046000",
1004
- # "orderId": "00000000-0000-0000-0000-000006dbb8ad",
1005
- # "price": "0.14094",
1006
- # "qty": "40.0",
1007
- # "commission": "0.01",
1008
- # "commissionAsset": "USD",
1009
- # "time": "1645283022351",
1010
- # "buyer": False,
1011
- # "maker": False,
1012
- # "isBuyer": False,
1013
- # "isMaker": False
1014
- # }
1015
- #
1016
- timestamp = self.safe_integer_2(trade, 'T', 'time')
1017
- priceString = self.safe_string_2(trade, 'p', 'price')
1018
- amountString = self.safe_string_2(trade, 'q', 'qty')
1019
- id = self.safe_string_2(trade, 'a', 'id')
1020
- side = None
1021
- orderId = self.safe_string(trade, 'orderId')
1022
- takerOrMaker = None
1023
- if 'm' in trade:
1024
- side = 'sell' if trade['m'] else 'buy' # self is reversed intentionally [TODO: needs reason to be mentioned]
1025
- takerOrMaker = 'taker' # in public trades, it's always taker
1026
- elif 'isBuyer' in trade:
1027
- side = 'buy' if (trade['isBuyer']) else 'sell' # self is a True side
1028
- takerOrMaker = 'maker' if trade['isMaker'] else 'taker'
1029
- fee = None
1030
- if 'commission' in trade:
1031
- fee = {
1032
- 'cost': self.safe_string(trade, 'commission'),
1033
- 'currency': self.safe_currency_code(self.safe_string(trade, 'commissionAsset')),
1034
- }
1035
- marketId = self.safe_string(trade, 'symbol')
1036
- symbol = self.safe_symbol(marketId, market)
1037
- return self.safe_trade({
1038
- 'id': id,
1039
- 'order': orderId,
1040
- 'timestamp': timestamp,
1041
- 'datetime': self.iso8601(timestamp),
1042
- 'symbol': symbol,
1043
- 'type': None,
1044
- 'takerOrMaker': takerOrMaker,
1045
- 'side': side,
1046
- 'price': priceString,
1047
- 'amount': amountString,
1048
- 'cost': None,
1049
- 'fee': fee,
1050
- 'info': trade,
1051
- }, market)
1052
-
1053
- def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
1054
- """
1055
- get the list of most recent trades for a particular symbol
1056
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/aggTradesUsingGET
1057
- :param str symbol: unified symbol of the market to fetch trades for
1058
- :param int [since]: timestamp in ms of the earliest trade to fetch
1059
- :param int [limit]: the maximum amount of trades to fetch
1060
- :param dict [params]: extra parameters specific to the exchange API endpoint
1061
- :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
1062
- """
1063
- self.load_markets()
1064
- market = self.market(symbol)
1065
- request: dict = {
1066
- 'symbol': market['id'],
1067
- # 'limit': 500, # default 500, max 1000
1068
- }
1069
- if limit is not None:
1070
- request['limit'] = min(limit, 1000) # default 500, max 1000
1071
- if since is not None:
1072
- request['startTime'] = since
1073
- response = self.publicGetV2AggTrades(self.extend(request, params))
1074
- #
1075
- # [
1076
- # {
1077
- # "a":"1658318071", # Aggregate tradeId
1078
- # "p":"0.02476", # Price
1079
- # "q":"0.0", # Official doc says: "Quantity(should be ignored)"
1080
- # "T":"1591001423382", # Epoch timestamp in MS
1081
- # "m":false # Was the buyer the maker
1082
- # },
1083
- # ]
1084
- #
1085
- return self.parse_trades(response, market, since, limit)
1086
-
1087
- def parse_order(self, order: dict, market: Market = None) -> Order:
1088
- #
1089
- # createOrder
1090
- #
1091
- # limit
1092
- #
1093
- # {
1094
- # "symbol": "BTC/USD",
1095
- # "orderId": "00000000-0000-0000-0000-000006eacaa0",
1096
- # "transactTime": "1645281669295",
1097
- # "price": "30000.00000000",
1098
- # "origQty": "0.0002", # might not be present for "market" order
1099
- # "executedQty": "0.0", # positive for BUY, negative for SELL. This property might not be present in Leverage markets
1100
- # "margin": 0.1, # present in leverage markets
1101
- # "status": "NEW", # NEW, FILLED, ...
1102
- # "timeInForce": "GTC",
1103
- # "type": "LIMIT", # LIMIT, MARKET
1104
- # "side": "BUY",
1105
- # "fills": [ # self field might not be present if there were no fills
1106
- # {
1107
- # "price": "0.14094",
1108
- # "qty": "40.0",
1109
- # "commission": "0",
1110
- # "commissionAsset": "dUSD",
1111
- # },
1112
- # ],
1113
- # }
1114
- #
1115
- # fetchOrder(fetchOpenOrders is an array same structure, with some extra fields)
1116
- #
1117
- # {
1118
- # "symbol": "BTC/USD_LEVERAGE",
1119
- # "accountId": "123456789012345678",
1120
- # "orderId": "00a01234-0123-54c4-0000-123451234567",
1121
- # "price": "25779.35",
1122
- # "status": "MODIFIED",
1123
- # "type": "LIMIT",
1124
- # "timeInForceType": "GTC",
1125
- # "side": "BUY",
1126
- # "guaranteedStopLoss": False,
1127
- # "trailingStopLoss": False,
1128
- # "margin": "0.05",
1129
- # "takeProfit": "27020.00",
1130
- # "stopLoss": "24500.35",
1131
- # "fills": [], # might not be present
1132
- # "timestamp": "1685958369623", # "time" in "fetchOpenOrders"
1133
- # "expireTime": "1686167960000", # "expireTimestamp" in "fetchOpenOrders"
1134
- # "quantity": "0.00040", # "origQty" in "fetchOpenOrders"
1135
- # "executedQty": "0.0", # present in "fetchOpenOrders"
1136
- # "updateTime": "1685958369542", # present in "fetchOpenOrders"
1137
- # "leverage": True, # present in "fetchOpenOrders"
1138
- # "working": True # present in "fetchOpenOrders"
1139
- # }
1140
- #
1141
- # cancelOrder
1142
- #
1143
- # {
1144
- # "symbol": "DOGE/USD",
1145
- # "orderId": "00000000-0000-0003-0000-000006db714c",
1146
- # "price": "0.13",
1147
- # "origQty": "30.0",
1148
- # "executedQty": "0.0",
1149
- # "status": "CANCELED",
1150
- # "timeInForce": "GTC",
1151
- # "type": "LIMIT",
1152
- # "side": "BUY",
1153
- # }
1154
- #
1155
- marketId = self.safe_string(order, 'symbol')
1156
- symbol = self.safe_symbol(marketId, market, '/')
1157
- id = self.safe_string(order, 'orderId')
1158
- price = self.safe_string(order, 'price')
1159
- amount = self.safe_string_2(order, 'origQty', 'quantity')
1160
- filledRaw = self.safe_string(order, 'executedQty')
1161
- filled = Precise.string_abs(filledRaw)
1162
- status = self.parse_order_status(self.safe_string(order, 'status'))
1163
- timeInForce = self.parse_order_time_in_force(self.safe_string_2(order, 'timeInForce', 'timeInForceType'))
1164
- type = self.parse_order_type(self.safe_string(order, 'type'))
1165
- side = self.parse_order_side(self.safe_string(order, 'side'))
1166
- timestamp = self.safe_integer_n(order, ['time', 'transactTime', 'timestamp'])
1167
- fills = self.safe_value(order, 'fills')
1168
- return self.safe_order({
1169
- 'info': order,
1170
- 'id': id,
1171
- 'timestamp': timestamp,
1172
- 'datetime': self.iso8601(timestamp),
1173
- 'lastTradeTimestamp': None,
1174
- 'symbol': symbol,
1175
- 'type': type,
1176
- 'timeInForce': timeInForce,
1177
- 'side': side,
1178
- 'price': price,
1179
- 'stopPrice': None,
1180
- 'triggerPrice': None,
1181
- 'amount': amount,
1182
- 'cost': None,
1183
- 'average': None,
1184
- 'filled': filled,
1185
- 'remaining': None,
1186
- 'status': status,
1187
- 'fee': None,
1188
- 'trades': fills,
1189
- }, market)
1190
-
1191
- def parse_order_status(self, status: Str):
1192
- statuses: dict = {
1193
- 'NEW': 'open',
1194
- 'CREATED': 'open',
1195
- 'MODIFIED': 'open',
1196
- 'PARTIALLY_FILLED': 'open',
1197
- 'FILLED': 'closed',
1198
- 'CANCELED': 'canceled',
1199
- 'PENDING_CANCEL': 'canceling',
1200
- 'REJECTED': 'rejected',
1201
- 'EXPIRED': 'expired',
1202
- }
1203
- return self.safe_string(statuses, status, status)
1204
-
1205
- def parse_order_type(self, status):
1206
- statuses: dict = {
1207
- 'MARKET': 'market',
1208
- 'LIMIT': 'limit',
1209
- 'STOP': 'stop',
1210
- # temporarily we remove custom mappings
1211
- # 'LIMIT_MAKER': '',
1212
- # 'STOP_LOSS': 'stop-loss',
1213
- # 'STOP_LOSS_LIMIT': 'stop-limit',
1214
- # 'TAKE_PROFIT': 'take-profit',
1215
- # 'TAKE_PROFIT_LIMIT': 'take-profit',
1216
- }
1217
- return self.safe_string(statuses, status, status)
1218
-
1219
- def parse_order_time_in_force(self, status):
1220
- statuses: dict = {
1221
- 'GTC': 'GTC',
1222
- 'FOK': 'FOK',
1223
- 'IOC': 'IOC',
1224
- }
1225
- return self.safe_string(statuses, status, status)
1226
-
1227
- def parse_order_side(self, status):
1228
- statuses: dict = {
1229
- 'BUY': 'buy',
1230
- 'SELL': 'sell',
1231
- }
1232
- return self.safe_string(statuses, status, status)
1233
-
1234
- def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1235
- """
1236
- create a trade order
1237
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/orderUsingPOST
1238
- :param str symbol: unified symbol of the market to create an order in
1239
- :param str type: 'market' or 'limit'
1240
- :param str side: 'buy' or 'sell'
1241
- :param float amount: how much of currency you want to trade in units of base currency
1242
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1243
- :param dict [params]: extra parameters specific to the exchange API endpoint
1244
- :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1245
- """
1246
- self.load_markets()
1247
- market = self.market(symbol)
1248
- accountId = None
1249
- if market['margin']:
1250
- accountId = self.safe_string(self.options, 'accountId')
1251
- accountId = self.safe_string(params, 'accountId', accountId)
1252
- if accountId is None:
1253
- raise ArgumentsRequired(self.id + " createOrder() requires an accountId parameter or an exchange.options['accountId'] option for " + market['type'] + ' markets')
1254
- newOrderRespType = self.safe_value(self.options['newOrderRespType'], type, 'RESULT')
1255
- request: dict = {
1256
- 'symbol': market['id'],
1257
- 'quantity': self.amount_to_precision(symbol, amount),
1258
- 'type': type.upper(),
1259
- 'side': side.upper(),
1260
- 'newOrderRespType': newOrderRespType, # 'RESULT' for full order or 'FULL' for order with fills
1261
- # 'leverage': 1,
1262
- # 'accountId': 5470306579272968, # required for leverage markets
1263
- # 'takeProfit': '123.45',
1264
- # 'stopLoss': '54.321',
1265
- # 'guaranteedStopLoss': '54.321',
1266
- }
1267
- if type == 'limit':
1268
- request['price'] = self.price_to_precision(symbol, price)
1269
- request['timeInForce'] = self.options['defaultTimeInForce']
1270
- else:
1271
- if type == 'stop':
1272
- request['type'] = 'STOP'
1273
- request['price'] = self.price_to_precision(symbol, price)
1274
- elif type == 'market':
1275
- stopPrice = self.safe_value_2(params, 'triggerPrice', 'stopPrice')
1276
- params = self.omit(params, ['triggerPrice', 'stopPrice'])
1277
- if stopPrice is not None:
1278
- request['type'] = 'STOP'
1279
- request['price'] = self.price_to_precision(symbol, stopPrice)
1280
- response = self.privatePostV2Order(self.extend(request, params))
1281
- #
1282
- # limit
1283
- #
1284
- # {
1285
- # "symbol": "BTC/USD",
1286
- # "orderId": "00000000-0000-0000-0000-000006eaaaa0",
1287
- # "transactTime": "1645281669295",
1288
- # "price": "30000.00000000",
1289
- # "origQty": "0.0002",
1290
- # "executedQty": "0.0", # positive for BUY, negative for SELL
1291
- # "status": "NEW",
1292
- # "timeInForce": "GTC",
1293
- # "type": "LIMIT",
1294
- # "side": "BUY",
1295
- # }
1296
- #
1297
- # market
1298
- #
1299
- # {
1300
- # "symbol": "DOGE/USD",
1301
- # "orderId": "00000000-0000-0000-0000-000006eab8ad",
1302
- # "transactTime": "1645283022252",
1303
- # "price": "0.14066000",
1304
- # "origQty": "40",
1305
- # "executedQty": "40.0", # positive for BUY, negative for SELL
1306
- # "status": "FILLED",
1307
- # "timeInForce": "FOK",
1308
- # "type": "MARKET",
1309
- # "side": "BUY",
1310
- # "fills": [
1311
- # {
1312
- # "price": "0.14094",
1313
- # "qty": "40.0",
1314
- # "commission": "0",
1315
- # "commissionAsset": "dUSD"
1316
- # }
1317
- # ]
1318
- # }
1319
- #
1320
- return self.parse_order(response, market)
1321
-
1322
- def fetch_order(self, id: str, symbol: Str = None, params={}):
1323
- """
1324
- fetches information on an order made by the user
1325
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getOrderUsingGET
1326
- :param str symbol: unified symbol of the market the order was made in
1327
- :param dict [params]: extra parameters specific to the exchange API endpoint
1328
- :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1329
- """
1330
- if symbol is None:
1331
- raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
1332
- self.load_markets()
1333
- market = self.market(symbol)
1334
- request: dict = {
1335
- 'orderId': id,
1336
- 'symbol': market['id'],
1337
- }
1338
- response = self.privateGetV2FetchOrder(self.extend(request, params))
1339
- #
1340
- # {
1341
- # "accountId": "109698017413125316",
1342
- # "orderId": "2810f1c5-0079-54c4-0000-000080421601",
1343
- # "quantity": "20.0",
1344
- # "price": "0.06",
1345
- # "timestamp": "1661157503788",
1346
- # "status": "CREATED",
1347
- # "type": "LIMIT",
1348
- # "timeInForceType": "GTC",
1349
- # "side": "BUY",
1350
- # "margin": "0.1",
1351
- # "fills": [ # might not be present
1352
- # {
1353
- # "price": "0.14094",
1354
- # "qty": "40.0",
1355
- # "commission": "0",
1356
- # "commissionAsset": "dUSD"
1357
- # }
1358
- # ]
1359
- # }
1360
- #
1361
- return self.parse_order(response)
1362
-
1363
- def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1364
- """
1365
- fetch all unfilled currently open orders
1366
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/openOrdersUsingGET
1367
- :param str symbol: unified market symbol
1368
- :param int [since]: the earliest time in ms to fetch open orders for
1369
- :param int [limit]: the maximum number of open orders structures to retrieve
1370
- :param dict [params]: extra parameters specific to the exchange API endpoint
1371
- :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1372
- """
1373
- self.load_markets()
1374
- market = None
1375
- request: dict = {}
1376
- if symbol is not None:
1377
- market = self.market(symbol)
1378
- request['symbol'] = market['id']
1379
- elif self.options['warnOnFetchOpenOrdersWithoutSymbol']:
1380
- symbols = self.symbols
1381
- numSymbols = len(symbols)
1382
- fetchOpenOrdersRateLimit = self.parse_to_int(numSymbols / 2)
1383
- raise ExchangeError(self.id + ' fetchOpenOrders() WARNING: fetching open orders without specifying a symbol is rate-limited to one call per ' + str(fetchOpenOrdersRateLimit) + ' seconds. Do not call self method frequently to avoid ban. Set ' + self.id + '.options["warnOnFetchOpenOrdersWithoutSymbol"] = False to suppress self warning message.')
1384
- response = self.privateGetV2OpenOrders(self.extend(request, params))
1385
- #
1386
- # [
1387
- # {
1388
- # "symbol": "DOGE/USD",
1389
- # "orderId": "00000000-0000-0003-0000-000004bac57a",
1390
- # "price": "0.13",
1391
- # "origQty": "39.0",
1392
- # "executedQty": "0.0", # positive for BUY, negative for SELL
1393
- # "status": "NEW",
1394
- # "timeInForce": "GTC",
1395
- # "type": "LIMIT",
1396
- # "side": "BUY",
1397
- # "time": "1645284216240",
1398
- # "updateTime": "1645284216240",
1399
- # "leverage": False,
1400
- # "working": True
1401
- # },
1402
- # ]
1403
- #
1404
- return self.parse_orders(response, market, since, limit, params)
1405
-
1406
- def cancel_order(self, id: str, symbol: Str = None, params={}):
1407
- """
1408
- cancels an open order
1409
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/cancelOrderUsingDELETE
1410
- :param str id: order id
1411
- :param str symbol: unified symbol of the market the order was made in
1412
- :param dict [params]: extra parameters specific to the exchange API endpoint
1413
- :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1414
- """
1415
- if symbol is None:
1416
- raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
1417
- self.load_markets()
1418
- market = self.market(symbol)
1419
- origClientOrderId = self.safe_value(params, 'origClientOrderId')
1420
- request: dict = {
1421
- 'symbol': market['id'],
1422
- # 'orderId': int(id),
1423
- # 'origClientOrderId': id,
1424
- }
1425
- if origClientOrderId is None:
1426
- request['orderId'] = id
1427
- else:
1428
- request['origClientOrderId'] = origClientOrderId
1429
- response = self.privateDeleteV2Order(self.extend(request, params))
1430
- #
1431
- # {
1432
- # "symbol": "DOGE/USD",
1433
- # "orderId": "00000000-0000-0003-0000-000006db764c",
1434
- # "price": "0.13",
1435
- # "origQty": "30.0",
1436
- # "executedQty": "0.0", # positive for BUY, negative for SELL
1437
- # "status": "CANCELED",
1438
- # "timeInForce": "GTC",
1439
- # "type": "LIMIT",
1440
- # "side": "BUY",
1441
- # }
1442
- #
1443
- return self.parse_order(response, market)
1444
-
1445
- def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1446
- """
1447
- fetch all trades made by the user
1448
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/myTradesUsingGET
1449
- :param str symbol: unified market symbol
1450
- :param int [since]: the earliest time in ms to fetch trades for
1451
- :param int [limit]: the maximum number of trades structures to retrieve
1452
- :param dict [params]: extra parameters specific to the exchange API endpoint
1453
- :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1454
- """
1455
- if symbol is None:
1456
- raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol argument')
1457
- self.load_markets()
1458
- market = self.market(symbol)
1459
- request: dict = {
1460
- 'symbol': market['id'],
1461
- }
1462
- if limit is not None:
1463
- request['limit'] = limit
1464
- response = self.privateGetV2MyTrades(self.extend(request, params))
1465
- #
1466
- # [
1467
- # {
1468
- # "symbol": "DOGE/USD",
1469
- # "id": "116046000",
1470
- # "orderId": "00000000-0000-0000-0000-000006dbb8ad",
1471
- # "price": "0.14094",
1472
- # "qty": "40.0",
1473
- # "commission": "0.01",
1474
- # "commissionAsset": "USD",
1475
- # "time": "1645283022351",
1476
- # "buyer": False,
1477
- # "maker": False,
1478
- # "isBuyer": False,
1479
- # "isMaker": False
1480
- # },
1481
- # ]
1482
- #
1483
- return self.parse_trades(response, market, since, limit)
1484
-
1485
- def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1486
- """
1487
- fetch all deposits made to an account
1488
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getDepositsUsingGET
1489
- :param str code: unified currency code
1490
- :param int [since]: the earliest time in ms to fetch deposits for
1491
- :param int [limit]: the maximum number of deposits structures to retrieve
1492
- :param dict [params]: extra parameters specific to the exchange API endpoint
1493
- :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
1494
- """
1495
- return self.fetch_transactions_by_method('privateGetV2Deposits', code, since, limit, params)
1496
-
1497
- def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1498
- """
1499
- fetch all withdrawals made from an account
1500
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getWithdrawalsUsingGET
1501
- :param str code: unified currency code
1502
- :param int [since]: the earliest time in ms to fetch withdrawals for
1503
- :param int [limit]: the maximum number of withdrawals structures to retrieve
1504
- :param dict [params]: extra parameters specific to the exchange API endpoint
1505
- :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
1506
- """
1507
- return self.fetch_transactions_by_method('privateGetV2Withdrawals', code, since, limit, params)
1508
-
1509
- def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1510
- """
1511
- fetch history of deposits and withdrawals
1512
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getTransactionsUsingGET
1513
- :param str [code]: unified currency code for the currency of the deposit/withdrawals, default is None
1514
- :param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
1515
- :param int [limit]: max number of deposit/withdrawals to return, default is None
1516
- :param dict [params]: extra parameters specific to the exchange API endpoint
1517
- :returns dict: a list of `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1518
- """
1519
- return self.fetch_transactions_by_method('privateGetV2Transactions', code, since, limit, params)
1520
-
1521
- def fetch_transactions_by_method(self, method, code: Str = None, since: Int = None, limit: Int = None, params={}):
1522
- self.load_markets()
1523
- request: dict = {}
1524
- currency = None
1525
- if code is not None:
1526
- currency = self.currency(code)
1527
- if since is not None:
1528
- request['startTime'] = since
1529
- if limit is not None:
1530
- request['limit'] = limit
1531
- response = None
1532
- if method == 'privateGetV2Deposits':
1533
- response = self.privateGetV2Deposits(self.extend(request, params))
1534
- elif method == 'privateGetV2Withdrawals':
1535
- response = self.privateGetV2Withdrawals(self.extend(request, params))
1536
- elif method == 'privateGetV2Transactions':
1537
- response = self.privateGetV2Transactions(self.extend(request, params))
1538
- else:
1539
- raise NotSupported(self.id + ' fetchTransactionsByMethod() not support self method')
1540
- #
1541
- # [
1542
- # {
1543
- # "id": "616769213",
1544
- # "balance": "2.088",
1545
- # "amount": "1.304", # negative for 'withdrawal'
1546
- # "currency": "CAKE",
1547
- # "type": "deposit",
1548
- # "timestamp": "1645282121023",
1549
- # "paymentMethod": "BLOCKCHAIN",
1550
- # "blockchainTransactionHash": "0x57c68c1f2ae74d5eda5a2a00516361d241a5c9e1ee95bf32573523857c38c112",
1551
- # "status": "PROCESSED",
1552
- # "commission": "0.14", # self property only exists in withdrawal
1553
- # },
1554
- # ]
1555
- #
1556
- return self.parse_transactions(response, currency, since, limit, params)
1557
-
1558
- def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
1559
- #
1560
- # {
1561
- # "id": "616769213",
1562
- # "balance": "2.088",
1563
- # "amount": "1.304", # negative for 'withdrawal'
1564
- # "currency": "CAKE",
1565
- # "type": "deposit",
1566
- # "timestamp": "1645282121023",
1567
- # "paymentMethod": "BLOCKCHAIN",
1568
- # "blockchainTransactionHash": "0x57c68c1f2ae74d5eda5a2a00516361d241a5c9e1ee95bf32573523857c38c112",
1569
- # "status": "PROCESSED",
1570
- # "commission": "0.14", # self property only exists in withdrawal
1571
- # }
1572
- #
1573
- timestamp = self.safe_integer(transaction, 'timestamp')
1574
- currencyId = self.safe_string(transaction, 'currency')
1575
- code = self.safe_currency_code(currencyId, currency)
1576
- feeCost = self.safe_string(transaction, 'commission')
1577
- fee = {
1578
- 'currency': None,
1579
- 'cost': None,
1580
- 'rate': None,
1581
- }
1582
- if feeCost is not None:
1583
- fee['currency'] = code
1584
- fee['cost'] = feeCost
1585
- return {
1586
- 'info': transaction,
1587
- 'id': self.safe_string(transaction, 'id'),
1588
- 'txid': self.safe_string(transaction, 'blockchainTransactionHash'),
1589
- 'type': self.parse_transaction_type(self.safe_string(transaction, 'type')),
1590
- 'currency': code,
1591
- 'network': None,
1592
- 'amount': self.safe_number(transaction, 'amount'),
1593
- 'status': self.parse_transaction_status(self.safe_string(transaction, 'state')),
1594
- 'timestamp': timestamp,
1595
- 'datetime': self.iso8601(timestamp),
1596
- 'address': None,
1597
- 'addressFrom': None,
1598
- 'addressTo': None,
1599
- 'tag': None,
1600
- 'tagFrom': None,
1601
- 'tagTo': None,
1602
- 'updated': None,
1603
- 'internal': None,
1604
- 'comment': None,
1605
- 'fee': fee,
1606
- }
1607
-
1608
- def parse_transaction_status(self, status: Str):
1609
- statuses: dict = {
1610
- 'APPROVAL': 'pending',
1611
- 'PROCESSED': 'ok',
1612
- }
1613
- return self.safe_string(statuses, status, status)
1614
-
1615
- def parse_transaction_type(self, type):
1616
- types: dict = {
1617
- 'deposit': 'deposit',
1618
- 'withdrawal': 'withdrawal',
1619
- }
1620
- return self.safe_string(types, type, type)
1621
-
1622
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1623
- """
1624
- fetch the history of changes, actions done by the user or operations that altered balance of the user
1625
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getLedgerUsingGET
1626
- :param str code: unified currency code, default is None
1627
- :param int [since]: timestamp in ms of the earliest ledger entry, default is None
1628
- :param int [limit]: max number of ledger entrys to return, default is None
1629
- :param dict [params]: extra parameters specific to the exchange API endpoint
1630
- :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
1631
- """
1632
- self.load_markets()
1633
- request: dict = {}
1634
- currency = None
1635
- if code is not None:
1636
- currency = self.currency(code)
1637
- if since is not None:
1638
- request['startTime'] = since
1639
- if limit is not None:
1640
- request['limit'] = limit
1641
- response = self.privateGetV2Ledger(self.extend(request, params))
1642
- # in the below example, first item expresses withdrawal/deposit type, second example expresses trade
1643
- #
1644
- # [
1645
- # {
1646
- # "id": "619031398",
1647
- # "balance": "0.0",
1648
- # "amount": "-1.088",
1649
- # "currency": "CAKE",
1650
- # "type": "withdrawal",
1651
- # "timestamp": "1645460496425",
1652
- # "commission": "0.13",
1653
- # "paymentMethod": "BLOCKCHAIN", # present in withdrawal/deposit
1654
- # "blockchainTransactionHash": "0x400ac905557c3d34638b1c60eba110b3ee0f97f4eb0f7318015ab76e7f16b7d6", # present in withdrawal/deposit
1655
- # "status": "PROCESSED"
1656
- # },
1657
- # {
1658
- # "id": "619031034",
1659
- # "balance": "8.17223588",
1660
- # "amount": "-0.01326294",
1661
- # "currency": "USD",
1662
- # "type": "exchange_commission",
1663
- # "timestamp": "1645460461235",
1664
- # "commission": "0.01326294",
1665
- # "status": "PROCESSED"
1666
- # },
1667
- # ]
1668
- #
1669
- return self.parse_ledger(response, currency, since, limit)
1670
-
1671
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
1672
- id = self.safe_string(item, 'id')
1673
- amountString = self.safe_string(item, 'amount')
1674
- amount = Precise.string_abs(amountString)
1675
- timestamp = self.safe_integer(item, 'timestamp')
1676
- currencyId = self.safe_string(item, 'currency')
1677
- code = self.safe_currency_code(currencyId, currency)
1678
- feeCost = self.safe_string(item, 'commission')
1679
- fee = None
1680
- if feeCost is not None:
1681
- fee = {'currency': code, 'cost': feeCost}
1682
- direction = 'out' if Precise.string_lt(amountString, '0') else 'in'
1683
- result: dict = {
1684
- 'id': id,
1685
- 'timestamp': timestamp,
1686
- 'datetime': self.iso8601(timestamp),
1687
- 'direction': direction,
1688
- 'account': None,
1689
- 'referenceId': self.safe_string(item, 'blockchainTransactionHash'),
1690
- 'referenceAccount': None,
1691
- 'type': self.parse_ledger_entry_type(self.safe_string(item, 'type')),
1692
- 'currency': code,
1693
- 'amount': amount,
1694
- 'before': None,
1695
- 'after': self.safe_string(item, 'balance'),
1696
- 'status': self.parse_ledger_entry_status(self.safe_string(item, 'status')),
1697
- 'fee': fee,
1698
- 'info': item,
1699
- }
1700
- return result
1701
-
1702
- def parse_ledger_entry_status(self, status):
1703
- statuses: dict = {
1704
- 'APPROVAL': 'pending',
1705
- 'PROCESSED': 'ok',
1706
- 'CANCELLED': 'canceled',
1707
- }
1708
- return self.safe_string(statuses, status, status)
1709
-
1710
- def parse_ledger_entry_type(self, type):
1711
- types: dict = {
1712
- 'deposit': 'transaction',
1713
- 'withdrawal': 'transaction',
1714
- 'exchange_commission': 'fee',
1715
- }
1716
- return self.safe_string(types, type, type)
1717
-
1718
- def fetch_leverage(self, symbol: str, params={}) -> Leverage:
1719
- """
1720
- fetch the set leverage for a market
1721
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/leverageSettingsUsingGET
1722
- :param str symbol: unified market symbol
1723
- :param dict [params]: extra parameters specific to the exchange API endpoint
1724
- :returns dict: a `leverage structure <https://docs.ccxt.com/#/?id=leverage-structure>`
1725
- """
1726
- self.load_markets()
1727
- market = self.market(symbol)
1728
- request: dict = {
1729
- 'symbol': market['id'],
1730
- }
1731
- response = self.privateGetV2LeverageSettings(self.extend(request, params))
1732
- #
1733
- # {
1734
- # "values": [1, 2, 5, 10,],
1735
- # "value": "10",
1736
- # }
1737
- #
1738
- return self.parse_leverage(response, market)
1739
-
1740
- def parse_leverage(self, leverage: dict, market: Market = None) -> Leverage:
1741
- leverageValue = self.safe_integer(leverage, 'value')
1742
- return {
1743
- 'info': leverage,
1744
- 'symbol': market['symbol'],
1745
- 'marginMode': None,
1746
- 'longLeverage': leverageValue,
1747
- 'shortLeverage': leverageValue,
1748
- }
1749
-
1750
- def fetch_deposit_address(self, code: str, params={}):
1751
- """
1752
- fetch the deposit address for a currency associated with self account
1753
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/getDepositAddressUsingGET
1754
- :param str code: unified currency code
1755
- :param dict [params]: extra parameters specific to the exchange API endpoint
1756
- :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
1757
- """
1758
- self.load_markets()
1759
- currency = self.currency(code)
1760
- request: dict = {
1761
- 'coin': currency['id'],
1762
- }
1763
- response = self.privateGetV2DepositAddress(self.extend(request, params))
1764
- #
1765
- # {"address":"0x97d64eb014ac779194991e7264f01c74c90327f0"}
1766
- #
1767
- return self.parse_deposit_address(response, currency)
1768
-
1769
- def parse_deposit_address(self, depositAddress, currency: Currency = None):
1770
- address = self.safe_string(depositAddress, 'address')
1771
- self.check_address(address)
1772
- currency = self.safe_currency(None, currency)
1773
- return {
1774
- 'currency': currency['code'],
1775
- 'address': address,
1776
- 'tag': None,
1777
- 'network': None,
1778
- 'info': depositAddress,
1779
- }
1780
-
1781
- def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
1782
- url = self.urls['api'][api] + '/' + path
1783
- if path == 'historicalTrades':
1784
- headers = {
1785
- 'X-MBX-APIKEY': self.apiKey,
1786
- }
1787
- if api == 'private':
1788
- self.check_required_credentials()
1789
- query = self.urlencode(self.extend({
1790
- 'timestamp': self.nonce(),
1791
- 'recvWindow': self.options['recvWindow'],
1792
- }, params))
1793
- signature = self.hmac(self.encode(query), self.encode(self.secret), hashlib.sha256)
1794
- query += '&' + 'signature=' + signature
1795
- headers = {
1796
- 'X-MBX-APIKEY': self.apiKey,
1797
- }
1798
- if (method == 'GET') or (method == 'DELETE'):
1799
- url += '?' + query
1800
- else:
1801
- body = query
1802
- headers['Content-Type'] = 'application/x-www-form-urlencoded'
1803
- else:
1804
- if params:
1805
- url += '?' + self.urlencode(params)
1806
- url = self.implode_hostname(url)
1807
- return {'url': url, 'method': method, 'body': body, 'headers': headers}
1808
-
1809
- def fetch_positions(self, symbols: Strings = None, params={}):
1810
- """
1811
- fetch all open positions
1812
- :see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/tradingPositionsUsingGET
1813
- :param str[]|None symbols: list of unified market symbols
1814
- :param dict [params]: extra parameters specific to the exchange API endpoint
1815
- :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
1816
- """
1817
- self.load_markets()
1818
- response = self.privateGetV2TradingPositions(params)
1819
- #
1820
- # {
1821
- # "positions": [
1822
- # {
1823
- # "accountId": "109698017416453793",
1824
- # "id": "00a18490-0079-54c4-0000-0000803e73d3",
1825
- # "instrumentId": "45463225268524228",
1826
- # "orderId": "00a18490-0079-54c4-0000-0000803e73d2",
1827
- # "openQuantity": "13.6",
1828
- # "openPrice": "0.75724",
1829
- # "closeQuantity": "0.0",
1830
- # "closePrice": "0",
1831
- # "rpl": "-0.007723848",
1832
- # "rplConverted": "0",
1833
- # "upl": "-0.006664",
1834
- # "uplConverted": "-0.006664",
1835
- # "swap": "0",
1836
- # "swapConverted": "0",
1837
- # "fee": "-0.007723848",
1838
- # "dividend": "0",
1839
- # "margin": "0.2",
1840
- # "state": "ACTIVE",
1841
- # "currency": "USD",
1842
- # "createdTimestamp": "1645473877236",
1843
- # "openTimestamp": "1645473877193",
1844
- # "type": "NET",
1845
- # "cost": "2.0583600",
1846
- # "symbol": "XRP/USD_LEVERAGE"
1847
- # }
1848
- # ]
1849
- # }
1850
- #
1851
- data = self.safe_list(response, 'positions', [])
1852
- return self.parse_positions(data, symbols)
1853
-
1854
- def parse_position(self, position: dict, market: Market = None):
1855
- #
1856
- # {
1857
- # "accountId": "109698017416453793",
1858
- # "id": "00a18490-0079-54c4-0000-0000803e73d3",
1859
- # "instrumentId": "45463225268524228",
1860
- # "orderId": "00a18490-0079-54c4-0000-0000803e73d2",
1861
- # "openQuantity": "13.6",
1862
- # "openPrice": "0.75724",
1863
- # "closeQuantity": "0.0",
1864
- # "closePrice": "0",
1865
- # "rpl": "-0.007723848",
1866
- # "rplConverted": "0",
1867
- # "upl": "-0.006664",
1868
- # "uplConverted": "-0.006664",
1869
- # "swap": "0",
1870
- # "swapConverted": "0",
1871
- # "fee": "-0.007723848",
1872
- # "dividend": "0",
1873
- # "margin": "0.2",
1874
- # "state": "ACTIVE",
1875
- # "currency": "USD",
1876
- # "createdTimestamp": "1645473877236",
1877
- # "openTimestamp": "1645473877193",
1878
- # "type": "NET",
1879
- # "cost": "2.0583600",
1880
- # "symbol": "XRP/USD_LEVERAGE"
1881
- # }
1882
- #
1883
- market = self.safe_market(self.safe_string(position, 'symbol'), market)
1884
- symbol = market['symbol']
1885
- timestamp = self.safe_integer(position, 'createdTimestamp')
1886
- quantityRaw = self.safe_string(position, 'openQuantity')
1887
- side = 'long' if Precise.string_gt(quantityRaw, '0') else 'short'
1888
- quantity = Precise.string_abs(quantityRaw)
1889
- entryPrice = self.safe_number(position, 'openPrice')
1890
- unrealizedProfit = self.safe_number(position, 'upl')
1891
- marginCoeff = self.safe_string(position, 'margin')
1892
- leverage = Precise.string_div('1', marginCoeff)
1893
- return self.safe_position({
1894
- 'info': position,
1895
- 'symbol': symbol,
1896
- 'timestamp': timestamp,
1897
- 'datetime': self.iso8601(timestamp),
1898
- 'lastUpdateTimestamp': None,
1899
- 'contracts': self.parse_number(quantity),
1900
- 'contractSize': None,
1901
- 'entryPrice': entryPrice,
1902
- 'collateral': None,
1903
- 'side': side,
1904
- # 'realizedProfit': self.safe_number(position, 'rpl'),
1905
- 'unrealizedProfit': unrealizedProfit,
1906
- 'leverage': leverage,
1907
- 'percentage': None,
1908
- 'marginMode': None,
1909
- 'notional': None,
1910
- 'markPrice': None,
1911
- 'lastPrice': None,
1912
- 'liquidationPrice': None,
1913
- 'initialMargin': None,
1914
- 'initialMarginPercentage': None,
1915
- 'maintenanceMargin': self.parse_number(marginCoeff),
1916
- 'maintenanceMarginPercentage': None,
1917
- 'marginRatio': None,
1918
- 'id': None,
1919
- 'unrealizedPnl': None,
1920
- 'hedged': None,
1921
- 'stopLossPrice': None,
1922
- 'takeProfitPrice': None,
1923
- })
1924
-
1925
- def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
1926
- if (httpCode == 418) or (httpCode == 429):
1927
- raise DDoSProtection(self.id + ' ' + str(httpCode) + ' ' + reason + ' ' + body)
1928
- # error response in a form: {"code": -1013, "msg": "Invalid quantity."}
1929
- # following block cointains legacy checks against message patterns in "msg" property
1930
- # will switch "code" checks eventually, when we know all of them
1931
- if httpCode >= 400:
1932
- if body.find('Price * QTY is zero or less') >= 0:
1933
- raise InvalidOrder(self.id + ' order cost = amount * price is zero or less ' + body)
1934
- if body.find('LOT_SIZE') >= 0:
1935
- raise InvalidOrder(self.id + ' order amount should be evenly divisible by lot size ' + body)
1936
- if body.find('PRICE_FILTER') >= 0:
1937
- raise InvalidOrder(self.id + ' order price is invalid, i.e. exceeds allowed price precision, exceeds min price or max price limits or is invalid float value in general, use self.price_to_precision(symbol, amount) ' + body)
1938
- if response is None:
1939
- return None # fallback to default error handler
1940
- #
1941
- # {"code":-1128,"msg":"Combination of optional parameters invalid."}
1942
- #
1943
- errorCode = self.safe_string(response, 'code')
1944
- if (errorCode is not None) and (errorCode != '0'):
1945
- feedback = self.id + ' ' + self.json(response)
1946
- self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
1947
- message = self.safe_string(response, 'msg')
1948
- self.throw_broadly_matched_exception(self.exceptions['broad'], message, feedback)
1949
- raise ExchangeError(feedback)
1950
- return None