ccxt-ir 4.3.46.0.1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (772) hide show
  1. ccxt/__init__.py +358 -0
  2. ccxt/abantether.py +316 -0
  3. ccxt/abstract/__init__.py +0 -0
  4. ccxt/abstract/abantether.py +5 -0
  5. ccxt/abstract/ace.py +15 -0
  6. ccxt/abstract/afratether.py +6 -0
  7. ccxt/abstract/alpaca.py +70 -0
  8. ccxt/abstract/arzinja.py +5 -0
  9. ccxt/abstract/arzplus.py +7 -0
  10. ccxt/abstract/ascendex.py +77 -0
  11. ccxt/abstract/bequant.py +115 -0
  12. ccxt/abstract/bigone.py +45 -0
  13. ccxt/abstract/binance.py +712 -0
  14. ccxt/abstract/binancecoinm.py +712 -0
  15. ccxt/abstract/binanceus.py +764 -0
  16. ccxt/abstract/binanceusdm.py +712 -0
  17. ccxt/abstract/bingx.py +113 -0
  18. ccxt/abstract/bit2c.py +27 -0
  19. ccxt/abstract/bitbank.py +27 -0
  20. ccxt/abstract/bitbay.py +53 -0
  21. ccxt/abstract/bitbns.py +40 -0
  22. ccxt/abstract/bitcoincom.py +115 -0
  23. ccxt/abstract/bitfinex.py +69 -0
  24. ccxt/abstract/bitfinex2.py +139 -0
  25. ccxt/abstract/bitflyer.py +38 -0
  26. ccxt/abstract/bitget.py +508 -0
  27. ccxt/abstract/bithumb.py +32 -0
  28. ccxt/abstract/bitimen.py +7 -0
  29. ccxt/abstract/bitir.py +7 -0
  30. ccxt/abstract/bitmart.py +99 -0
  31. ccxt/abstract/bitmex.py +97 -0
  32. ccxt/abstract/bitopro.py +29 -0
  33. ccxt/abstract/bitpanda.py +35 -0
  34. ccxt/abstract/bitpin.py +7 -0
  35. ccxt/abstract/bitrue.py +72 -0
  36. ccxt/abstract/bitso.py +43 -0
  37. ccxt/abstract/bitstamp.py +258 -0
  38. ccxt/abstract/bitteam.py +29 -0
  39. ccxt/abstract/bitvavo.py +27 -0
  40. ccxt/abstract/bl3p.py +19 -0
  41. ccxt/abstract/blockchaincom.py +28 -0
  42. ccxt/abstract/blofin.py +37 -0
  43. ccxt/abstract/btcalpha.py +18 -0
  44. ccxt/abstract/btcbox.py +13 -0
  45. ccxt/abstract/btcmarkets.py +39 -0
  46. ccxt/abstract/btcturk.py +20 -0
  47. ccxt/abstract/bybit.py +298 -0
  48. ccxt/abstract/cex.py +33 -0
  49. ccxt/abstract/coinbase.py +94 -0
  50. ccxt/abstract/coinbaseadvanced.py +94 -0
  51. ccxt/abstract/coinbaseexchange.py +67 -0
  52. ccxt/abstract/coinbaseinternational.py +39 -0
  53. ccxt/abstract/coincatch.py +94 -0
  54. ccxt/abstract/coincheck.py +33 -0
  55. ccxt/abstract/coinex.py +237 -0
  56. ccxt/abstract/coinlist.py +54 -0
  57. ccxt/abstract/coinmate.py +62 -0
  58. ccxt/abstract/coinmetro.py +34 -0
  59. ccxt/abstract/coinone.py +67 -0
  60. ccxt/abstract/coinsph.py +54 -0
  61. ccxt/abstract/coinspot.py +28 -0
  62. ccxt/abstract/cryptocom.py +107 -0
  63. ccxt/abstract/currencycom.py +68 -0
  64. ccxt/abstract/delta.py +50 -0
  65. ccxt/abstract/deribit.py +125 -0
  66. ccxt/abstract/digifinex.py +91 -0
  67. ccxt/abstract/eterex.py +5 -0
  68. ccxt/abstract/excoino.py +7 -0
  69. ccxt/abstract/exir.py +8 -0
  70. ccxt/abstract/exmo.py +55 -0
  71. ccxt/abstract/exnovin.py +6 -0
  72. ccxt/abstract/farhadexchange.py +5 -0
  73. ccxt/abstract/fmfwio.py +115 -0
  74. ccxt/abstract/gate.py +265 -0
  75. ccxt/abstract/gateio.py +265 -0
  76. ccxt/abstract/gemini.py +58 -0
  77. ccxt/abstract/hashkey.py +67 -0
  78. ccxt/abstract/hitbtc.py +115 -0
  79. ccxt/abstract/hitbtc3.py +115 -0
  80. ccxt/abstract/hitobit.py +8 -0
  81. ccxt/abstract/hollaex.py +33 -0
  82. ccxt/abstract/htx.py +548 -0
  83. ccxt/abstract/huobi.py +548 -0
  84. ccxt/abstract/huobijp.py +114 -0
  85. ccxt/abstract/hyperliquid.py +6 -0
  86. ccxt/abstract/idex.py +26 -0
  87. ccxt/abstract/independentreserve.py +37 -0
  88. ccxt/abstract/indodax.py +26 -0
  89. ccxt/abstract/jibitex.py +7 -0
  90. ccxt/abstract/kraken.py +57 -0
  91. ccxt/abstract/krakenfutures.py +38 -0
  92. ccxt/abstract/kucoin.py +214 -0
  93. ccxt/abstract/kucoinfutures.py +233 -0
  94. ccxt/abstract/kuna.py +182 -0
  95. ccxt/abstract/latoken.py +56 -0
  96. ccxt/abstract/lbank.py +61 -0
  97. ccxt/abstract/luno.py +37 -0
  98. ccxt/abstract/lykke.py +29 -0
  99. ccxt/abstract/mercado.py +25 -0
  100. ccxt/abstract/mexc.py +178 -0
  101. ccxt/abstract/ndax.py +97 -0
  102. ccxt/abstract/nobitex.py +7 -0
  103. ccxt/abstract/novadax.py +29 -0
  104. ccxt/abstract/oceanex.py +22 -0
  105. ccxt/abstract/okcoin.py +74 -0
  106. ccxt/abstract/okexchange.py +8 -0
  107. ccxt/abstract/okx.py +324 -0
  108. ccxt/abstract/ompfinex.py +7 -0
  109. ccxt/abstract/onetrading.py +35 -0
  110. ccxt/abstract/oxfun.py +34 -0
  111. ccxt/abstract/p2b.py +22 -0
  112. ccxt/abstract/paradex.py +40 -0
  113. ccxt/abstract/paymium.py +28 -0
  114. ccxt/abstract/phemex.py +115 -0
  115. ccxt/abstract/poloniex.py +69 -0
  116. ccxt/abstract/poloniexfutures.py +48 -0
  117. ccxt/abstract/probit.py +23 -0
  118. ccxt/abstract/ramzinex.py +7 -0
  119. ccxt/abstract/sarmayex.py +5 -0
  120. ccxt/abstract/sarrafex.py +7 -0
  121. ccxt/abstract/tabdeal.py +7 -0
  122. ccxt/abstract/tetherland.py +5 -0
  123. ccxt/abstract/timex.py +62 -0
  124. ccxt/abstract/tokocrypto.py +37 -0
  125. ccxt/abstract/tradeogre.py +16 -0
  126. ccxt/abstract/twox.py +5 -0
  127. ccxt/abstract/ubitex.py +7 -0
  128. ccxt/abstract/upbit.py +38 -0
  129. ccxt/abstract/vertex.py +19 -0
  130. ccxt/abstract/wallex.py +8 -0
  131. ccxt/abstract/wavesexchange.py +154 -0
  132. ccxt/abstract/wazirx.py +30 -0
  133. ccxt/abstract/whitebit.py +98 -0
  134. ccxt/abstract/woo.py +83 -0
  135. ccxt/abstract/woofipro.py +119 -0
  136. ccxt/abstract/xt.py +152 -0
  137. ccxt/abstract/yobit.py +16 -0
  138. ccxt/abstract/zaif.py +38 -0
  139. ccxt/abstract/zonda.py +53 -0
  140. ccxt/ace.py +1012 -0
  141. ccxt/afratether.py +293 -0
  142. ccxt/alpaca.py +1083 -0
  143. ccxt/arzinja.py +285 -0
  144. ccxt/arzplus.py +412 -0
  145. ccxt/ascendex.py +3330 -0
  146. ccxt/async_support/__init__.py +337 -0
  147. ccxt/async_support/abantether.py +316 -0
  148. ccxt/async_support/ace.py +1012 -0
  149. ccxt/async_support/afratether.py +293 -0
  150. ccxt/async_support/alpaca.py +1083 -0
  151. ccxt/async_support/arzinja.py +285 -0
  152. ccxt/async_support/arzplus.py +412 -0
  153. ccxt/async_support/ascendex.py +3330 -0
  154. ccxt/async_support/base/__init__.py +1 -0
  155. ccxt/async_support/base/exchange.py +1966 -0
  156. ccxt/async_support/base/throttler.py +50 -0
  157. ccxt/async_support/base/ws/__init__.py +38 -0
  158. ccxt/async_support/base/ws/aiohttp_client.py +125 -0
  159. ccxt/async_support/base/ws/cache.py +212 -0
  160. ccxt/async_support/base/ws/client.py +193 -0
  161. ccxt/async_support/base/ws/fast_client.py +96 -0
  162. ccxt/async_support/base/ws/functions.py +59 -0
  163. ccxt/async_support/base/ws/future.py +58 -0
  164. ccxt/async_support/base/ws/order_book.py +78 -0
  165. ccxt/async_support/base/ws/order_book_side.py +174 -0
  166. ccxt/async_support/bequant.py +33 -0
  167. ccxt/async_support/bigone.py +2113 -0
  168. ccxt/async_support/binance.py +12234 -0
  169. ccxt/async_support/binancecoinm.py +45 -0
  170. ccxt/async_support/binanceus.py +211 -0
  171. ccxt/async_support/binanceusdm.py +58 -0
  172. ccxt/async_support/bingx.py +4325 -0
  173. ccxt/async_support/bit2c.py +866 -0
  174. ccxt/async_support/bitbank.py +1001 -0
  175. ccxt/async_support/bitbay.py +17 -0
  176. ccxt/async_support/bitbns.py +1154 -0
  177. ccxt/async_support/bitcoincom.py +17 -0
  178. ccxt/async_support/bitfinex.py +1617 -0
  179. ccxt/async_support/bitfinex2.py +3552 -0
  180. ccxt/async_support/bitflyer.py +995 -0
  181. ccxt/async_support/bitget.py +8273 -0
  182. ccxt/async_support/bithumb.py +1061 -0
  183. ccxt/async_support/bitimen.py +401 -0
  184. ccxt/async_support/bitir.py +490 -0
  185. ccxt/async_support/bitmart.py +4415 -0
  186. ccxt/async_support/bitmex.py +2756 -0
  187. ccxt/async_support/bitopro.py +1630 -0
  188. ccxt/async_support/bitpanda.py +16 -0
  189. ccxt/async_support/bitpin.py +454 -0
  190. ccxt/async_support/bitrue.py +3027 -0
  191. ccxt/async_support/bitso.py +1670 -0
  192. ccxt/async_support/bitstamp.py +2203 -0
  193. ccxt/async_support/bitteam.py +2239 -0
  194. ccxt/async_support/bitvavo.py +1968 -0
  195. ccxt/async_support/bl3p.py +485 -0
  196. ccxt/async_support/blockchaincom.py +1104 -0
  197. ccxt/async_support/blofin.py +2066 -0
  198. ccxt/async_support/btcalpha.py +891 -0
  199. ccxt/async_support/btcbox.py +544 -0
  200. ccxt/async_support/btcmarkets.py +1221 -0
  201. ccxt/async_support/btcturk.py +911 -0
  202. ccxt/async_support/bybit.py +8159 -0
  203. ccxt/async_support/cex.py +1605 -0
  204. ccxt/async_support/coinbase.py +4475 -0
  205. ccxt/async_support/coinbaseadvanced.py +17 -0
  206. ccxt/async_support/coinbaseexchange.py +1734 -0
  207. ccxt/async_support/coinbaseinternational.py +1899 -0
  208. ccxt/async_support/coincatch.py +5069 -0
  209. ccxt/async_support/coincheck.py +815 -0
  210. ccxt/async_support/coinex.py +5526 -0
  211. ccxt/async_support/coinlist.py +2243 -0
  212. ccxt/async_support/coinmate.py +1067 -0
  213. ccxt/async_support/coinmetro.py +1797 -0
  214. ccxt/async_support/coinone.py +1127 -0
  215. ccxt/async_support/coinsph.py +1850 -0
  216. ccxt/async_support/coinspot.py +534 -0
  217. ccxt/async_support/cryptocom.py +2822 -0
  218. ccxt/async_support/currencycom.py +1950 -0
  219. ccxt/async_support/delta.py +3376 -0
  220. ccxt/async_support/deribit.py +3437 -0
  221. ccxt/async_support/digifinex.py +3960 -0
  222. ccxt/async_support/eterex.py +286 -0
  223. ccxt/async_support/excoino.py +399 -0
  224. ccxt/async_support/exir.py +375 -0
  225. ccxt/async_support/exmo.py +2462 -0
  226. ccxt/async_support/exnovin.py +360 -0
  227. ccxt/async_support/farhadexchange.py +266 -0
  228. ccxt/async_support/fmfwio.py +34 -0
  229. ccxt/async_support/gate.py +6976 -0
  230. ccxt/async_support/gateio.py +16 -0
  231. ccxt/async_support/gemini.py +1825 -0
  232. ccxt/async_support/hashkey.py +4150 -0
  233. ccxt/async_support/hitbtc.py +3423 -0
  234. ccxt/async_support/hitbtc3.py +16 -0
  235. ccxt/async_support/hitobit.py +391 -0
  236. ccxt/async_support/hollaex.py +1813 -0
  237. ccxt/async_support/htx.py +8506 -0
  238. ccxt/async_support/huobi.py +16 -0
  239. ccxt/async_support/huobijp.py +1801 -0
  240. ccxt/async_support/hyperliquid.py +2431 -0
  241. ccxt/async_support/idex.py +1766 -0
  242. ccxt/async_support/independentreserve.py +784 -0
  243. ccxt/async_support/indodax.py +1247 -0
  244. ccxt/async_support/jibitex.py +395 -0
  245. ccxt/async_support/kraken.py +2894 -0
  246. ccxt/async_support/krakenfutures.py +2601 -0
  247. ccxt/async_support/kucoin.py +4602 -0
  248. ccxt/async_support/kucoinfutures.py +2698 -0
  249. ccxt/async_support/kuna.py +1841 -0
  250. ccxt/async_support/latoken.py +1664 -0
  251. ccxt/async_support/lbank.py +2683 -0
  252. ccxt/async_support/luno.py +1067 -0
  253. ccxt/async_support/lykke.py +1270 -0
  254. ccxt/async_support/mercado.py +842 -0
  255. ccxt/async_support/mexc.py +5369 -0
  256. ccxt/async_support/ndax.py +2354 -0
  257. ccxt/async_support/nobitex.py +419 -0
  258. ccxt/async_support/novadax.py +1484 -0
  259. ccxt/async_support/oceanex.py +903 -0
  260. ccxt/async_support/okcoin.py +2936 -0
  261. ccxt/async_support/okexchange.py +349 -0
  262. ccxt/async_support/okx.py +7827 -0
  263. ccxt/async_support/ompfinex.py +472 -0
  264. ccxt/async_support/onetrading.py +1911 -0
  265. ccxt/async_support/oxfun.py +2773 -0
  266. ccxt/async_support/p2b.py +1194 -0
  267. ccxt/async_support/paradex.py +2015 -0
  268. ccxt/async_support/paymium.py +564 -0
  269. ccxt/async_support/phemex.py +4473 -0
  270. ccxt/async_support/poloniex.py +2232 -0
  271. ccxt/async_support/poloniexfutures.py +1717 -0
  272. ccxt/async_support/probit.py +1734 -0
  273. ccxt/async_support/ramzinex.py +476 -0
  274. ccxt/async_support/sarmayex.py +357 -0
  275. ccxt/async_support/sarrafex.py +478 -0
  276. ccxt/async_support/tabdeal.py +364 -0
  277. ccxt/async_support/tetherland.py +349 -0
  278. ccxt/async_support/timex.py +1593 -0
  279. ccxt/async_support/tokocrypto.py +2405 -0
  280. ccxt/async_support/tradeogre.py +608 -0
  281. ccxt/async_support/twox.py +326 -0
  282. ccxt/async_support/ubitex.py +409 -0
  283. ccxt/async_support/upbit.py +1833 -0
  284. ccxt/async_support/vertex.py +2922 -0
  285. ccxt/async_support/wallex.py +445 -0
  286. ccxt/async_support/wavesexchange.py +2473 -0
  287. ccxt/async_support/wazirx.py +1224 -0
  288. ccxt/async_support/whitebit.py +2469 -0
  289. ccxt/async_support/woo.py +3114 -0
  290. ccxt/async_support/woofipro.py +2533 -0
  291. ccxt/async_support/xt.py +4454 -0
  292. ccxt/async_support/yobit.py +1283 -0
  293. ccxt/async_support/zaif.py +725 -0
  294. ccxt/async_support/zonda.py +1828 -0
  295. ccxt/base/__init__.py +27 -0
  296. ccxt/base/decimal_to_precision.py +174 -0
  297. ccxt/base/errors.py +242 -0
  298. ccxt/base/exchange.py +5941 -0
  299. ccxt/base/precise.py +287 -0
  300. ccxt/base/types.py +502 -0
  301. ccxt/bequant.py +33 -0
  302. ccxt/bigone.py +2112 -0
  303. ccxt/binance.py +12233 -0
  304. ccxt/binancecoinm.py +45 -0
  305. ccxt/binanceus.py +211 -0
  306. ccxt/binanceusdm.py +58 -0
  307. ccxt/bingx.py +4324 -0
  308. ccxt/bit2c.py +866 -0
  309. ccxt/bitbank.py +1001 -0
  310. ccxt/bitbay.py +17 -0
  311. ccxt/bitbns.py +1154 -0
  312. ccxt/bitcoincom.py +17 -0
  313. ccxt/bitfinex.py +1617 -0
  314. ccxt/bitfinex2.py +3552 -0
  315. ccxt/bitflyer.py +995 -0
  316. ccxt/bitget.py +8272 -0
  317. ccxt/bithumb.py +1061 -0
  318. ccxt/bitimen.py +401 -0
  319. ccxt/bitir.py +490 -0
  320. ccxt/bitmart.py +4415 -0
  321. ccxt/bitmex.py +2756 -0
  322. ccxt/bitopro.py +1630 -0
  323. ccxt/bitpanda.py +16 -0
  324. ccxt/bitpin.py +454 -0
  325. ccxt/bitrue.py +3026 -0
  326. ccxt/bitso.py +1670 -0
  327. ccxt/bitstamp.py +2203 -0
  328. ccxt/bitteam.py +2239 -0
  329. ccxt/bitvavo.py +1968 -0
  330. ccxt/bl3p.py +485 -0
  331. ccxt/blockchaincom.py +1104 -0
  332. ccxt/blofin.py +2066 -0
  333. ccxt/btcalpha.py +891 -0
  334. ccxt/btcbox.py +544 -0
  335. ccxt/btcmarkets.py +1221 -0
  336. ccxt/btcturk.py +911 -0
  337. ccxt/bybit.py +8158 -0
  338. ccxt/cex.py +1605 -0
  339. ccxt/coinbase.py +4474 -0
  340. ccxt/coinbaseadvanced.py +17 -0
  341. ccxt/coinbaseexchange.py +1734 -0
  342. ccxt/coinbaseinternational.py +1899 -0
  343. ccxt/coincatch.py +5069 -0
  344. ccxt/coincheck.py +815 -0
  345. ccxt/coinex.py +5525 -0
  346. ccxt/coinlist.py +2243 -0
  347. ccxt/coinmate.py +1067 -0
  348. ccxt/coinmetro.py +1797 -0
  349. ccxt/coinone.py +1127 -0
  350. ccxt/coinsph.py +1850 -0
  351. ccxt/coinspot.py +534 -0
  352. ccxt/cryptocom.py +2822 -0
  353. ccxt/currencycom.py +1950 -0
  354. ccxt/delta.py +3376 -0
  355. ccxt/deribit.py +3437 -0
  356. ccxt/digifinex.py +3959 -0
  357. ccxt/eterex.py +286 -0
  358. ccxt/excoino.py +399 -0
  359. ccxt/exir.py +375 -0
  360. ccxt/exmo.py +2462 -0
  361. ccxt/exnovin.py +360 -0
  362. ccxt/farhadexchange.py +266 -0
  363. ccxt/fmfwio.py +34 -0
  364. ccxt/gate.py +6975 -0
  365. ccxt/gateio.py +16 -0
  366. ccxt/gemini.py +1824 -0
  367. ccxt/hashkey.py +4150 -0
  368. ccxt/hitbtc.py +3423 -0
  369. ccxt/hitbtc3.py +16 -0
  370. ccxt/hitobit.py +391 -0
  371. ccxt/hollaex.py +1813 -0
  372. ccxt/htx.py +8505 -0
  373. ccxt/huobi.py +16 -0
  374. ccxt/huobijp.py +1801 -0
  375. ccxt/hyperliquid.py +2430 -0
  376. ccxt/idex.py +1766 -0
  377. ccxt/independentreserve.py +784 -0
  378. ccxt/indodax.py +1247 -0
  379. ccxt/jibitex.py +395 -0
  380. ccxt/kraken.py +2894 -0
  381. ccxt/krakenfutures.py +2601 -0
  382. ccxt/kucoin.py +4601 -0
  383. ccxt/kucoinfutures.py +2698 -0
  384. ccxt/kuna.py +1841 -0
  385. ccxt/latoken.py +1664 -0
  386. ccxt/lbank.py +2682 -0
  387. ccxt/luno.py +1067 -0
  388. ccxt/lykke.py +1270 -0
  389. ccxt/mercado.py +842 -0
  390. ccxt/mexc.py +5369 -0
  391. ccxt/ndax.py +2354 -0
  392. ccxt/nobitex.py +419 -0
  393. ccxt/novadax.py +1484 -0
  394. ccxt/oceanex.py +903 -0
  395. ccxt/okcoin.py +2936 -0
  396. ccxt/okexchange.py +349 -0
  397. ccxt/okx.py +7826 -0
  398. ccxt/ompfinex.py +472 -0
  399. ccxt/onetrading.py +1911 -0
  400. ccxt/oxfun.py +2772 -0
  401. ccxt/p2b.py +1194 -0
  402. ccxt/paradex.py +2015 -0
  403. ccxt/paymium.py +564 -0
  404. ccxt/phemex.py +4473 -0
  405. ccxt/poloniex.py +2232 -0
  406. ccxt/poloniexfutures.py +1717 -0
  407. ccxt/pro/__init__.py +149 -0
  408. ccxt/pro/alpaca.py +685 -0
  409. ccxt/pro/ascendex.py +916 -0
  410. ccxt/pro/bequant.py +38 -0
  411. ccxt/pro/binance.py +3488 -0
  412. ccxt/pro/binancecoinm.py +28 -0
  413. ccxt/pro/binanceus.py +48 -0
  414. ccxt/pro/binanceusdm.py +31 -0
  415. ccxt/pro/bingx.py +1264 -0
  416. ccxt/pro/bitcoincom.py +34 -0
  417. ccxt/pro/bitfinex.py +621 -0
  418. ccxt/pro/bitfinex2.py +1083 -0
  419. ccxt/pro/bitget.py +1692 -0
  420. ccxt/pro/bithumb.py +368 -0
  421. ccxt/pro/bitmart.py +1449 -0
  422. ccxt/pro/bitmex.py +1656 -0
  423. ccxt/pro/bitopro.py +445 -0
  424. ccxt/pro/bitpanda.py +15 -0
  425. ccxt/pro/bitrue.py +447 -0
  426. ccxt/pro/bitstamp.py +522 -0
  427. ccxt/pro/bitvavo.py +1270 -0
  428. ccxt/pro/blockchaincom.py +738 -0
  429. ccxt/pro/blofin.py +692 -0
  430. ccxt/pro/bybit.py +2000 -0
  431. ccxt/pro/cex.py +1440 -0
  432. ccxt/pro/coinbase.py +678 -0
  433. ccxt/pro/coinbaseadvanced.py +16 -0
  434. ccxt/pro/coinbaseexchange.py +895 -0
  435. ccxt/pro/coinbaseinternational.py +620 -0
  436. ccxt/pro/coincatch.py +1464 -0
  437. ccxt/pro/coincheck.py +199 -0
  438. ccxt/pro/coinex.py +1061 -0
  439. ccxt/pro/coinone.py +395 -0
  440. ccxt/pro/cryptocom.py +947 -0
  441. ccxt/pro/currencycom.py +536 -0
  442. ccxt/pro/deribit.py +892 -0
  443. ccxt/pro/exmo.py +629 -0
  444. ccxt/pro/gate.py +1416 -0
  445. ccxt/pro/gateio.py +15 -0
  446. ccxt/pro/gemini.py +865 -0
  447. ccxt/pro/hashkey.py +802 -0
  448. ccxt/pro/hitbtc.py +1216 -0
  449. ccxt/pro/hollaex.py +563 -0
  450. ccxt/pro/htx.py +2215 -0
  451. ccxt/pro/huobi.py +15 -0
  452. ccxt/pro/huobijp.py +570 -0
  453. ccxt/pro/hyperliquid.py +525 -0
  454. ccxt/pro/idex.py +672 -0
  455. ccxt/pro/independentreserve.py +270 -0
  456. ccxt/pro/kraken.py +1356 -0
  457. ccxt/pro/krakenfutures.py +1492 -0
  458. ccxt/pro/kucoin.py +1133 -0
  459. ccxt/pro/kucoinfutures.py +1081 -0
  460. ccxt/pro/lbank.py +843 -0
  461. ccxt/pro/luno.py +303 -0
  462. ccxt/pro/mexc.py +1122 -0
  463. ccxt/pro/ndax.py +506 -0
  464. ccxt/pro/okcoin.py +698 -0
  465. ccxt/pro/okx.py +1851 -0
  466. ccxt/pro/onetrading.py +1275 -0
  467. ccxt/pro/oxfun.py +950 -0
  468. ccxt/pro/p2b.py +419 -0
  469. ccxt/pro/paradex.py +352 -0
  470. ccxt/pro/phemex.py +1441 -0
  471. ccxt/pro/poloniex.py +1166 -0
  472. ccxt/pro/poloniexfutures.py +990 -0
  473. ccxt/pro/probit.py +551 -0
  474. ccxt/pro/upbit.py +520 -0
  475. ccxt/pro/vertex.py +943 -0
  476. ccxt/pro/wazirx.py +749 -0
  477. ccxt/pro/whitebit.py +864 -0
  478. ccxt/pro/woo.py +1078 -0
  479. ccxt/pro/woofipro.py +1183 -0
  480. ccxt/pro/xt.py +1067 -0
  481. ccxt/probit.py +1734 -0
  482. ccxt/ramzinex.py +476 -0
  483. ccxt/sarmayex.py +357 -0
  484. ccxt/sarrafex.py +478 -0
  485. ccxt/static_dependencies/__init__.py +1 -0
  486. ccxt/static_dependencies/ecdsa/__init__.py +14 -0
  487. ccxt/static_dependencies/ecdsa/_version.py +520 -0
  488. ccxt/static_dependencies/ecdsa/curves.py +56 -0
  489. ccxt/static_dependencies/ecdsa/der.py +221 -0
  490. ccxt/static_dependencies/ecdsa/ecdsa.py +310 -0
  491. ccxt/static_dependencies/ecdsa/ellipticcurve.py +197 -0
  492. ccxt/static_dependencies/ecdsa/keys.py +332 -0
  493. ccxt/static_dependencies/ecdsa/numbertheory.py +531 -0
  494. ccxt/static_dependencies/ecdsa/rfc6979.py +100 -0
  495. ccxt/static_dependencies/ecdsa/util.py +266 -0
  496. ccxt/static_dependencies/ethereum/__init__.py +7 -0
  497. ccxt/static_dependencies/ethereum/abi/__init__.py +16 -0
  498. ccxt/static_dependencies/ethereum/abi/abi.py +19 -0
  499. ccxt/static_dependencies/ethereum/abi/base.py +152 -0
  500. ccxt/static_dependencies/ethereum/abi/codec.py +217 -0
  501. ccxt/static_dependencies/ethereum/abi/constants.py +3 -0
  502. ccxt/static_dependencies/ethereum/abi/decoding.py +565 -0
  503. ccxt/static_dependencies/ethereum/abi/encoding.py +720 -0
  504. ccxt/static_dependencies/ethereum/abi/exceptions.py +139 -0
  505. ccxt/static_dependencies/ethereum/abi/grammar.py +443 -0
  506. ccxt/static_dependencies/ethereum/abi/packed.py +13 -0
  507. ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
  508. ccxt/static_dependencies/ethereum/abi/registry.py +643 -0
  509. ccxt/static_dependencies/ethereum/abi/tools/__init__.py +3 -0
  510. ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +230 -0
  511. ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
  512. ccxt/static_dependencies/ethereum/abi/utils/numeric.py +83 -0
  513. ccxt/static_dependencies/ethereum/abi/utils/padding.py +27 -0
  514. ccxt/static_dependencies/ethereum/abi/utils/string.py +19 -0
  515. ccxt/static_dependencies/ethereum/account/__init__.py +3 -0
  516. ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +4 -0
  517. ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +239 -0
  518. ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +40 -0
  519. ccxt/static_dependencies/ethereum/account/messages.py +263 -0
  520. ccxt/static_dependencies/ethereum/account/py.typed +0 -0
  521. ccxt/static_dependencies/ethereum/hexbytes/__init__.py +5 -0
  522. ccxt/static_dependencies/ethereum/hexbytes/_utils.py +54 -0
  523. ccxt/static_dependencies/ethereum/hexbytes/main.py +65 -0
  524. ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
  525. ccxt/static_dependencies/ethereum/typing/__init__.py +63 -0
  526. ccxt/static_dependencies/ethereum/typing/abi.py +6 -0
  527. ccxt/static_dependencies/ethereum/typing/bls.py +7 -0
  528. ccxt/static_dependencies/ethereum/typing/discovery.py +5 -0
  529. ccxt/static_dependencies/ethereum/typing/encoding.py +7 -0
  530. ccxt/static_dependencies/ethereum/typing/enums.py +17 -0
  531. ccxt/static_dependencies/ethereum/typing/ethpm.py +9 -0
  532. ccxt/static_dependencies/ethereum/typing/evm.py +20 -0
  533. ccxt/static_dependencies/ethereum/typing/networks.py +1122 -0
  534. ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
  535. ccxt/static_dependencies/ethereum/utils/__init__.py +115 -0
  536. ccxt/static_dependencies/ethereum/utils/abi.py +72 -0
  537. ccxt/static_dependencies/ethereum/utils/address.py +171 -0
  538. ccxt/static_dependencies/ethereum/utils/applicators.py +151 -0
  539. ccxt/static_dependencies/ethereum/utils/conversions.py +190 -0
  540. ccxt/static_dependencies/ethereum/utils/currency.py +107 -0
  541. ccxt/static_dependencies/ethereum/utils/curried/__init__.py +269 -0
  542. ccxt/static_dependencies/ethereum/utils/debug.py +20 -0
  543. ccxt/static_dependencies/ethereum/utils/decorators.py +132 -0
  544. ccxt/static_dependencies/ethereum/utils/encoding.py +6 -0
  545. ccxt/static_dependencies/ethereum/utils/exceptions.py +4 -0
  546. ccxt/static_dependencies/ethereum/utils/functional.py +75 -0
  547. ccxt/static_dependencies/ethereum/utils/hexadecimal.py +74 -0
  548. ccxt/static_dependencies/ethereum/utils/humanize.py +188 -0
  549. ccxt/static_dependencies/ethereum/utils/logging.py +159 -0
  550. ccxt/static_dependencies/ethereum/utils/module_loading.py +31 -0
  551. ccxt/static_dependencies/ethereum/utils/numeric.py +43 -0
  552. ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
  553. ccxt/static_dependencies/ethereum/utils/toolz.py +76 -0
  554. ccxt/static_dependencies/ethereum/utils/types.py +54 -0
  555. ccxt/static_dependencies/ethereum/utils/typing/__init__.py +18 -0
  556. ccxt/static_dependencies/ethereum/utils/typing/misc.py +14 -0
  557. ccxt/static_dependencies/ethereum/utils/units.py +31 -0
  558. ccxt/static_dependencies/keccak/__init__.py +3 -0
  559. ccxt/static_dependencies/keccak/keccak.py +197 -0
  560. ccxt/static_dependencies/lark/__init__.py +38 -0
  561. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  562. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  563. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  564. ccxt/static_dependencies/lark/common.py +86 -0
  565. ccxt/static_dependencies/lark/exceptions.py +292 -0
  566. ccxt/static_dependencies/lark/grammar.py +130 -0
  567. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  568. ccxt/static_dependencies/lark/indenter.py +143 -0
  569. ccxt/static_dependencies/lark/lark.py +658 -0
  570. ccxt/static_dependencies/lark/lexer.py +678 -0
  571. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  572. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  573. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  574. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  575. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  576. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  577. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  578. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  579. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  580. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  581. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  582. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  583. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  584. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  585. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  586. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  587. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  588. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  589. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  590. ccxt/static_dependencies/lark/tree.py +267 -0
  591. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  592. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  593. ccxt/static_dependencies/lark/utils.py +343 -0
  594. ccxt/static_dependencies/lark/visitors.py +596 -0
  595. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  596. ccxt/static_dependencies/marshmallow/base.py +65 -0
  597. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  598. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  599. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  600. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  601. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  602. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  603. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  604. ccxt/static_dependencies/marshmallow/types.py +12 -0
  605. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  606. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  607. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  608. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  609. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  610. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  611. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  612. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  613. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  614. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  615. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  616. ccxt/static_dependencies/msgpack/__init__.py +55 -0
  617. ccxt/static_dependencies/msgpack/exceptions.py +48 -0
  618. ccxt/static_dependencies/msgpack/ext.py +168 -0
  619. ccxt/static_dependencies/msgpack/fallback.py +951 -0
  620. ccxt/static_dependencies/parsimonious/__init__.py +10 -0
  621. ccxt/static_dependencies/parsimonious/exceptions.py +105 -0
  622. ccxt/static_dependencies/parsimonious/expressions.py +479 -0
  623. ccxt/static_dependencies/parsimonious/grammar.py +487 -0
  624. ccxt/static_dependencies/parsimonious/nodes.py +325 -0
  625. ccxt/static_dependencies/parsimonious/utils.py +40 -0
  626. ccxt/static_dependencies/starknet/__init__.py +0 -0
  627. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  628. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  629. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  630. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  631. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  632. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  633. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  634. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  635. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  636. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  637. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  638. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  639. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  640. ccxt/static_dependencies/starknet/common.py +15 -0
  641. ccxt/static_dependencies/starknet/constants.py +39 -0
  642. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  643. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  644. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  645. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  646. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  647. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  648. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  649. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  650. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  651. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  652. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  653. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  654. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  655. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  656. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  657. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  658. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  659. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  660. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  661. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  662. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  663. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  664. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  665. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  666. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  667. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  668. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  669. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  670. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  671. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  672. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  673. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  674. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  675. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  676. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  677. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  678. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  679. ccxt/static_dependencies/starkware/__init__.py +0 -0
  680. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  681. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  682. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  683. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  684. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  685. ccxt/static_dependencies/sympy/__init__.py +0 -0
  686. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  687. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  688. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  689. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  690. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  691. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  692. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  693. ccxt/static_dependencies/toolz/__init__.py +26 -0
  694. ccxt/static_dependencies/toolz/_signatures.py +784 -0
  695. ccxt/static_dependencies/toolz/_version.py +520 -0
  696. ccxt/static_dependencies/toolz/compatibility.py +30 -0
  697. ccxt/static_dependencies/toolz/curried/__init__.py +101 -0
  698. ccxt/static_dependencies/toolz/curried/exceptions.py +22 -0
  699. ccxt/static_dependencies/toolz/curried/operator.py +22 -0
  700. ccxt/static_dependencies/toolz/dicttoolz.py +339 -0
  701. ccxt/static_dependencies/toolz/functoolz.py +1049 -0
  702. ccxt/static_dependencies/toolz/itertoolz.py +1057 -0
  703. ccxt/static_dependencies/toolz/recipes.py +46 -0
  704. ccxt/static_dependencies/toolz/utils.py +9 -0
  705. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  706. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  707. ccxt/tabdeal.py +364 -0
  708. ccxt/test/__init__.py +3 -0
  709. ccxt/test/base/__init__.py +29 -0
  710. ccxt/test/base/test_account.py +26 -0
  711. ccxt/test/base/test_balance.py +56 -0
  712. ccxt/test/base/test_borrow_interest.py +35 -0
  713. ccxt/test/base/test_borrow_rate.py +32 -0
  714. ccxt/test/base/test_calculate_fee.py +51 -0
  715. ccxt/test/base/test_crypto.py +127 -0
  716. ccxt/test/base/test_currency.py +76 -0
  717. ccxt/test/base/test_datetime.py +109 -0
  718. ccxt/test/base/test_decimal_to_precision.py +392 -0
  719. ccxt/test/base/test_deep_extend.py +68 -0
  720. ccxt/test/base/test_deposit_withdrawal.py +50 -0
  721. ccxt/test/base/test_exchange_datetime_functions.py +76 -0
  722. ccxt/test/base/test_funding_rate_history.py +29 -0
  723. ccxt/test/base/test_last_price.py +31 -0
  724. ccxt/test/base/test_ledger_entry.py +45 -0
  725. ccxt/test/base/test_ledger_item.py +48 -0
  726. ccxt/test/base/test_leverage_tier.py +33 -0
  727. ccxt/test/base/test_liquidation.py +50 -0
  728. ccxt/test/base/test_margin_mode.py +24 -0
  729. ccxt/test/base/test_margin_modification.py +35 -0
  730. ccxt/test/base/test_market.py +193 -0
  731. ccxt/test/base/test_number.py +411 -0
  732. ccxt/test/base/test_ohlcv.py +33 -0
  733. ccxt/test/base/test_open_interest.py +32 -0
  734. ccxt/test/base/test_order.py +64 -0
  735. ccxt/test/base/test_order_book.py +69 -0
  736. ccxt/test/base/test_position.py +60 -0
  737. ccxt/test/base/test_shared_methods.py +353 -0
  738. ccxt/test/base/test_status.py +24 -0
  739. ccxt/test/base/test_throttle.py +126 -0
  740. ccxt/test/base/test_ticker.py +92 -0
  741. ccxt/test/base/test_trade.py +47 -0
  742. ccxt/test/base/test_trading_fee.py +26 -0
  743. ccxt/test/base/test_transaction.py +39 -0
  744. ccxt/test/test_async.py +1649 -0
  745. ccxt/test/test_sync.py +1648 -0
  746. ccxt/test/tests_async.py +1558 -0
  747. ccxt/test/tests_helpers.py +287 -0
  748. ccxt/test/tests_init.py +39 -0
  749. ccxt/test/tests_sync.py +1555 -0
  750. ccxt/tetherland.py +349 -0
  751. ccxt/timex.py +1593 -0
  752. ccxt/tokocrypto.py +2405 -0
  753. ccxt/tradeogre.py +608 -0
  754. ccxt/twox.py +326 -0
  755. ccxt/ubitex.py +409 -0
  756. ccxt/upbit.py +1833 -0
  757. ccxt/vertex.py +2922 -0
  758. ccxt/wallex.py +445 -0
  759. ccxt/wavesexchange.py +2472 -0
  760. ccxt/wazirx.py +1224 -0
  761. ccxt/whitebit.py +2469 -0
  762. ccxt/woo.py +3114 -0
  763. ccxt/woofipro.py +2533 -0
  764. ccxt/xt.py +4453 -0
  765. ccxt/yobit.py +1283 -0
  766. ccxt/zaif.py +725 -0
  767. ccxt/zonda.py +1828 -0
  768. ccxt_ir-4.3.46.0.1.dist-info/LICENSE.txt +21 -0
  769. ccxt_ir-4.3.46.0.1.dist-info/METADATA +655 -0
  770. ccxt_ir-4.3.46.0.1.dist-info/RECORD +772 -0
  771. ccxt_ir-4.3.46.0.1.dist-info/WHEEL +6 -0
  772. ccxt_ir-4.3.46.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2683 @@
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.async_support.base.exchange import Exchange
7
+ from ccxt.abstract.lbank import ImplicitAPI
8
+ import asyncio
9
+ import hashlib
10
+ from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction
11
+ from typing import List
12
+ from ccxt.base.errors import ExchangeError
13
+ from ccxt.base.errors import AuthenticationError
14
+ from ccxt.base.errors import PermissionDenied
15
+ from ccxt.base.errors import ArgumentsRequired
16
+ from ccxt.base.errors import BadRequest
17
+ from ccxt.base.errors import BadSymbol
18
+ from ccxt.base.errors import InsufficientFunds
19
+ from ccxt.base.errors import InvalidAddress
20
+ from ccxt.base.errors import InvalidOrder
21
+ from ccxt.base.errors import DuplicateOrderId
22
+ from ccxt.base.errors import NotSupported
23
+ from ccxt.base.errors import RateLimitExceeded
24
+ from ccxt.base.errors import InvalidNonce
25
+ from ccxt.base.decimal_to_precision import TICK_SIZE
26
+ from ccxt.base.precise import Precise
27
+
28
+
29
+ class lbank(Exchange, ImplicitAPI):
30
+
31
+ def describe(self):
32
+ return self.deep_extend(super(lbank, self).describe(), {
33
+ 'id': 'lbank',
34
+ 'name': 'LBank',
35
+ 'countries': ['CN'],
36
+ 'version': 'v2',
37
+ # 50 per second for making and cancelling orders 1000ms / 50 = 20
38
+ # 20 per second for all other requests, cost = 50 / 20 = 2.5
39
+ 'rateLimit': 20,
40
+ 'pro': True,
41
+ 'has': {
42
+ 'CORS': False,
43
+ 'spot': True,
44
+ 'margin': False,
45
+ 'swap': None,
46
+ 'future': False,
47
+ 'option': False,
48
+ 'addMargin': False,
49
+ 'cancelAllOrders': True,
50
+ 'cancelOrder': True,
51
+ 'createMarketBuyOrderWithCost': True,
52
+ 'createMarketOrderWithCost': False,
53
+ 'createMarketSellOrderWithCost': False,
54
+ 'createOrder': True,
55
+ 'createReduceOnlyOrder': False,
56
+ 'createStopLimitOrder': False,
57
+ 'createStopMarketOrder': False,
58
+ 'createStopOrder': False,
59
+ 'fetchBalance': True,
60
+ 'fetchBorrowRateHistories': False,
61
+ 'fetchBorrowRateHistory': False,
62
+ 'fetchClosedOrders': False,
63
+ 'fetchCrossBorrowRate': False,
64
+ 'fetchCrossBorrowRates': False,
65
+ 'fetchDepositAddress': True,
66
+ 'fetchDepositWithdrawFee': 'emulated',
67
+ 'fetchDepositWithdrawFees': True,
68
+ 'fetchFundingHistory': False,
69
+ 'fetchFundingRate': False,
70
+ 'fetchFundingRateHistory': False,
71
+ 'fetchFundingRates': False,
72
+ 'fetchIndexOHLCV': False,
73
+ 'fetchIsolatedBorrowRate': False,
74
+ 'fetchIsolatedBorrowRates': False,
75
+ 'fetchIsolatedPositions': False,
76
+ 'fetchLeverage': False,
77
+ 'fetchLeverageTiers': False,
78
+ 'fetchMarginMode': False,
79
+ 'fetchMarkets': True,
80
+ 'fetchMarkOHLCV': False,
81
+ 'fetchMyTrades': True,
82
+ 'fetchOHLCV': True,
83
+ 'fetchOpenOrders': True,
84
+ 'fetchOrder': True,
85
+ 'fetchOrderBook': True,
86
+ 'fetchOrders': True,
87
+ 'fetchPosition': False,
88
+ 'fetchPositionMode': False,
89
+ 'fetchPositions': False,
90
+ 'fetchPositionsRisk': False,
91
+ 'fetchPremiumIndexOHLCV': False,
92
+ 'fetchTicker': True,
93
+ 'fetchTickers': True,
94
+ 'fetchTime': True,
95
+ 'fetchTrades': True,
96
+ 'fetchTradingFees': True,
97
+ 'fetchTransactionFees': True,
98
+ 'reduceMargin': False,
99
+ 'setLeverage': False,
100
+ 'setMarginMode': False,
101
+ 'setPositionMode': False,
102
+ 'withdraw': True,
103
+ },
104
+ 'timeframes': {
105
+ '1m': 'minute1',
106
+ '5m': 'minute5',
107
+ '15m': 'minute15',
108
+ '30m': 'minute30',
109
+ '1h': 'hour1',
110
+ '2h': 'hour2',
111
+ '4h': 'hour4',
112
+ '6h': 'hour6',
113
+ '8h': 'hour8',
114
+ '12h': 'hour12',
115
+ '1d': 'day1',
116
+ '1w': 'week1',
117
+ },
118
+ 'urls': {
119
+ 'logo': 'https://user-images.githubusercontent.com/1294454/38063602-9605e28a-3302-11e8-81be-64b1e53c4cfb.jpg',
120
+ 'api': {
121
+ 'rest': 'https://api.lbank.info',
122
+ 'contract': 'https://lbkperp.lbank.com',
123
+ },
124
+ 'api2': 'https://api.lbkex.com',
125
+ 'www': 'https://www.lbank.com',
126
+ 'doc': 'https://www.lbank.com/en-US/docs/index.html',
127
+ 'fees': 'https://support.lbank.site/hc/en-gb/articles/900000535703-Trading-Fees-From-14-00-on-April-7-2020-UTC-8-',
128
+ 'referral': 'https://www.lbank.com/login/?icode=7QCY',
129
+ },
130
+ 'api': {
131
+ 'spot': {
132
+ 'public': {
133
+ 'get': {
134
+ 'currencyPairs': 2.5,
135
+ 'accuracy': 2.5,
136
+ 'usdToCny': 2.5,
137
+ 'withdrawConfigs': 2.5,
138
+ 'timestamp': 2.5,
139
+ 'ticker/24hr': 2.5,
140
+ 'ticker': 2.5,
141
+ 'depth': 2.5,
142
+ 'incrDepth': 2.5,
143
+ 'trades': 2.5,
144
+ 'kline': 2.5,
145
+ # new quote endpoints
146
+ 'supplement/system_ping': 2.5,
147
+ 'supplement/incrDepth': 2.5,
148
+ 'supplement/trades': 2.5,
149
+ 'supplement/ticker/price': 2.5,
150
+ 'supplement/ticker/bookTicker': 2.5,
151
+ },
152
+ 'post': {
153
+ 'supplement/system_status': 2.5,
154
+ },
155
+ },
156
+ 'private': {
157
+ 'post': {
158
+ # account
159
+ 'user_info': 2.5,
160
+ 'subscribe/get_key': 2.5,
161
+ 'subscribe/refresh_key': 2.5,
162
+ 'subscribe/destroy_key': 2.5,
163
+ 'get_deposit_address': 2.5,
164
+ 'deposit_history': 2.5,
165
+ # order
166
+ 'create_order': 1,
167
+ 'batch_create_order': 1,
168
+ 'cancel_order': 1,
169
+ 'cancel_clientOrders': 1,
170
+ 'orders_info': 2.5,
171
+ 'orders_info_history': 2.5,
172
+ 'order_transaction_detail': 2.5,
173
+ 'transaction_history': 2.5,
174
+ 'orders_info_no_deal': 2.5,
175
+ # withdraw
176
+ 'withdraw': 2.5,
177
+ 'withdrawCancel': 2.5,
178
+ 'withdraws': 2.5,
179
+ 'supplement/user_info': 2.5,
180
+ 'supplement/withdraw': 2.5,
181
+ 'supplement/deposit_history': 2.5,
182
+ 'supplement/withdraws': 2.5,
183
+ 'supplement/get_deposit_address': 2.5,
184
+ 'supplement/asset_detail': 2.5,
185
+ 'supplement/customer_trade_fee': 2.5,
186
+ 'supplement/api_Restrictions': 2.5,
187
+ # new quote endpoints
188
+ 'supplement/system_ping': 2.5,
189
+ # new order endpoints
190
+ 'supplement/create_order_test': 1,
191
+ 'supplement/create_order': 1,
192
+ 'supplement/cancel_order': 1,
193
+ 'supplement/cancel_order_by_symbol': 1,
194
+ 'supplement/orders_info': 2.5,
195
+ 'supplement/orders_info_no_deal': 2.5,
196
+ 'supplement/orders_info_history': 2.5,
197
+ 'supplement/user_info_account': 2.5,
198
+ 'supplement/transaction_history': 2.5,
199
+ },
200
+ },
201
+ },
202
+ 'contract': {
203
+ 'public': {
204
+ 'get': {
205
+ 'cfd/openApi/v1/pub/getTime': 2.5,
206
+ 'cfd/openApi/v1/pub/instrument': 2.5,
207
+ 'cfd/openApi/v1/pub/marketData': 2.5,
208
+ 'cfd/openApi/v1/pub/marketOrder': 2.5,
209
+ },
210
+ },
211
+ },
212
+ },
213
+ 'fees': {
214
+ 'trading': {
215
+ 'maker': self.parse_number('0.001'),
216
+ 'taker': self.parse_number('0.001'),
217
+ },
218
+ 'funding': {
219
+ 'withdraw': {},
220
+ },
221
+ },
222
+ 'commonCurrencies': {
223
+ 'VET_ERC20': 'VEN',
224
+ 'PNT': 'Penta',
225
+ },
226
+ 'precisionMode': TICK_SIZE,
227
+ 'options': {
228
+ 'cacheSecretAsPem': True,
229
+ 'createMarketBuyOrderRequiresPrice': True,
230
+ 'fetchTrades': {
231
+ 'method': 'spotPublicGetTrades', # or 'spotPublicGetTradesSupplement'
232
+ },
233
+ 'fetchTransactionFees': { # DEPRECATED, please use fetchDepositWithdrawFees
234
+ 'method': 'fetchPrivateTransactionFees', # or 'fetchPublicTransactionFees'
235
+ },
236
+ 'fetchDepositWithdrawFees': {
237
+ 'method': 'fetchPrivateDepositWithdrawFees', # or 'fetchPublicDepositWithdrawFees'
238
+ },
239
+ 'fetchDepositAddress': {
240
+ 'method': 'fetchDepositAddressDefault', # or fetchDepositAddressSupplement
241
+ },
242
+ 'createOrder': {
243
+ 'method': 'spotPrivatePostSupplementCreateOrder', # or spotPrivatePostCreateOrder
244
+ },
245
+ 'fetchOrder': {
246
+ 'method': 'fetchOrderSupplement', # or fetchOrderDefault
247
+ },
248
+ 'fetchBalance': {
249
+ 'method': 'spotPrivatePostSupplementUserInfo', # or spotPrivatePostSupplementUserInfoAccount or spotPrivatePostUserInfo
250
+ },
251
+ 'networks': {
252
+ 'ERC20': 'erc20',
253
+ 'ETH': 'erc20',
254
+ 'TRC20': 'trc20',
255
+ 'TRX': 'trc20',
256
+ 'OMNI': 'omni',
257
+ 'ASA': 'asa',
258
+ 'BEP20': 'bep20(bsc)',
259
+ 'BSC': 'bep20(bsc)',
260
+ 'HT': 'heco',
261
+ 'BNB': 'bep2',
262
+ 'BTC': 'btc',
263
+ 'DOGE': 'dogecoin',
264
+ 'MATIC': 'matic',
265
+ 'POLYGON': 'matic',
266
+ 'OEC': 'oec',
267
+ 'BTCTRON': 'btctron',
268
+ 'XRP': 'xrp',
269
+ # other unusual chains with number of listed currencies supported
270
+ # 'avax c-chain': 1,
271
+ # klay: 12,
272
+ # bta: 1,
273
+ # fantom: 1,
274
+ # celo: 1,
275
+ # sol: 2,
276
+ # zenith: 1,
277
+ # ftm: 5,
278
+ # bep20: 1,(single token with mis-named chain) SSS
279
+ # bitci: 1,
280
+ # sgb: 1,
281
+ # moonbeam: 1,
282
+ # ekta: 1,
283
+ # etl: 1,
284
+ # arbitrum: 1,
285
+ # tpc: 1,
286
+ # ptx: 1
287
+ # }
288
+ },
289
+ 'inverse-networks': {
290
+ 'erc20': 'ERC20',
291
+ 'trc20': 'TRC20',
292
+ 'omni': 'OMNI',
293
+ 'asa': 'ASA',
294
+ 'bep20(bsc)': 'BSC',
295
+ 'bep20': 'BSC',
296
+ 'heco': 'HT',
297
+ 'bep2': 'BNB',
298
+ 'btc': 'BTC',
299
+ 'dogecoin': 'DOGE',
300
+ 'matic': 'MATIC',
301
+ 'oec': 'OEC',
302
+ 'btctron': 'BTCTRON',
303
+ 'xrp': 'XRP',
304
+ },
305
+ 'defaultNetworks': {
306
+ 'USDT': 'TRC20',
307
+ },
308
+ },
309
+ })
310
+
311
+ async def fetch_time(self, params={}):
312
+ """
313
+ fetches the current integer timestamp in milliseconds from the exchange server
314
+ :see: https://www.lbank.com/en-US/docs/index.html#get-timestamp
315
+ :see: https://www.lbank.com/en-US/docs/contract.html#get-the-current-time
316
+ :param dict [params]: extra parameters specific to the exchange API endpoint
317
+ :returns int: the current integer timestamp in milliseconds from the exchange server
318
+ """
319
+ type = None
320
+ type, params = self.handle_market_type_and_params('fetchTime', None, params)
321
+ response = None
322
+ if type == 'swap':
323
+ response = await self.contractPublicGetCfdOpenApiV1PubGetTime(params)
324
+ else:
325
+ response = await self.spotPublicGetTimestamp(params)
326
+ #
327
+ # spot
328
+ #
329
+ # {
330
+ # "result": "true",
331
+ # "data": 1691789627950,
332
+ # "error_code": 0,
333
+ # "ts": 1691789627950
334
+ # }
335
+ #
336
+ # swap
337
+ #
338
+ # {
339
+ # "data": 1691789627950,
340
+ # "error_code": 0,
341
+ # "msg": "Success",
342
+ # "result": "true",
343
+ # "success": True
344
+ # }
345
+ #
346
+ return self.safe_integer(response, 'data')
347
+
348
+ async def fetch_markets(self, params={}) -> List[Market]:
349
+ """
350
+ retrieves data on all markets for lbank
351
+ :see: https://www.lbank.com/en-US/docs/index.html#trading-pairs
352
+ :see: https://www.lbank.com/en-US/docs/contract.html#query-contract-information-list
353
+ :param dict [params]: extra parameters specific to the exchange API endpoint
354
+ :returns dict[]: an array of objects representing market data
355
+ """
356
+ marketsPromises = [
357
+ self.fetch_spot_markets(params),
358
+ self.fetch_swap_markets(params),
359
+ ]
360
+ resolvedMarkets = await asyncio.gather(*marketsPromises)
361
+ return self.array_concat(resolvedMarkets[0], resolvedMarkets[1])
362
+
363
+ async def fetch_spot_markets(self, params={}):
364
+ response = await self.spotPublicGetAccuracy(params)
365
+ #
366
+ # {
367
+ # "result": "true",
368
+ # "data": [
369
+ # {
370
+ # "symbol": "btc_usdt",
371
+ # "quantityAccuracy": "4",
372
+ # "minTranQua": "0.0001",
373
+ # "priceAccuracy": "2"
374
+ # },
375
+ # ],
376
+ # "error_code": 0,
377
+ # "ts": 1691560288484
378
+ # }
379
+ #
380
+ data = self.safe_value(response, 'data', [])
381
+ result = []
382
+ for i in range(0, len(data)):
383
+ market = data[i]
384
+ marketId = self.safe_string(market, 'symbol')
385
+ parts = marketId.split('_')
386
+ baseId = parts[0]
387
+ quoteId = parts[1]
388
+ base = self.safe_currency_code(baseId)
389
+ quote = self.safe_currency_code(quoteId)
390
+ symbol = base + '/' + quote
391
+ result.append({
392
+ 'id': marketId,
393
+ 'symbol': symbol,
394
+ 'base': base,
395
+ 'quote': quote,
396
+ 'baseId': baseId,
397
+ 'quoteId': quoteId,
398
+ 'settle': None,
399
+ 'settleId': None,
400
+ 'type': 'spot',
401
+ 'spot': True,
402
+ 'margin': False,
403
+ 'swap': False,
404
+ 'future': False,
405
+ 'option': False,
406
+ 'active': True,
407
+ 'contract': False,
408
+ 'linear': None,
409
+ 'inverse': None,
410
+ 'contractSize': None,
411
+ 'expiry': None,
412
+ 'expiryDatetime': None,
413
+ 'strike': None,
414
+ 'optionType': None,
415
+ 'precision': {
416
+ 'amount': self.parse_number(self.parse_precision(self.safe_string(market, 'quantityAccuracy'))),
417
+ 'price': self.parse_number(self.parse_precision(self.safe_string(market, 'priceAccuracy'))),
418
+ },
419
+ 'limits': {
420
+ 'leverage': {
421
+ 'min': None,
422
+ 'max': None,
423
+ },
424
+ 'amount': {
425
+ 'min': self.safe_number(market, 'minTranQua'),
426
+ 'max': None,
427
+ },
428
+ 'price': {
429
+ 'min': None,
430
+ 'max': None,
431
+ },
432
+ 'cost': {
433
+ 'min': None,
434
+ 'max': None,
435
+ },
436
+ },
437
+ 'created': None,
438
+ 'info': market,
439
+ })
440
+ return result
441
+
442
+ async def fetch_swap_markets(self, params={}):
443
+ request: dict = {
444
+ 'productGroup': 'SwapU',
445
+ }
446
+ response = await self.contractPublicGetCfdOpenApiV1PubInstrument(self.extend(request, params))
447
+ #
448
+ # {
449
+ # "data": [
450
+ # {
451
+ # "priceLimitUpperValue": 0.2,
452
+ # "symbol": "BTCUSDT",
453
+ # "volumeTick": 0.0001,
454
+ # "indexPrice": "29707.70200000",
455
+ # "minOrderVolume": "0.0001",
456
+ # "priceTick": 0.1,
457
+ # "maxOrderVolume": "30.0",
458
+ # "baseCurrency": "BTC",
459
+ # "volumeMultiple": 1.0,
460
+ # "exchangeID": "Exchange",
461
+ # "priceCurrency": "USDT",
462
+ # "priceLimitLowerValue": 0.2,
463
+ # "clearCurrency": "USDT",
464
+ # "symbolName": "BTCUSDT",
465
+ # "defaultLeverage": 20.0,
466
+ # "minOrderCost": "5.0"
467
+ # },
468
+ # ],
469
+ # "error_code": 0,
470
+ # "msg": "Success",
471
+ # "result": "true",
472
+ # "success": True
473
+ # }
474
+ #
475
+ data = self.safe_value(response, 'data', [])
476
+ result = []
477
+ for i in range(0, len(data)):
478
+ market = data[i]
479
+ marketId = self.safe_string(market, 'symbol')
480
+ baseId = self.safe_string(market, 'baseCurrency')
481
+ settleId = self.safe_string(market, 'clearCurrency')
482
+ quoteId = settleId
483
+ base = self.safe_currency_code(baseId)
484
+ quote = self.safe_currency_code(quoteId)
485
+ settle = self.safe_currency_code(settleId)
486
+ symbol = base + '/' + quote + ':' + settle
487
+ result.append({
488
+ 'id': marketId,
489
+ 'symbol': symbol,
490
+ 'base': base,
491
+ 'quote': quote,
492
+ 'settle': settle,
493
+ 'baseId': baseId,
494
+ 'quoteId': quoteId,
495
+ 'settleId': settleId,
496
+ 'type': 'swap',
497
+ 'spot': False,
498
+ 'margin': False,
499
+ 'swap': True,
500
+ 'future': False,
501
+ 'option': False,
502
+ 'active': True,
503
+ 'contract': True,
504
+ 'linear': True,
505
+ 'inverse': None,
506
+ 'contractSize': self.safe_number(market, 'volumeMultiple'),
507
+ 'expiry': None,
508
+ 'expiryDatetime': None,
509
+ 'strike': None,
510
+ 'optionType': None,
511
+ 'precision': {
512
+ 'amount': self.safe_number(market, 'volumeTick'),
513
+ 'price': self.safe_number(market, 'priceTick'),
514
+ },
515
+ 'limits': {
516
+ 'leverage': {
517
+ 'min': None,
518
+ 'max': None,
519
+ },
520
+ 'amount': {
521
+ 'min': self.safe_number(market, 'minOrderVolume'),
522
+ 'max': self.safe_number(market, 'maxOrderVolume'),
523
+ },
524
+ 'price': {
525
+ 'min': self.safe_number(market, 'priceLimitLowerValue'),
526
+ 'max': self.safe_number(market, 'priceLimitUpperValue'),
527
+ },
528
+ 'cost': {
529
+ 'min': self.safe_number(market, 'minOrderCost'),
530
+ 'max': None,
531
+ },
532
+ },
533
+ 'created': None,
534
+ 'info': market,
535
+ })
536
+ return result
537
+
538
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
539
+ #
540
+ # spot: fetchTicker, fetchTickers
541
+ #
542
+ # {
543
+ # "symbol": "btc_usdt",
544
+ # "ticker": {
545
+ # "high": "29695.57",
546
+ # "vol": "6890.2789",
547
+ # "low": "29110",
548
+ # "change": "0.58",
549
+ # "turnover": "202769821.06",
550
+ # "latest": "29405.98"
551
+ # },
552
+ # "timestamp": :1692064274908
553
+ # }
554
+ #
555
+ # swap: fetchTickers
556
+ #
557
+ # {
558
+ # "prePositionFeeRate": "0.000053",
559
+ # "volume": "2435.459",
560
+ # "symbol": "BTCUSDT",
561
+ # "highestPrice": "29446.5",
562
+ # "lowestPrice": "29362.9",
563
+ # "openPrice": "29419.5",
564
+ # "markedPrice": "29385.1",
565
+ # "turnover": "36345526.2438402",
566
+ # "lastPrice": "29387.0"
567
+ # }
568
+ #
569
+ timestamp = self.safe_integer(ticker, 'timestamp')
570
+ marketId = self.safe_string(ticker, 'symbol')
571
+ symbol = self.safe_symbol(marketId, market)
572
+ tickerData = self.safe_value(ticker, 'ticker', {})
573
+ market = self.safe_market(marketId, market)
574
+ data = ticker if (market['contract']) else tickerData
575
+ return self.safe_ticker({
576
+ 'symbol': symbol,
577
+ 'timestamp': timestamp,
578
+ 'datetime': self.iso8601(timestamp),
579
+ 'high': self.safe_string_2(data, 'high', 'highestPrice'),
580
+ 'low': self.safe_string_2(data, 'low', 'lowestPrice'),
581
+ 'bid': None,
582
+ 'bidVolume': None,
583
+ 'ask': None,
584
+ 'askVolume': None,
585
+ 'vwap': None,
586
+ 'open': self.safe_string(data, 'openPrice'),
587
+ 'close': None,
588
+ 'last': self.safe_string_2(data, 'latest', 'lastPrice'),
589
+ 'previousClose': None,
590
+ 'change': None,
591
+ 'percentage': self.safe_string(data, 'change'),
592
+ 'average': None,
593
+ 'baseVolume': self.safe_string_2(data, 'vol', 'volume'),
594
+ 'quoteVolume': self.safe_string(data, 'turnover'),
595
+ 'info': ticker,
596
+ }, market)
597
+
598
+ async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
599
+ """
600
+ fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
601
+ :see: https://www.lbank.com/en-US/docs/index.html#query-current-market-data-new
602
+ :param str symbol: unified symbol of the market to fetch the ticker for
603
+ :param dict [params]: extra parameters specific to the exchange API endpoint
604
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
605
+ """
606
+ await self.load_markets()
607
+ market = self.market(symbol)
608
+ if market['swap']:
609
+ responseForSwap = await self.fetch_tickers([market['symbol']], params)
610
+ return self.safe_value(responseForSwap, market['symbol'])
611
+ request: dict = {
612
+ 'symbol': market['id'],
613
+ }
614
+ response = await self.spotPublicGetTicker24hr(self.extend(request, params))
615
+ #
616
+ # {
617
+ # "result": "true",
618
+ # "data": [
619
+ # {
620
+ # "symbol": "btc_usdt",
621
+ # "ticker": {
622
+ # "high": "29695.57",
623
+ # "vol": "6890.2789",
624
+ # "low": "29110",
625
+ # "change": "0.58",
626
+ # "turnover": "202769821.06",
627
+ # "latest": "29405.98"
628
+ # },
629
+ # "timestamp": :1692064274908
630
+ # }
631
+ # ],
632
+ # "error_code": 0,
633
+ # "ts": :1692064276872
634
+ # }
635
+ #
636
+ data = self.safe_value(response, 'data', [])
637
+ first = self.safe_dict(data, 0, {})
638
+ return self.parse_ticker(first, market)
639
+
640
+ async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
641
+ """
642
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
643
+ :see: https://www.lbank.com/en-US/docs/index.html#query-current-market-data-new
644
+ :see: https://www.lbank.com/en-US/docs/contract.html#query-contract-market-list
645
+ :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
646
+ :param dict [params]: extra parameters specific to the exchange API endpoint
647
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
648
+ """
649
+ await self.load_markets()
650
+ market = None
651
+ if symbols is not None:
652
+ symbols = self.market_symbols(symbols)
653
+ symbolsLength = len(symbols)
654
+ if symbolsLength > 0:
655
+ market = self.market(symbols[0])
656
+ request: dict = {}
657
+ type = None
658
+ type, params = self.handle_market_type_and_params('fetchTickers', market, params)
659
+ response = None
660
+ if type == 'swap':
661
+ request['productGroup'] = 'SwapU'
662
+ response = await self.contractPublicGetCfdOpenApiV1PubMarketData(self.extend(request, params))
663
+ else:
664
+ request['symbol'] = 'all'
665
+ response = await self.spotPublicGetTicker24hr(self.extend(request, params))
666
+ #
667
+ # spot
668
+ #
669
+ # {
670
+ # "result": "true",
671
+ # "data": [
672
+ # {
673
+ # "symbol": "btc_usdt",
674
+ # "ticker": {
675
+ # "high": "29695.57",
676
+ # "vol": "6890.2789",
677
+ # "low": "29110",
678
+ # "change": "0.58",
679
+ # "turnover": "202769821.06",
680
+ # "latest": "29405.98"
681
+ # },
682
+ # "timestamp": :1692064274908
683
+ # }
684
+ # ],
685
+ # "error_code": 0,
686
+ # "ts": :1692064276872
687
+ # }
688
+ #
689
+ # swap
690
+ #
691
+ # {
692
+ # "data": [
693
+ # {
694
+ # "prePositionFeeRate": "0.000053",
695
+ # "volume": "2435.459",
696
+ # "symbol": "BTCUSDT",
697
+ # "highestPrice": "29446.5",
698
+ # "lowestPrice": "29362.9",
699
+ # "openPrice": "29419.5",
700
+ # "markedPrice": "29385.1",
701
+ # "turnover": "36345526.2438402",
702
+ # "lastPrice": "29387.0"
703
+ # },
704
+ # ],
705
+ # "error_code": 0,
706
+ # "msg": "Success",
707
+ # "result": "true",
708
+ # "success": True
709
+ # }
710
+ #
711
+ data = self.safe_list(response, 'data', [])
712
+ return self.parse_tickers(data, symbols)
713
+
714
+ async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
715
+ """
716
+ fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
717
+ :see: https://www.lbank.com/en-US/docs/index.html#query-market-depth
718
+ :see: https://www.lbank.com/en-US/docs/contract.html#get-handicap
719
+ :param str symbol: unified symbol of the market to fetch the order book for
720
+ :param int [limit]: the maximum amount of order book entries to return
721
+ :param dict [params]: extra parameters specific to the exchange API endpoint
722
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
723
+ """
724
+ await self.load_markets()
725
+ market = self.market(symbol)
726
+ if limit is None:
727
+ limit = 60
728
+ request: dict = {
729
+ 'symbol': market['id'],
730
+ }
731
+ type = None
732
+ type, params = self.handle_market_type_and_params('fetchOrderBook', market, params)
733
+ response = None
734
+ if type == 'swap':
735
+ request['depth'] = limit
736
+ response = await self.contractPublicGetCfdOpenApiV1PubMarketOrder(self.extend(request, params))
737
+ else:
738
+ request['size'] = limit
739
+ response = await self.spotPublicGetDepth(self.extend(request, params))
740
+ #
741
+ # spot
742
+ #
743
+ # {
744
+ # "result": "true",
745
+ # "data": {
746
+ # "asks": [
747
+ # ["29243.37", "2.8783"],
748
+ # ["29243.39", "2.2842"],
749
+ # ["29243.4", "0.0337"]
750
+ # ],
751
+ # "bids": [
752
+ # ["29243.36", "1.5258"],
753
+ # ["29243.34", "0.8218"],
754
+ # ["29243.28", "1.285"]
755
+ # ],
756
+ # "timestamp": :1692157328820
757
+ # },
758
+ # "error_code": 0,
759
+ # "ts": :1692157328820
760
+ # }
761
+ #
762
+ # swap
763
+ #
764
+ # {
765
+ # "data": {
766
+ # "symbol": "BTCUSDT",
767
+ # "asks": [
768
+ # {
769
+ # "volume": "14.6535",
770
+ # "price": "29234.2",
771
+ # "orders": "1"
772
+ # },
773
+ # ],
774
+ # "bids": [
775
+ # {
776
+ # "volume": "13.4899",
777
+ # "price": "29234.1",
778
+ # "orders": "4"
779
+ # },
780
+ # ]
781
+ # },
782
+ # "error_code": 0,
783
+ # "msg": "Success",
784
+ # "result": "true",
785
+ # "success": True
786
+ # }
787
+ #
788
+ orderbook = self.safe_value(response, 'data', {})
789
+ timestamp = self.milliseconds()
790
+ if market['swap']:
791
+ return self.parse_order_book(orderbook, market['symbol'], timestamp, 'bids', 'asks', 'price', 'volume')
792
+ return self.parse_order_book(orderbook, market['symbol'], timestamp)
793
+
794
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
795
+ #
796
+ # fetchTrades(old) spotPublicGetTrades
797
+ #
798
+ # {
799
+ # "date_ms":1647021989789,
800
+ # "amount":0.0028,
801
+ # "price":38804.2,
802
+ # "type":"buy",
803
+ # "tid":"52d5616ee35c43019edddebe59b3e094"
804
+ # }
805
+ #
806
+ #
807
+ # fetchTrades(new) spotPublicGetTradesSupplement
808
+ #
809
+ # {
810
+ # "quoteQty":1675.048485,
811
+ # "price":0.127545,
812
+ # "qty":13133,
813
+ # "id":"3589541dc22e4357b227283650f714e2",
814
+ # "time":1648058297110,
815
+ # "isBuyerMaker":false
816
+ # }
817
+ #
818
+ # fetchMyTrades(private)
819
+ #
820
+ # {
821
+ # "orderUuid":"38b4e7a4-14f6-45fd-aba1-1a37024124a0",
822
+ # "tradeFeeRate":0.0010000000,
823
+ # "dealTime":1648500944496,
824
+ # "dealQuantity":30.00000000000000000000,
825
+ # "tradeFee":0.00453300000000000000,
826
+ # "txUuid":"11f3850cc6214ea3b495adad3a032794",
827
+ # "dealPrice":0.15111300000000000000,
828
+ # "dealVolumePrice":4.53339000000000000000,
829
+ # "tradeType":"sell_market"
830
+ # }
831
+ #
832
+ timestamp = self.safe_integer_2(trade, 'date_ms', 'time')
833
+ if timestamp is None:
834
+ timestamp = self.safe_integer(trade, 'dealTime')
835
+ amountString = self.safe_string_2(trade, 'amount', 'qty')
836
+ if amountString is None:
837
+ amountString = self.safe_string(trade, 'dealQuantity')
838
+ priceString = self.safe_string(trade, 'price')
839
+ if priceString is None:
840
+ priceString = self.safe_string(trade, 'dealPrice')
841
+ costString = self.safe_string(trade, 'quoteQty')
842
+ if costString is None:
843
+ costString = self.safe_string(trade, 'dealVolumePrice')
844
+ side = self.safe_string_2(trade, 'tradeType', 'type')
845
+ type = None
846
+ takerOrMaker = None
847
+ if side is not None:
848
+ parts = side.split('_')
849
+ side = self.safe_string(parts, 0)
850
+ typePart = self.safe_string(parts, 1)
851
+ type = 'limit'
852
+ takerOrMaker = 'taker'
853
+ if typePart is not None:
854
+ if typePart == 'market':
855
+ type = 'market'
856
+ elif typePart == 'maker':
857
+ takerOrMaker = 'maker'
858
+ id = self.safe_string_2(trade, 'tid', 'id')
859
+ if id is None:
860
+ id = self.safe_string(trade, 'txUuid')
861
+ order = self.safe_string(trade, 'orderUuid')
862
+ symbol = self.safe_symbol(None, market)
863
+ fee = None
864
+ feeCost = self.safe_string(trade, 'tradeFee')
865
+ if feeCost is not None:
866
+ fee = {
867
+ 'cost': feeCost,
868
+ 'currency': market['base'] if (side == 'buy') else market['quote'],
869
+ 'rate': self.safe_string(trade, 'tradeFeeRate'),
870
+ }
871
+ return self.safe_trade({
872
+ 'timestamp': timestamp,
873
+ 'datetime': self.iso8601(timestamp),
874
+ 'symbol': symbol,
875
+ 'id': id,
876
+ 'order': order,
877
+ 'type': type,
878
+ 'takerOrMaker': takerOrMaker,
879
+ 'side': side,
880
+ 'price': priceString,
881
+ 'amount': amountString,
882
+ 'cost': costString,
883
+ 'fee': fee,
884
+ 'info': trade,
885
+ }, market)
886
+
887
+ async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
888
+ """
889
+ get the list of most recent trades for a particular symbol
890
+ :see: https://www.lbank.com/en-US/docs/index.html#query-historical-transactions
891
+ :see: https://www.lbank.com/en-US/docs/index.html#recent-transactions-list
892
+ :param str symbol: unified symbol of the market to fetch trades for
893
+ :param int [since]: timestamp in ms of the earliest trade to fetch
894
+ :param int [limit]: the maximum amount of trades to fetch
895
+ :param dict [params]: extra parameters specific to the exchange API endpoint
896
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
897
+ """
898
+ await self.load_markets()
899
+ market = self.market(symbol)
900
+ request: dict = {
901
+ 'symbol': market['id'],
902
+ }
903
+ if since is not None:
904
+ request['time'] = since
905
+ if limit is not None:
906
+ request['size'] = min(limit, 600)
907
+ else:
908
+ request['size'] = 600 # max
909
+ options = self.safe_value(self.options, 'fetchTrades', {})
910
+ defaultMethod = self.safe_string(options, 'method', 'spotPublicGetTrades')
911
+ method = self.safe_string(params, 'method', defaultMethod)
912
+ params = self.omit(params, 'method')
913
+ response = None
914
+ if method == 'spotPublicGetSupplementTrades':
915
+ response = await self.spotPublicGetSupplementTrades(self.extend(request, params))
916
+ else:
917
+ response = await self.spotPublicGetTrades(self.extend(request, params))
918
+ #
919
+ # {
920
+ # "result":"true",
921
+ # "data": [
922
+ # {
923
+ # "date_ms":1647021989789,
924
+ # "amount":0.0028,
925
+ # "price":38804.2,
926
+ # "type":"buy",
927
+ # "tid":"52d5616ee35c43019edddebe59b3e094"
928
+ # }
929
+ # ],
930
+ # "error_code":0,
931
+ # "ts":1647021999308
932
+ # }
933
+ #
934
+ trades = self.safe_list(response, 'data', [])
935
+ return self.parse_trades(trades, market, since, limit)
936
+
937
+ def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
938
+ #
939
+ # [
940
+ # 1482311500, # timestamp
941
+ # 5423.23, # open
942
+ # 5472.80, # high
943
+ # 5516.09, # low
944
+ # 5462, # close
945
+ # 234.3250 # volume
946
+ # ],
947
+ #
948
+ return [
949
+ self.safe_timestamp(ohlcv, 0), # timestamp
950
+ self.safe_number(ohlcv, 1), # open
951
+ self.safe_number(ohlcv, 2), # high
952
+ self.safe_number(ohlcv, 3), # low
953
+ self.safe_number(ohlcv, 4), # close
954
+ self.safe_number(ohlcv, 5), # volume
955
+ ]
956
+
957
+ async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
958
+ """
959
+ fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
960
+ :see: https://www.lbank.com/en-US/docs/index.html#query-k-bar-data
961
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
962
+ :param str timeframe: the length of time each candle represents
963
+ :param int [since]: timestamp in ms of the earliest candle to fetch
964
+ :param int [limit]: the maximum amount of candles to fetch
965
+ :param dict [params]: extra parameters specific to the exchange API endpoint
966
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
967
+ """
968
+ # endpoint doesnt work
969
+ await self.load_markets()
970
+ market = self.market(symbol)
971
+ if limit is None:
972
+ limit = 100
973
+ else:
974
+ limit = min(limit, 2000)
975
+ if since is None:
976
+ duration = self.parse_timeframe(timeframe)
977
+ since = self.milliseconds() - duration * 1000 * limit
978
+ request: dict = {
979
+ 'symbol': market['id'],
980
+ 'type': self.safe_string(self.timeframes, timeframe, timeframe),
981
+ 'time': self.parse_to_int(since / 1000),
982
+ 'size': limit, # max 2000
983
+ }
984
+ response = await self.spotPublicGetKline(self.extend(request, params))
985
+ ohlcvs = self.safe_value(response, 'data', [])
986
+ #
987
+ #
988
+ # [
989
+ # [
990
+ # 1482311500,
991
+ # 5423.23,
992
+ # 5472.80,
993
+ # 5516.09,
994
+ # 5462,
995
+ # 234.3250
996
+ # ],
997
+ # [
998
+ # 1482311400,
999
+ # 5432.52,
1000
+ # 5459.87,
1001
+ # 5414.30,
1002
+ # 5428.23,
1003
+ # 213.7329
1004
+ # ]
1005
+ # ]
1006
+ #
1007
+ return self.parse_ohlcvs(ohlcvs, market, timeframe, since, limit)
1008
+
1009
+ def parse_balance(self, response) -> Balances:
1010
+ #
1011
+ # spotPrivatePostUserInfo
1012
+ #
1013
+ # {
1014
+ # "toBtc": {
1015
+ # "egc:": "0",
1016
+ # "iog": "0",
1017
+ # "ksm": "0",
1018
+ # },
1019
+ # "freeze": {
1020
+ # "egc": "0",
1021
+ # "iog": "0",
1022
+ # "ksm": "0" ,
1023
+ # },
1024
+ # "asset": {
1025
+ # "egc": "0",
1026
+ # "iog": "0",
1027
+ # "ksm": "0",
1028
+ # },
1029
+ # "free": {
1030
+ # "egc": "0",
1031
+ # "iog": "0",
1032
+ # "ksm": "0",
1033
+ # }
1034
+ # }
1035
+ #
1036
+ # spotPrivatePostSupplementUserInfoAccount
1037
+ #
1038
+ # {
1039
+ # "balances":[
1040
+ # {
1041
+ # "asset":"lbk",
1042
+ # "free":"0",
1043
+ # "locked":"0"
1044
+ # }, ...
1045
+ # ]
1046
+ # }
1047
+ #
1048
+ # spotPrivatePostSupplementUserInfo
1049
+ #
1050
+ # [
1051
+ # {
1052
+ # "usableAmt":"31.45130723",
1053
+ # "assetAmt":"31.45130723",
1054
+ # "networkList":[
1055
+ # {
1056
+ # "isDefault":true,
1057
+ # "withdrawFeeRate":"",
1058
+ # "name":"bep20(bsc)",
1059
+ # "withdrawMin":30,
1060
+ # "minLimit":0.0001,
1061
+ # "minDeposit":0.0001,
1062
+ # "feeAssetCode":"doge",
1063
+ # "withdrawFee":"30",
1064
+ # "type":1,
1065
+ # "coin":"doge",
1066
+ # "network":"bsc"
1067
+ # },
1068
+ # {
1069
+ # "isDefault":false,
1070
+ # "withdrawFeeRate":"",
1071
+ # "name":"dogecoin",
1072
+ # "withdrawMin":10,
1073
+ # "minLimit":0.0001,
1074
+ # "minDeposit":10,
1075
+ # "feeAssetCode":"doge",
1076
+ # "withdrawFee":"10",
1077
+ # "type":1,
1078
+ # "coin":"doge",
1079
+ # "network":"dogecoin"
1080
+ # }
1081
+ # ],
1082
+ # "freezeAmt":"0",
1083
+ # "coin":"doge"
1084
+ # }, ...
1085
+ # ]
1086
+ #
1087
+ timestamp = self.safe_integer(response, 'ts')
1088
+ result: dict = {
1089
+ 'info': response,
1090
+ 'timestamp': timestamp,
1091
+ 'datetime': self.iso8601(timestamp),
1092
+ }
1093
+ data = self.safe_value(response, 'data')
1094
+ # from spotPrivatePostUserInfo
1095
+ toBtc = self.safe_value(data, 'toBtc')
1096
+ if toBtc is not None:
1097
+ used = self.safe_value(data, 'freeze', {})
1098
+ free = self.safe_value(data, 'free', {})
1099
+ currencies = list(free.keys())
1100
+ for i in range(0, len(currencies)):
1101
+ currencyId = currencies[i]
1102
+ code = self.safe_currency_code(currencyId)
1103
+ account = self.account()
1104
+ account['used'] = self.safe_string(used, currencyId)
1105
+ account['free'] = self.safe_string(free, currencyId)
1106
+ result[code] = account
1107
+ return self.safe_balance(result)
1108
+ # from spotPrivatePostSupplementUserInfoAccount
1109
+ balances = self.safe_value(data, 'balances')
1110
+ if balances is not None:
1111
+ for i in range(0, len(balances)):
1112
+ item = balances[i]
1113
+ currencyId = self.safe_string(item, 'asset')
1114
+ codeInner = self.safe_currency_code(currencyId)
1115
+ account = self.account()
1116
+ account['free'] = self.safe_string(item, 'free')
1117
+ account['used'] = self.safe_string(item, 'locked')
1118
+ result[codeInner] = account
1119
+ return self.safe_balance(result)
1120
+ # from spotPrivatePostSupplementUserInfo
1121
+ isArray = isinstance(data, list)
1122
+ if isArray is True:
1123
+ for i in range(0, len(data)):
1124
+ item = data[i]
1125
+ currencyId = self.safe_string(item, 'coin')
1126
+ codeInner = self.safe_currency_code(currencyId)
1127
+ account = self.account()
1128
+ account['free'] = self.safe_string(item, 'usableAmt')
1129
+ account['used'] = self.safe_string(item, 'freezeAmt')
1130
+ result[codeInner] = account
1131
+ return self.safe_balance(result)
1132
+ return None
1133
+
1134
+ async def fetch_balance(self, params={}) -> Balances:
1135
+ """
1136
+ query for balance and get the amount of funds available for trading or funds locked in orders
1137
+ :see: https://www.lbank.com/en-US/docs/index.html#asset-information
1138
+ :see: https://www.lbank.com/en-US/docs/index.html#account-information
1139
+ :see: https://www.lbank.com/en-US/docs/index.html#get-all-coins-information
1140
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1141
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1142
+ """
1143
+ await self.load_markets()
1144
+ options = self.safe_value(self.options, 'fetchBalance', {})
1145
+ defaultMethod = self.safe_string(options, 'method', 'spotPrivatePostSupplementUserInfo')
1146
+ method = self.safe_string(params, 'method', defaultMethod)
1147
+ response = None
1148
+ if method == 'spotPrivatePostSupplementUserInfoAccount':
1149
+ response = await self.spotPrivatePostSupplementUserInfoAccount()
1150
+ elif method == 'spotPrivatePostUserInfo':
1151
+ response = await self.spotPrivatePostUserInfo()
1152
+ else:
1153
+ response = await self.spotPrivatePostSupplementUserInfo()
1154
+ #
1155
+ # {
1156
+ # "result": "true",
1157
+ # "data": [
1158
+ # {
1159
+ # "usableAmt": "14.36",
1160
+ # "assetAmt": "14.36",
1161
+ # "networkList": [
1162
+ # {
1163
+ # "isDefault": False,
1164
+ # "withdrawFeeRate": "",
1165
+ # "name": "erc20",
1166
+ # "withdrawMin": 30,
1167
+ # "minLimit": 0.0001,
1168
+ # "minDeposit": 20,
1169
+ # "feeAssetCode": "usdt",
1170
+ # "withdrawFee": "30",
1171
+ # "type": 1,
1172
+ # "coin": "usdt",
1173
+ # "network": "eth"
1174
+ # },
1175
+ # ...
1176
+ # ],
1177
+ # "freezeAmt": "0",
1178
+ # "coin": "ada"
1179
+ # }
1180
+ # ],
1181
+ # "code": 0
1182
+ # }
1183
+ #
1184
+ return self.parse_balance(response)
1185
+
1186
+ def parse_trading_fee(self, fee: dict, market: Market = None) -> TradingFeeInterface:
1187
+ #
1188
+ # {
1189
+ # "symbol":"skt_usdt",
1190
+ # "makerCommission":"0.10",
1191
+ # "takerCommission":"0.10"
1192
+ # }
1193
+ #
1194
+ marketId = self.safe_string(fee, 'symbol')
1195
+ symbol = self.safe_symbol(marketId)
1196
+ return {
1197
+ 'info': fee,
1198
+ 'symbol': symbol,
1199
+ 'maker': self.safe_number(fee, 'makerCommission'),
1200
+ 'taker': self.safe_number(fee, 'takerCommission'),
1201
+ 'percentage': None,
1202
+ 'tierBased': None,
1203
+ }
1204
+
1205
+ async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
1206
+ """
1207
+ fetch the trading fees for a market
1208
+ :see: https://www.lbank.com/en-US/docs/index.html#transaction-fee-rate-query
1209
+ :param str symbol: unified market symbol
1210
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1211
+ :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
1212
+ """
1213
+ market = self.market(symbol)
1214
+ result = await self.fetch_trading_fees(self.extend(params, {'category': market['id']}))
1215
+ return self.safe_dict(result, symbol)
1216
+
1217
+ async def fetch_trading_fees(self, params={}) -> TradingFees:
1218
+ """
1219
+ fetch the trading fees for multiple markets
1220
+ :see: https://www.lbank.com/en-US/docs/index.html#transaction-fee-rate-query
1221
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1222
+ :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
1223
+ """
1224
+ await self.load_markets()
1225
+ request: dict = {}
1226
+ response = await self.spotPrivatePostSupplementCustomerTradeFee(self.extend(request, params))
1227
+ fees = self.safe_value(response, 'data', [])
1228
+ result: dict = {}
1229
+ for i in range(0, len(fees)):
1230
+ fee = self.parse_trading_fee(fees[i])
1231
+ symbol = fee['symbol']
1232
+ result[symbol] = fee
1233
+ return result
1234
+
1235
+ async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
1236
+ """
1237
+ create a market buy order by providing the symbol and cost
1238
+ :see: https://www.lbank.com/en-US/docs/index.html#place-order
1239
+ :see: https://www.lbank.com/en-US/docs/index.html#place-an-order
1240
+ :param str symbol: unified symbol of the market to create an order in
1241
+ :param float cost: how much you want to trade in units of the quote currency
1242
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1243
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1244
+ """
1245
+ await self.load_markets()
1246
+ market = self.market(symbol)
1247
+ if not market['spot']:
1248
+ raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
1249
+ params['createMarketBuyOrderRequiresPrice'] = False
1250
+ return await self.create_order(symbol, 'market', 'buy', cost, None, params)
1251
+
1252
+ async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1253
+ """
1254
+ create a trade order
1255
+ :see: https://www.lbank.com/en-US/docs/index.html#place-order
1256
+ :see: https://www.lbank.com/en-US/docs/index.html#place-an-order
1257
+ :param str symbol: unified symbol of the market to create an order in
1258
+ :param str type: 'market' or 'limit'
1259
+ :param str side: 'buy' or 'sell'
1260
+ :param float amount: how much of currency you want to trade in units of base currency
1261
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1262
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1263
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1264
+ """
1265
+ await self.load_markets()
1266
+ market = self.market(symbol)
1267
+ clientOrderId = self.safe_string_2(params, 'custom_id', 'clientOrderId')
1268
+ postOnly = self.safe_bool(params, 'postOnly', False)
1269
+ timeInForce = self.safe_string_upper(params, 'timeInForce')
1270
+ params = self.omit(params, ['custom_id', 'clientOrderId', 'timeInForce', 'postOnly'])
1271
+ request: dict = {
1272
+ 'symbol': market['id'],
1273
+ }
1274
+ ioc = (timeInForce == 'IOC')
1275
+ fok = (timeInForce == 'FOK')
1276
+ maker = (postOnly or (timeInForce == 'PO'))
1277
+ if (type == 'market') and (ioc or fok or maker):
1278
+ raise InvalidOrder(self.id + ' createOrder() does not allow market FOK, IOC, or postOnly orders. Only limit IOC, FOK, and postOnly orders are allowed')
1279
+ if type == 'limit':
1280
+ request['type'] = side
1281
+ request['price'] = self.price_to_precision(symbol, price)
1282
+ request['amount'] = self.amount_to_precision(symbol, amount)
1283
+ if ioc:
1284
+ request['type'] = side + '_' + 'ioc'
1285
+ elif fok:
1286
+ request['type'] = side + '_' + 'fok'
1287
+ elif maker:
1288
+ request['type'] = side + '_' + 'maker'
1289
+ elif type == 'market':
1290
+ if side == 'sell':
1291
+ request['type'] = side + '_' + 'market'
1292
+ request['amount'] = self.amount_to_precision(symbol, amount)
1293
+ elif side == 'buy':
1294
+ request['type'] = side + '_' + 'market'
1295
+ quoteAmount = None
1296
+ createMarketBuyOrderRequiresPrice = True
1297
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
1298
+ cost = self.safe_number(params, 'cost')
1299
+ params = self.omit(params, 'cost')
1300
+ if cost is not None:
1301
+ quoteAmount = self.cost_to_precision(symbol, cost)
1302
+ elif createMarketBuyOrderRequiresPrice:
1303
+ if price is None:
1304
+ raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
1305
+ else:
1306
+ amountString = self.number_to_string(amount)
1307
+ priceString = self.number_to_string(price)
1308
+ costRequest = Precise.string_mul(amountString, priceString)
1309
+ quoteAmount = self.cost_to_precision(symbol, costRequest)
1310
+ else:
1311
+ quoteAmount = self.cost_to_precision(symbol, amount)
1312
+ # market buys require filling the price param instead of the amount param, for market buys the price is treated cost by lbank
1313
+ request['price'] = quoteAmount
1314
+ if clientOrderId is not None:
1315
+ request['custom_id'] = clientOrderId
1316
+ options = self.safe_value(self.options, 'createOrder', {})
1317
+ defaultMethod = self.safe_string(options, 'method', 'spotPrivatePostSupplementCreateOrder')
1318
+ method = self.safe_string(params, 'method', defaultMethod)
1319
+ params = self.omit(params, 'method')
1320
+ response = None
1321
+ if method == 'spotPrivatePostCreateOrder':
1322
+ response = await self.spotPrivatePostCreateOrder(self.extend(request, params))
1323
+ else:
1324
+ response = await self.spotPrivatePostSupplementCreateOrder(self.extend(request, params))
1325
+ #
1326
+ # {
1327
+ # "result":true,
1328
+ # "data":{
1329
+ # "symbol":"doge_usdt",
1330
+ # "order_id":"0cf8a3de-4597-4296-af45-be7abaa06b07"
1331
+ # },
1332
+ # "error_code":0,
1333
+ # "ts":1648162321043
1334
+ # }
1335
+ #
1336
+ result = self.safe_value(response, 'data', {})
1337
+ return self.safe_order({
1338
+ 'id': self.safe_string(result, 'order_id'),
1339
+ 'info': result,
1340
+ }, market)
1341
+
1342
+ def parse_order_status(self, status: Str):
1343
+ statuses: dict = {
1344
+ '-1': 'canceled', # canceled
1345
+ '0': 'open', # not traded
1346
+ '1': 'open', # partial deal
1347
+ '2': 'closed', # complete deal
1348
+ '3': 'canceled', # filled partially and cancelled
1349
+ '4': 'closed', # disposal processing
1350
+ }
1351
+ return self.safe_string(statuses, status, status)
1352
+
1353
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1354
+ #
1355
+ # fetchOrderSupplement(private)
1356
+ #
1357
+ # {
1358
+ # "cummulativeQuoteQty":0,
1359
+ # "symbol":"doge_usdt",
1360
+ # "executedQty":0,
1361
+ # "orderId":"53d2d53e-70fb-4398-b722-f48571a5f61e",
1362
+ # "origQty":1E+2,
1363
+ # "price":0.05,
1364
+ # "clientOrderId":null,
1365
+ # "origQuoteOrderQty":5,
1366
+ # "updateTime":1648163406000,
1367
+ # "time":1648163139387,
1368
+ # "type":"buy_maker",
1369
+ # "status":-1
1370
+ # }
1371
+ #
1372
+ #
1373
+ # fetchOrderDefault(private)
1374
+ #
1375
+ # {
1376
+ # "symbol":"shib_usdt",
1377
+ # "amount":1,
1378
+ # "create_time":1649367863356,
1379
+ # "price":0.0000246103,
1380
+ # "avg_price":0.00002466180000000104,
1381
+ # "type":"buy_market",
1382
+ # "order_id":"abe8b92d-86d9-4d6d-b71e-d14f5fb53ddf",
1383
+ # "custom_id": "007", # field only present if user creates it at order time
1384
+ # "deal_amount":40548.54065802,
1385
+ # "status":2
1386
+ # }
1387
+ #
1388
+ # fetchOpenOrders(private)
1389
+ #
1390
+ # {
1391
+ # "cummulativeQuoteQty":0,
1392
+ # "symbol":"doge_usdt",
1393
+ # "executedQty":0,
1394
+ # "orderId":"73878edf-008d-4e4c-8041-df1f1b2cd8bb",
1395
+ # "origQty":100,
1396
+ # "price":0.05,
1397
+ # "origQuoteOrderQty":5,
1398
+ # "updateTime":1648501762000,
1399
+ # "time":1648501762353,
1400
+ # "type":"buy",
1401
+ # "status":0
1402
+ # }
1403
+ #
1404
+ # fetchOrders(private)
1405
+ #
1406
+ # {
1407
+ # "cummulativeQuoteQty":0,
1408
+ # "symbol":"doge_usdt",
1409
+ # "executedQty":0,
1410
+ # "orderId":"2cadc7cc-b5f6-486b-a5b4-d6ac49a9c186",
1411
+ # "origQty":100,
1412
+ # "price":0.05,
1413
+ # "origQuoteOrderQty":5,
1414
+ # "updateTime":1648501384000,
1415
+ # "time":1648501363889,
1416
+ # "type":"buy",
1417
+ # "status":-1
1418
+ # }
1419
+ #
1420
+ id = self.safe_string_2(order, 'orderId', 'order_id')
1421
+ clientOrderId = self.safe_string_2(order, 'clientOrderId', 'custom_id')
1422
+ timestamp = self.safe_integer_2(order, 'time', 'create_time')
1423
+ rawStatus = self.safe_string(order, 'status')
1424
+ marketId = self.safe_string(order, 'symbol')
1425
+ market = self.safe_market(marketId, market)
1426
+ timeInForce = None
1427
+ postOnly = False
1428
+ type = 'limit'
1429
+ rawType = self.safe_string(order, 'type') # buy, sell, buy_market, sell_market, buy_maker,sell_maker,buy_ioc,sell_ioc, buy_fok, sell_fok
1430
+ parts = rawType.split('_')
1431
+ side = self.safe_string(parts, 0)
1432
+ typePart = self.safe_string(parts, 1) # market, maker, ioc, fok or None(limit)
1433
+ if typePart == 'market':
1434
+ type = 'market'
1435
+ if typePart == 'maker':
1436
+ postOnly = True
1437
+ timeInForce = 'PO'
1438
+ if typePart == 'ioc':
1439
+ timeInForce = 'IOC'
1440
+ if typePart == 'fok':
1441
+ timeInForce = 'FOK'
1442
+ price = self.safe_string(order, 'price')
1443
+ costString = self.safe_string(order, 'cummulativeQuoteQty')
1444
+ amountString = None
1445
+ if rawType != 'buy_market':
1446
+ amountString = self.safe_string_2(order, 'origQty', 'amount')
1447
+ filledString = self.safe_string_2(order, 'executedQty', 'deal_amount')
1448
+ return self.safe_order({
1449
+ 'id': id,
1450
+ 'clientOrderId': clientOrderId,
1451
+ 'datetime': self.iso8601(timestamp),
1452
+ 'timestamp': timestamp,
1453
+ 'lastTradeTimestamp': None,
1454
+ 'status': self.parse_order_status(rawStatus),
1455
+ 'symbol': market['symbol'],
1456
+ 'type': type,
1457
+ 'timeInForce': timeInForce,
1458
+ 'postOnly': postOnly,
1459
+ 'side': side,
1460
+ 'price': price,
1461
+ 'stopPrice': None,
1462
+ 'triggerPrice': None,
1463
+ 'cost': costString,
1464
+ 'amount': amountString,
1465
+ 'filled': filledString,
1466
+ 'remaining': None,
1467
+ 'trades': None,
1468
+ 'fee': None,
1469
+ 'info': order,
1470
+ 'average': None,
1471
+ }, market)
1472
+
1473
+ async def fetch_order(self, id: str, symbol: Str = None, params={}):
1474
+ """
1475
+ fetches information on an order made by the user
1476
+ :see: https://www.lbank.com/en-US/docs/index.html#query-order
1477
+ :see: https://www.lbank.com/en-US/docs/index.html#query-order-new
1478
+ :param str symbol: unified symbol of the market the order was made in
1479
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1480
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1481
+ """
1482
+ await self.load_markets()
1483
+ method = self.safe_string(params, 'method')
1484
+ if method is None:
1485
+ options = self.safe_value(self.options, 'fetchOrder', {})
1486
+ method = self.safe_string(options, 'method', 'fetchOrderSupplement')
1487
+ if method == 'fetchOrderSupplement':
1488
+ return await self.fetch_order_supplement(id, symbol, params)
1489
+ return await self.fetch_order_default(id, symbol, params)
1490
+
1491
+ async def fetch_order_supplement(self, id: str, symbol: Str = None, params={}):
1492
+ if symbol is None:
1493
+ raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
1494
+ await self.load_markets()
1495
+ market = self.market(symbol)
1496
+ request: dict = {
1497
+ 'symbol': market['id'],
1498
+ 'orderId': id,
1499
+ }
1500
+ response = await self.spotPrivatePostSupplementOrdersInfo(self.extend(request, params))
1501
+ #
1502
+ # {
1503
+ # "result":true,
1504
+ # "data":{
1505
+ # "cummulativeQuoteQty":0,
1506
+ # "symbol":"doge_usdt",
1507
+ # "executedQty":0,
1508
+ # "orderId":"53d2d53e-70fb-4398-b722-f48571a5f61e",
1509
+ # "origQty":1E+2,
1510
+ # "price":0.05,
1511
+ # "clientOrderId":null,
1512
+ # "origQuoteOrderQty":5,
1513
+ # "updateTime":1648163406000,
1514
+ # "time":1648163139387,
1515
+ # "type":"buy_maker",
1516
+ # "status":-1
1517
+ # },
1518
+ # "error_code":0,
1519
+ # "ts":1648164471827
1520
+ # }
1521
+ #
1522
+ result = self.safe_dict(response, 'data', {})
1523
+ return self.parse_order(result)
1524
+
1525
+ async def fetch_order_default(self, id: str, symbol: Str = None, params={}):
1526
+ # Id can be a list of ids delimited by a comma
1527
+ if symbol is None:
1528
+ raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
1529
+ await self.load_markets()
1530
+ market = self.market(symbol)
1531
+ request: dict = {
1532
+ 'symbol': market['id'],
1533
+ 'order_id': id,
1534
+ }
1535
+ response = await self.spotPrivatePostOrdersInfo(self.extend(request, params))
1536
+ #
1537
+ # {
1538
+ # "result":true,
1539
+ # "data":[
1540
+ # {
1541
+ # "symbol":"doge_usdt",
1542
+ # "amount":18,
1543
+ # "create_time":1647455223186,
1544
+ # "price":0,
1545
+ # "avg_price":0.113344,
1546
+ # "type":"sell_market",
1547
+ # "order_id":"d4ca1ddd-40d9-42c1-9717-5de435865bec",
1548
+ # "deal_amount":18,
1549
+ # "status":2
1550
+ # }
1551
+ # ],
1552
+ # "error_code":0,
1553
+ # "ts":1647455270776
1554
+ # }
1555
+ #
1556
+ result = self.safe_value(response, 'data', [])
1557
+ numOrders = len(result)
1558
+ if numOrders == 1:
1559
+ return self.parse_order(result[0])
1560
+ else:
1561
+ # parsedOrders = []
1562
+ # for i in range(0, numOrders):
1563
+ # parsedOrder = self.parse_order(result[i])
1564
+ # parsedOrders.append(parsedOrder)
1565
+ # }
1566
+ # return parsedOrders
1567
+ raise BadRequest(self.id + ' fetchOrder() can only fetch one order at a time')
1568
+
1569
+ async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1570
+ """
1571
+ fetch all trades made by the user
1572
+ :see: https://www.lbank.com/en-US/docs/index.html#past-transaction-details
1573
+ :param str symbol: unified market symbol
1574
+ :param int [since]: the earliest time in ms to fetch trades for
1575
+ :param int [limit]: the maximum number of trade structures to retrieve
1576
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1577
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1578
+ """
1579
+ if symbol is None:
1580
+ raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol argument')
1581
+ await self.load_markets()
1582
+ market = self.market(symbol)
1583
+ since = self.safe_value(params, 'start_date', since)
1584
+ params = self.omit(params, 'start_date')
1585
+ request: dict = {
1586
+ 'symbol': market['id'],
1587
+ # 'start_date' Start time yyyy-mm-dd, the maximum is today, the default is yesterday
1588
+ # 'end_date' Finish time yyyy-mm-dd, the maximum is today, the default is today
1589
+ # 'The start': and end date of the query window is up to 2 days
1590
+ # 'from' Initial transaction number inquiring
1591
+ # 'direct' inquire direction,The default is the 'next' which is the positive sequence of dealing time,the 'prev' is inverted order of dealing time
1592
+ # 'size' Query the number of defaults to 100
1593
+ }
1594
+ if limit is not None:
1595
+ request['size'] = limit
1596
+ if since is not None:
1597
+ request['start_date'] = self.ymd(since, '-') # max query 2 days ago
1598
+ request['end_date'] = self.ymd(since + 86400000, '-') # will cover 2 days
1599
+ response = await self.spotPrivatePostTransactionHistory(self.extend(request, params))
1600
+ #
1601
+ # {
1602
+ # "result":true,
1603
+ # "data":[
1604
+ # {
1605
+ # "orderUuid":"38b4e7a4-14f6-45fd-aba1-1a37024124a0",
1606
+ # "tradeFeeRate":0.0010000000,
1607
+ # "dealTime":1648500944496,
1608
+ # "dealQuantity":30.00000000000000000000,
1609
+ # "tradeFee":0.00453300000000000000,
1610
+ # "txUuid":"11f3850cc6214ea3b495adad3a032794",
1611
+ # "dealPrice":0.15111300000000000000,
1612
+ # "dealVolumePrice":4.53339000000000000000,
1613
+ # "tradeType":"sell_market"
1614
+ # }
1615
+ # ],
1616
+ # "error_code":0,
1617
+ # "ts":1648509742164
1618
+ # }
1619
+ #
1620
+ trades = self.safe_list(response, 'data', [])
1621
+ return self.parse_trades(trades, market, since, limit)
1622
+
1623
+ async def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1624
+ """
1625
+ fetches information on multiple orders made by the user
1626
+ :see: https://www.lbank.com/en-US/docs/index.html#query-all-orders
1627
+ :param str symbol: unified market symbol of the market orders were made in
1628
+ :param int [since]: the earliest time in ms to fetch orders for
1629
+ :param int [limit]: the maximum number of order structures to retrieve
1630
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1631
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1632
+ """
1633
+ # default query is for canceled and completely filled orders
1634
+ # does not return open orders unless specified explicitly
1635
+ if symbol is None:
1636
+ raise ArgumentsRequired(self.id + ' fetchOrders() requires a symbol argument')
1637
+ await self.load_markets()
1638
+ market = self.market(symbol)
1639
+ if limit is None:
1640
+ limit = 100
1641
+ request: dict = {
1642
+ 'symbol': market['id'],
1643
+ 'current_page': 1,
1644
+ 'page_length': limit,
1645
+ # 'status' -1: Cancelled, 0: Unfilled, 1: Partially filled, 2: Completely filled, 3: Partially filled and cancelled, 4: Cancellation is being processed
1646
+ }
1647
+ response = await self.spotPrivatePostSupplementOrdersInfoHistory(self.extend(request, params))
1648
+ #
1649
+ # {
1650
+ # "result":true,
1651
+ # "data":{
1652
+ # "total":1,
1653
+ # "page_length":100,
1654
+ # "orders":[
1655
+ # {
1656
+ # "cummulativeQuoteQty":0,
1657
+ # "symbol":"doge_usdt",
1658
+ # "executedQty":0,
1659
+ # "orderId":"2cadc7cc-b5f6-486b-a5b4-d6ac49a9c186",
1660
+ # "origQty":100,
1661
+ # "price":0.05,
1662
+ # "origQuoteOrderQty":5,
1663
+ # "updateTime":1648501384000,
1664
+ # "time":1648501363889,
1665
+ # "type":"buy",
1666
+ # "status":-1
1667
+ # }, ...
1668
+ # ],
1669
+ # "current_page":1
1670
+ # },
1671
+ # "error_code":0,
1672
+ # "ts":1648505706348
1673
+ # }
1674
+ #
1675
+ result = self.safe_value(response, 'data', {})
1676
+ orders = self.safe_list(result, 'orders', [])
1677
+ return self.parse_orders(orders, market, since, limit)
1678
+
1679
+ async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1680
+ """
1681
+ fetch all unfilled currently open orders
1682
+ :see: https://www.lbank.com/en-US/docs/index.html#current-pending-order
1683
+ :param str symbol: unified market symbol
1684
+ :param int [since]: the earliest time in ms to fetch open orders for
1685
+ :param int [limit]: the maximum number of open order structures to retrieve
1686
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1687
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1688
+ """
1689
+ if symbol is None:
1690
+ raise ArgumentsRequired(self.id + ' fetchOpenOrders() requires a symbol argument')
1691
+ await self.load_markets()
1692
+ market = self.market(symbol)
1693
+ if limit is None:
1694
+ limit = 100
1695
+ request: dict = {
1696
+ 'symbol': market['id'],
1697
+ 'current_page': 1,
1698
+ 'page_length': limit,
1699
+ }
1700
+ response = await self.spotPrivatePostSupplementOrdersInfoNoDeal(self.extend(request, params))
1701
+ #
1702
+ # {
1703
+ # "result":true,
1704
+ # "data":{
1705
+ # "total":1,
1706
+ # "page_length":100,
1707
+ # "orders":[
1708
+ # {
1709
+ # "cummulativeQuoteQty":0,
1710
+ # "symbol":"doge_usdt",
1711
+ # "executedQty":0,
1712
+ # "orderId":"73878edf-008d-4e4c-8041-df1f1b2cd8bb",
1713
+ # "origQty":100,
1714
+ # "price":0.05,
1715
+ # "origQuoteOrderQty":5,
1716
+ # "updateTime":1648501762000,
1717
+ # "time":1648501762353,
1718
+ # "type":"buy",
1719
+ # "status":0
1720
+ # }, ...
1721
+ # ],
1722
+ # "current_page":1
1723
+ # },
1724
+ # "error_code":0,
1725
+ # "ts":1648506110196
1726
+ # }
1727
+ #
1728
+ result = self.safe_value(response, 'data', {})
1729
+ orders = self.safe_list(result, 'orders', [])
1730
+ return self.parse_orders(orders, market, since, limit)
1731
+
1732
+ async def cancel_order(self, id: str, symbol: Str = None, params={}):
1733
+ """
1734
+ cancels an open order
1735
+ :see: https://www.lbank.com/en-US/docs/index.html#cancel-order-new
1736
+ :param str id: order id
1737
+ :param str symbol: unified symbol of the market the order was made in
1738
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1739
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1740
+ """
1741
+ if symbol is None:
1742
+ raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
1743
+ await self.load_markets()
1744
+ clientOrderId = self.safe_string_2(params, 'origClientOrderId', 'clientOrderId')
1745
+ params = self.omit(params, ['origClientOrderId', 'clientOrderId'])
1746
+ market = self.market(symbol)
1747
+ request: dict = {
1748
+ 'symbol': market['id'],
1749
+ 'orderId': id,
1750
+ }
1751
+ if clientOrderId is not None:
1752
+ request['origClientOrderId'] = clientOrderId
1753
+ response = await self.spotPrivatePostSupplementCancelOrder(self.extend(request, params))
1754
+ #
1755
+ # {
1756
+ # "result":true,
1757
+ # "data":{
1758
+ # "executedQty":0.0,
1759
+ # "price":0.05,
1760
+ # "origQty":100.0,
1761
+ # "tradeType":"buy",
1762
+ # "status":0
1763
+ # },
1764
+ # "error_code":0,
1765
+ # "ts":1648501286196
1766
+ # }
1767
+ result = self.safe_value(response, 'data', {})
1768
+ return result
1769
+
1770
+ async def cancel_all_orders(self, symbol: Str = None, params={}):
1771
+ """
1772
+ cancel all open orders in a market
1773
+ :see: https://www.lbank.com/en-US/docs/index.html#cancel-all-pending-orders-for-a-single-trading-pair
1774
+ :param str symbol: unified market symbol of the market to cancel orders in
1775
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1776
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1777
+ """
1778
+ if symbol is None:
1779
+ raise ArgumentsRequired(self.id + ' cancelAllOrders() requires a symbol argument')
1780
+ await self.load_markets()
1781
+ market = self.market(symbol)
1782
+ request: dict = {
1783
+ 'symbol': market['id'],
1784
+ }
1785
+ response = await self.spotPrivatePostSupplementCancelOrderBySymbol(self.extend(request, params))
1786
+ #
1787
+ # {
1788
+ # "result":"true",
1789
+ # "data":[
1790
+ # {
1791
+ # "executedQty":0.00000000000000000000,
1792
+ # "orderId":"293ef71b-3e67-4962-af93-aa06990a045f",
1793
+ # "price":0.05000000000000000000,
1794
+ # "origQty":100.00000000000000000000,
1795
+ # "tradeType":"buy",
1796
+ # "status":0
1797
+ # },
1798
+ # ],
1799
+ # "error_code":0,
1800
+ # "ts":1648506641469
1801
+ # }
1802
+ #
1803
+ result = self.safe_value(response, 'data', [])
1804
+ return result
1805
+
1806
+ def get_network_code_for_currency(self, currencyCode, params):
1807
+ defaultNetworks = self.safe_value(self.options, 'defaultNetworks')
1808
+ defaultNetwork = self.safe_string_upper(defaultNetworks, currencyCode)
1809
+ networks = self.safe_value(self.options, 'networks', {})
1810
+ network = self.safe_string_upper(params, 'network', defaultNetwork) # self line allows the user to specify either ERC20 or ETH
1811
+ network = self.safe_string(networks, network, network) # handle ERC20>ETH alias
1812
+ return network
1813
+
1814
+ async def fetch_deposit_address(self, code: str, params={}):
1815
+ """
1816
+ fetch the deposit address for a currency associated with self account
1817
+ :see: https://www.lbank.com/en-US/docs/index.html#get-deposit-address
1818
+ :see: https://www.lbank.com/en-US/docs/index.html#the-user-obtains-the-deposit-address
1819
+ :param str code: unified currency code
1820
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1821
+ :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
1822
+ """
1823
+ await self.load_markets()
1824
+ options = self.safe_value(self.options, 'fetchDepositAddress', {})
1825
+ defaultMethod = self.safe_string(options, 'method', 'fetchDepositAddressDefault')
1826
+ method = self.safe_string(params, 'method', defaultMethod)
1827
+ params = self.omit(params, 'method')
1828
+ response = None
1829
+ if method == 'fetchDepositAddressSupplement':
1830
+ response = await self.fetch_deposit_address_supplement(code, params)
1831
+ else:
1832
+ response = await self.fetch_deposit_address_default(code, params)
1833
+ return response
1834
+
1835
+ async def fetch_deposit_address_default(self, code: str, params={}):
1836
+ await self.load_markets()
1837
+ currency = self.currency(code)
1838
+ request: dict = {
1839
+ 'assetCode': currency['id'],
1840
+ }
1841
+ network = self.get_network_code_for_currency(code, params)
1842
+ if network is not None:
1843
+ request['netWork'] = network # ... yes, really lol
1844
+ params = self.omit(params, 'network')
1845
+ response = await self.spotPrivatePostGetDepositAddress(self.extend(request, params))
1846
+ #
1847
+ # {
1848
+ # "result":true,
1849
+ # "data":{
1850
+ # "assetCode":"usdt",
1851
+ # "address":"0xc85689d37ca650bf2f2161364cdedee21eb6ca53",
1852
+ # "memo":null,
1853
+ # "netWork":"bep20(bsc)"
1854
+ # },
1855
+ # "error_code":0,
1856
+ # "ts":1648075865103
1857
+ # }
1858
+ #
1859
+ result = self.safe_value(response, 'data')
1860
+ address = self.safe_string(result, 'address')
1861
+ tag = self.safe_string(result, 'memo')
1862
+ networkId = self.safe_string(result, 'netWork')
1863
+ inverseNetworks = self.safe_value(self.options, 'inverse-networks', {})
1864
+ networkCode = self.safe_string_upper(inverseNetworks, networkId, networkId)
1865
+ return {
1866
+ 'currency': code,
1867
+ 'address': address,
1868
+ 'tag': tag,
1869
+ 'network': networkCode,
1870
+ 'info': response,
1871
+ }
1872
+
1873
+ async def fetch_deposit_address_supplement(self, code: str, params={}):
1874
+ # returns the address for whatever the default network is...
1875
+ await self.load_markets()
1876
+ currency = self.currency(code)
1877
+ request: dict = {
1878
+ 'coin': currency['id'],
1879
+ }
1880
+ networks = self.safe_value(self.options, 'networks')
1881
+ network = self.safe_string_upper(params, 'network')
1882
+ network = self.safe_string(networks, network, network)
1883
+ if network is not None:
1884
+ request['networkName'] = network
1885
+ params = self.omit(params, 'network')
1886
+ response = await self.spotPrivatePostSupplementGetDepositAddress(self.extend(request, params))
1887
+ #
1888
+ # {
1889
+ # "result":true,
1890
+ # "data":{
1891
+ # "address":"TDxtabCC8iQwaxUUrPcE4WL2jArGAfvQ5A",
1892
+ # "memo":null,
1893
+ # "coin":"usdt"
1894
+ # },
1895
+ # "error_code":0,
1896
+ # "ts":1648073818880
1897
+ # }
1898
+ #
1899
+ result = self.safe_value(response, 'data')
1900
+ address = self.safe_string(result, 'address')
1901
+ tag = self.safe_string(result, 'memo')
1902
+ inverseNetworks = self.safe_value(self.options, 'inverse-networks', {})
1903
+ networkCode = self.safe_string_upper(inverseNetworks, network, network)
1904
+ return {
1905
+ 'currency': code,
1906
+ 'address': address,
1907
+ 'tag': tag,
1908
+ 'network': networkCode, # will be None if not specified in request
1909
+ 'info': response,
1910
+ }
1911
+
1912
+ async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
1913
+ """
1914
+ make a withdrawal
1915
+ :see: https://www.lbank.com/en-US/docs/index.html#withdrawal
1916
+ :param str code: unified currency code
1917
+ :param float amount: the amount to withdraw
1918
+ :param str address: the address to withdraw to
1919
+ :param str tag:
1920
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1921
+ :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1922
+ """
1923
+ tag, params = self.handle_withdraw_tag_and_params(tag, params)
1924
+ self.check_address(address)
1925
+ await self.load_markets()
1926
+ fee = self.safe_string(params, 'fee')
1927
+ params = self.omit(params, 'fee')
1928
+ # The relevant coin network fee can be found by calling fetchDepositWithdrawFees(), note: if no network param is supplied then the default network will be used, self can also be found in fetchDepositWithdrawFees().
1929
+ self.check_required_argument('withdraw', fee, 'fee')
1930
+ currency = self.currency(code)
1931
+ request: dict = {
1932
+ 'address': address,
1933
+ 'coin': currency['id'],
1934
+ 'amount': amount,
1935
+ 'fee': fee, # the correct coin-network fee must be supplied, which can be found by calling fetchDepositWithdrawFees(private)
1936
+ # 'networkName': defaults to the defaultNetwork of the coin which can be found in the /supplement/user_info endpoint
1937
+ # 'memo': memo: memo word of bts and dct
1938
+ # 'mark': Withdrawal Notes
1939
+ # 'name': Remarks of the address. After hasattr(self, filling) parameter, it will be added to the withdrawal address book of the currency.
1940
+ # 'withdrawOrderId': withdrawOrderId
1941
+ # 'type': type=1 is for intra-site transfer
1942
+ }
1943
+ if tag is not None:
1944
+ request['memo'] = tag
1945
+ network = self.safe_string_upper_2(params, 'network', 'networkName')
1946
+ params = self.omit(params, ['network', 'networkName'])
1947
+ networks = self.safe_value(self.options, 'networks')
1948
+ networkId = self.safe_string(networks, network, network)
1949
+ if networkId is not None:
1950
+ request['networkName'] = networkId
1951
+ response = await self.spotPrivatePostSupplementWithdraw(self.extend(request, params))
1952
+ #
1953
+ # {
1954
+ # "result":true,
1955
+ # "data": {
1956
+ # "fee":10.00000000000000000000,
1957
+ # "withdrawId":1900376
1958
+ # },
1959
+ # "error_code":0,
1960
+ # "ts":1648992501414
1961
+ # }
1962
+ #
1963
+ result = self.safe_value(response, 'data', {})
1964
+ return {
1965
+ 'info': result,
1966
+ 'id': self.safe_string(result, 'withdrawId'),
1967
+ }
1968
+
1969
+ def parse_transaction_status(self, status, type):
1970
+ statuses: dict = {
1971
+ 'deposit': {
1972
+ '1': 'pending',
1973
+ '2': 'ok',
1974
+ '3': 'failed',
1975
+ '4': 'canceled',
1976
+ '5': 'transfer',
1977
+ },
1978
+ 'withdrawal': {
1979
+ '1': 'pending',
1980
+ '2': 'canceled',
1981
+ '3': 'failed',
1982
+ '4': 'ok',
1983
+ },
1984
+ }
1985
+ return self.safe_string(self.safe_value(statuses, type, {}), status, status)
1986
+
1987
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
1988
+ #
1989
+ # fetchDeposits(private)
1990
+ #
1991
+ # {
1992
+ # "insertTime":1649012310000,
1993
+ # "amount":9.00000000000000000000,
1994
+ # "address":"TYASr5UV6HEcXatwdFQfmLVUqQQQMUxHLS",
1995
+ # "networkName":"trc20",
1996
+ # "txId":"081e4e9351dd0274922168da5f2d14ea6c495b1c3b440244f4a6dd9fe196bf2b",
1997
+ # "coin":"usdt",
1998
+ # "status":"2"
1999
+ # }
2000
+ #
2001
+ #
2002
+ # fetchWithdrawals(private)
2003
+ #
2004
+ # {
2005
+ # "amount":2.00000000000000000000,
2006
+ # "address":"TBjrW5JHDyPZjFc5nrRMhRWUDaJmhGhmD6",
2007
+ # "fee":1.00000000000000000000,
2008
+ # "networkName":"trc20",
2009
+ # "coid":"usdt",
2010
+ # "transferType":"数字资产提现",
2011
+ # "txId":"47eeee2763ad49b8817524dacfa7d092fb58f8b0ab7e5d25473314df1a793c3d",
2012
+ # "id":1902194,
2013
+ # "applyTime":1649014002000,
2014
+ # "status":"4"
2015
+ # }
2016
+ #
2017
+ id = self.safe_string(transaction, 'id')
2018
+ type = None
2019
+ if id is None:
2020
+ type = 'deposit'
2021
+ else:
2022
+ type = 'withdrawal'
2023
+ txid = self.safe_string(transaction, 'txId')
2024
+ timestamp = self.safe_integer_2(transaction, 'insertTime', 'applyTime')
2025
+ networks = self.safe_value(self.options, 'inverse-networks', {})
2026
+ networkId = self.safe_string(transaction, 'networkName')
2027
+ network = self.safe_string(networks, networkId, networkId)
2028
+ address = self.safe_string(transaction, 'address')
2029
+ addressFrom = None
2030
+ addressTo = None
2031
+ if type == 'deposit':
2032
+ addressFrom = address
2033
+ else:
2034
+ addressTo = address
2035
+ amount = self.safe_number(transaction, 'amount')
2036
+ currencyId = self.safe_string_2(transaction, 'coin', 'coid')
2037
+ code = self.safe_currency_code(currencyId, currency)
2038
+ status = self.parse_transaction_status(self.safe_string(transaction, 'status'), type)
2039
+ fee = None
2040
+ feeCost = self.safe_number(transaction, 'fee')
2041
+ if feeCost is not None:
2042
+ fee = {
2043
+ 'cost': feeCost,
2044
+ 'currency': code,
2045
+ }
2046
+ return {
2047
+ 'info': transaction,
2048
+ 'id': id,
2049
+ 'txid': txid,
2050
+ 'timestamp': timestamp,
2051
+ 'datetime': self.iso8601(timestamp),
2052
+ 'network': network,
2053
+ 'address': address,
2054
+ 'addressTo': addressTo,
2055
+ 'addressFrom': addressFrom,
2056
+ 'tag': None,
2057
+ 'tagTo': None,
2058
+ 'tagFrom': None,
2059
+ 'type': type,
2060
+ 'amount': amount,
2061
+ 'currency': code,
2062
+ 'status': status,
2063
+ 'updated': None,
2064
+ 'comment': None,
2065
+ 'internal': (status == 'transfer'),
2066
+ 'fee': fee,
2067
+ }
2068
+
2069
+ async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2070
+ """
2071
+ fetch all deposits made to an account
2072
+ :see: https://www.lbank.com/en-US/docs/index.html#get-recharge-history
2073
+ :param str code: unified currency code
2074
+ :param int [since]: the earliest time in ms to fetch deposits for
2075
+ :param int [limit]: the maximum number of deposits structures to retrieve
2076
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2077
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2078
+ """
2079
+ await self.load_markets()
2080
+ request: dict = {
2081
+ # 'status': Recharge status: ("1","Applying"),("2","Recharge successful"),("3","Recharge failed"),("4","Already Cancel"),("5", "Transfer")
2082
+ # 'endTime': end time, timestamp in milliseconds, default now
2083
+ }
2084
+ currency = None
2085
+ if code is not None:
2086
+ currency = self.currency(code)
2087
+ request['coin'] = currency['id']
2088
+ if since is not None:
2089
+ request['startTime'] = since
2090
+ response = await self.spotPrivatePostSupplementDepositHistory(self.extend(request, params))
2091
+ #
2092
+ # {
2093
+ # "result":true,
2094
+ # "data": {
2095
+ # "total":1,
2096
+ # "depositOrders": [
2097
+ # {
2098
+ # "insertTime":1649012310000,
2099
+ # "amount":9.00000000000000000000,
2100
+ # "address":"TYASr5UV6HEcXatwdFQfmLVUqQQQMUxHLS",
2101
+ # "networkName":"trc20",
2102
+ # "txId":"081e4e9351dd0274922168da5f2d14ea6c495b1c3b440244f4a6dd9fe196bf2b",
2103
+ # "coin":"usdt",
2104
+ # "status":"2"
2105
+ # },
2106
+ # ],
2107
+ # "page_length":20,
2108
+ # "current_page":1
2109
+ # },
2110
+ # "error_code":0,
2111
+ # "ts":1649719721758
2112
+ # }
2113
+ #
2114
+ data = self.safe_value(response, 'data', {})
2115
+ deposits = self.safe_list(data, 'depositOrders', [])
2116
+ return self.parse_transactions(deposits, currency, since, limit)
2117
+
2118
+ async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2119
+ """
2120
+ fetch all withdrawals made from an account
2121
+ :see: https://www.lbank.com/en-US/docs/index.html#get-withdrawal-history
2122
+ :param str code: unified currency code
2123
+ :param int [since]: the earliest time in ms to fetch withdrawals for
2124
+ :param int [limit]: the maximum number of withdrawals structures to retrieve
2125
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2126
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2127
+ """
2128
+ await self.load_markets()
2129
+ request: dict = {
2130
+ # 'status': Recharge status: ("1","Applying"),("2","Recharge successful"),("3","Recharge failed"),("4","Already Cancel"),("5", "Transfer")
2131
+ # 'endTime': end time, timestamp in milliseconds, default now
2132
+ # 'withdrawOrderId': Custom withdrawal id
2133
+ }
2134
+ currency = None
2135
+ if code is not None:
2136
+ currency = self.currency(code)
2137
+ request['coin'] = currency['id']
2138
+ if since is not None:
2139
+ request['startTime'] = since
2140
+ response = await self.spotPrivatePostSupplementWithdraws(self.extend(request, params))
2141
+ #
2142
+ # {
2143
+ # "result":true,
2144
+ # "data": {
2145
+ # "total":1,
2146
+ # "withdraws": [
2147
+ # {
2148
+ # "amount":2.00000000000000000000,
2149
+ # "address":"TBjrW5JHDyPZjFc5nrRMhRWUDaJmhGhmD6",
2150
+ # "fee":1.00000000000000000000,
2151
+ # "networkName":"trc20",
2152
+ # "coid":"usdt",
2153
+ # "transferType":"数字资产提现",
2154
+ # "txId":"47eeee2763ad49b8817524dacfa7d092fb58f8b0ab7e5d25473314df1a793c3d",
2155
+ # "id":1902194,
2156
+ # "applyTime":1649014002000,
2157
+ # "status":"4"
2158
+ # },
2159
+ # ],
2160
+ # "page_length":20,
2161
+ # "current_page":1
2162
+ # },
2163
+ # "error_code":0,
2164
+ # "ts":1649720362362
2165
+ # }
2166
+ #
2167
+ data = self.safe_value(response, 'data', {})
2168
+ withdraws = self.safe_list(data, 'withdraws', [])
2169
+ return self.parse_transactions(withdraws, currency, since, limit)
2170
+
2171
+ async def fetch_transaction_fees(self, codes: Strings = None, params={}):
2172
+ """
2173
+ * @deprecated
2174
+ please use fetchDepositWithdrawFees instead
2175
+ :param str[]|None codes: not used by lbank fetchTransactionFees()
2176
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2177
+ :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
2178
+ """
2179
+ # private only returns information for currencies with non-zero balance
2180
+ await self.load_markets()
2181
+ isAuthorized = self.check_required_credentials(False)
2182
+ result = None
2183
+ if isAuthorized is True:
2184
+ options = self.safe_value(self.options, 'fetchTransactionFees', {})
2185
+ defaultMethod = self.safe_string(options, 'method', 'fetchPrivateTransactionFees')
2186
+ method = self.safe_string(params, 'method', defaultMethod)
2187
+ params = self.omit(params, 'method')
2188
+ if method == 'fetchPublicTransactionFees':
2189
+ result = await self.fetch_public_transaction_fees(params)
2190
+ else:
2191
+ result = await self.fetch_private_transaction_fees(params)
2192
+ else:
2193
+ result = await self.fetch_public_transaction_fees(params)
2194
+ return result
2195
+
2196
+ async def fetch_private_transaction_fees(self, params={}):
2197
+ # complete response
2198
+ # incl. for coins which None in public method
2199
+ await self.load_markets()
2200
+ response = await self.spotPrivatePostSupplementUserInfo()
2201
+ #
2202
+ # {
2203
+ # "result": "true",
2204
+ # "data": [
2205
+ # {
2206
+ # "usableAmt": "14.36",
2207
+ # "assetAmt": "14.36",
2208
+ # "networkList": [
2209
+ # {
2210
+ # "isDefault": False,
2211
+ # "withdrawFeeRate": "",
2212
+ # "name": "erc20",
2213
+ # "withdrawMin": 30,
2214
+ # "minLimit": 0.0001,
2215
+ # "minDeposit": 20,
2216
+ # "feeAssetCode": "usdt",
2217
+ # "withdrawFee": "30",
2218
+ # "type": 1,
2219
+ # "coin": "usdt",
2220
+ # "network": "eth"
2221
+ # },
2222
+ # ...
2223
+ # ],
2224
+ # "freezeAmt": "0",
2225
+ # "coin": "ada"
2226
+ # }
2227
+ # ],
2228
+ # "code": 0
2229
+ # }
2230
+ #
2231
+ result = self.safe_value(response, 'data', [])
2232
+ withdrawFees: dict = {}
2233
+ for i in range(0, len(result)):
2234
+ entry = result[i]
2235
+ currencyId = self.safe_string(entry, 'coin')
2236
+ code = self.safe_currency_code(currencyId)
2237
+ networkList = self.safe_value(entry, 'networkList', [])
2238
+ withdrawFees[code] = {}
2239
+ for j in range(0, len(networkList)):
2240
+ networkEntry = networkList[j]
2241
+ networkId = self.safe_string(networkEntry, 'name')
2242
+ networkCode = self.safe_string(self.options['inverse-networks'], networkId, networkId)
2243
+ fee = self.safe_number(networkEntry, 'withdrawFee')
2244
+ if fee is not None:
2245
+ withdrawFees[code][networkCode] = fee
2246
+ return {
2247
+ 'withdraw': withdrawFees,
2248
+ 'deposit': {},
2249
+ 'info': response,
2250
+ }
2251
+
2252
+ async def fetch_public_transaction_fees(self, params={}):
2253
+ # extremely incomplete response
2254
+ # vast majority fees None
2255
+ await self.load_markets()
2256
+ code = self.safe_string_2(params, 'coin', 'assetCode')
2257
+ params = self.omit(params, ['coin', 'assetCode'])
2258
+ request: dict = {}
2259
+ if code is not None:
2260
+ currency = self.currency(code)
2261
+ request['assetCode'] = currency['id']
2262
+ response = await self.spotPublicGetWithdrawConfigs(self.extend(request, params))
2263
+ #
2264
+ # {
2265
+ # "result": "true",
2266
+ # "data": [
2267
+ # {
2268
+ # "amountScale": "4",
2269
+ # "chain": "heco",
2270
+ # "assetCode": "lbk",
2271
+ # "min": "200",
2272
+ # "transferAmtScale": "4",
2273
+ # "canWithDraw": True,
2274
+ # "fee": "100",
2275
+ # "minTransfer": "0.0001",
2276
+ # "type": "1"
2277
+ # },
2278
+ # ...
2279
+ # ],
2280
+ # "error_code": "0",
2281
+ # "ts": "1663364435973"
2282
+ # }
2283
+ #
2284
+ result = self.safe_value(response, 'data', [])
2285
+ withdrawFees: dict = {}
2286
+ for i in range(0, len(result)):
2287
+ item = result[i]
2288
+ canWithdraw = self.safe_value(item, 'canWithDraw')
2289
+ if canWithdraw == 'true':
2290
+ currencyId = self.safe_string(item, 'assetCode')
2291
+ codeInner = self.safe_currency_code(currencyId)
2292
+ chain = self.safe_string(item, 'chain')
2293
+ network = self.safe_string(self.options['inverse-networks'], chain, chain)
2294
+ if network is None:
2295
+ network = codeInner
2296
+ fee = self.safe_string(item, 'fee')
2297
+ if withdrawFees[codeInner] is None:
2298
+ withdrawFees[codeInner] = {}
2299
+ withdrawFees[codeInner][network] = self.parse_number(fee)
2300
+ return {
2301
+ 'withdraw': withdrawFees,
2302
+ 'deposit': {},
2303
+ 'info': response,
2304
+ }
2305
+
2306
+ async def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
2307
+ """
2308
+ when using private endpoint, only returns information for currencies with non-zero balance, use public method by specifying self.options['fetchDepositWithdrawFees']['method'] = 'fetchPublicDepositWithdrawFees'
2309
+ :see: https://www.lbank.com/en-US/docs/index.html#get-all-coins-information
2310
+ :see: https://www.lbank.com/en-US/docs/index.html#withdrawal-configurations
2311
+ :param str[]|None codes: array of unified currency codes
2312
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2313
+ :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
2314
+ """
2315
+ await self.load_markets()
2316
+ isAuthorized = self.check_required_credentials(False)
2317
+ response = None
2318
+ if isAuthorized is True:
2319
+ options = self.safe_value(self.options, 'fetchDepositWithdrawFees', {})
2320
+ defaultMethod = self.safe_string(options, 'method', 'fetchPrivateDepositWithdrawFees')
2321
+ method = self.safe_string(params, 'method', defaultMethod)
2322
+ params = self.omit(params, 'method')
2323
+ if method == 'fetchPublicDepositWithdrawFees':
2324
+ await self.fetch_public_deposit_withdraw_fees(codes, params)
2325
+ else:
2326
+ await self.fetch_private_deposit_withdraw_fees(codes, params)
2327
+ else:
2328
+ await self.fetch_public_deposit_withdraw_fees(codes, params)
2329
+ return response
2330
+
2331
+ async def fetch_private_deposit_withdraw_fees(self, codes=None, params={}):
2332
+ # complete response
2333
+ # incl. for coins which None in public method
2334
+ await self.load_markets()
2335
+ response = await self.spotPrivatePostSupplementUserInfo(params)
2336
+ #
2337
+ # {
2338
+ # "result": "true",
2339
+ # "data": [
2340
+ # {
2341
+ # "usableAmt": "14.36",
2342
+ # "assetAmt": "14.36",
2343
+ # "networkList": [
2344
+ # {
2345
+ # "isDefault": False,
2346
+ # "withdrawFeeRate": "",
2347
+ # "name": "erc20",
2348
+ # "withdrawMin": 30,
2349
+ # "minLimit": 0.0001,
2350
+ # "minDeposit": 20,
2351
+ # "feeAssetCode": "usdt",
2352
+ # "withdrawFee": "30",
2353
+ # "type": 1,
2354
+ # "coin": "usdt",
2355
+ # "network": "eth"
2356
+ # },
2357
+ # ...
2358
+ # ],
2359
+ # "freezeAmt": "0",
2360
+ # "coin": "ada"
2361
+ # }
2362
+ # ],
2363
+ # "code": 0
2364
+ # }
2365
+ #
2366
+ data = self.safe_list(response, 'data', [])
2367
+ return self.parse_deposit_withdraw_fees(data, codes, 'coin')
2368
+
2369
+ async def fetch_public_deposit_withdraw_fees(self, codes=None, params={}):
2370
+ # extremely incomplete response
2371
+ # vast majority fees None
2372
+ await self.load_markets()
2373
+ request: dict = {}
2374
+ response = await self.spotPublicGetWithdrawConfigs(self.extend(request, params))
2375
+ #
2376
+ # {
2377
+ # "result": "true",
2378
+ # "data": [
2379
+ # {
2380
+ # "amountScale": "4",
2381
+ # "chain": "heco",
2382
+ # "assetCode": "lbk",
2383
+ # "min": "200",
2384
+ # "transferAmtScale": "4",
2385
+ # "canWithDraw": True,
2386
+ # "fee": "100",
2387
+ # "minTransfer": "0.0001",
2388
+ # "type": "1"
2389
+ # },
2390
+ # ...
2391
+ # ],
2392
+ # "error_code": "0",
2393
+ # "ts": "1663364435973"
2394
+ # }
2395
+ #
2396
+ data = self.safe_value(response, 'data', [])
2397
+ return self.parse_public_deposit_withdraw_fees(data, codes)
2398
+
2399
+ def parse_public_deposit_withdraw_fees(self, response, codes=None):
2400
+ #
2401
+ # [
2402
+ # {
2403
+ # "amountScale": "4",
2404
+ # "chain": "heco",
2405
+ # "assetCode": "lbk",
2406
+ # "min": "200",
2407
+ # "transferAmtScale": "4",
2408
+ # "canWithDraw": True,
2409
+ # "fee": "100",
2410
+ # "minTransfer": "0.0001",
2411
+ # "type": "1"
2412
+ # },
2413
+ # ...
2414
+ # ]
2415
+ #
2416
+ result: dict = {}
2417
+ for i in range(0, len(response)):
2418
+ fee = response[i]
2419
+ canWithdraw = self.safe_value(fee, 'canWithDraw')
2420
+ if canWithdraw is True:
2421
+ currencyId = self.safe_string(fee, 'assetCode')
2422
+ code = self.safe_currency_code(currencyId)
2423
+ if codes is None or self.in_array(code, codes):
2424
+ withdrawFee = self.safe_number(fee, 'fee')
2425
+ if withdrawFee is not None:
2426
+ resultValue = self.safe_value(result, code)
2427
+ if resultValue is None:
2428
+ result[code] = self.deposit_withdraw_fee([fee])
2429
+ else:
2430
+ result[code]['info'].append(fee)
2431
+ chain = self.safe_string(fee, 'chain')
2432
+ networkCode = self.safe_string(self.options['inverse-networks'], chain, chain)
2433
+ if networkCode is not None:
2434
+ result[code]['networks'][networkCode] = {
2435
+ 'withdraw': {
2436
+ 'fee': withdrawFee,
2437
+ 'percentage': None,
2438
+ },
2439
+ 'deposit': {
2440
+ 'fee': None,
2441
+ 'percentage': None,
2442
+ },
2443
+ }
2444
+ else:
2445
+ result[code]['withdraw'] = {
2446
+ 'fee': withdrawFee,
2447
+ 'percentage': None,
2448
+ }
2449
+ return result
2450
+
2451
+ def parse_deposit_withdraw_fee(self, fee, currency: Currency = None):
2452
+ #
2453
+ # * only used for fetchPrivateDepositWithdrawFees
2454
+ #
2455
+ # {
2456
+ # "usableAmt": "14.36",
2457
+ # "assetAmt": "14.36",
2458
+ # "networkList": [
2459
+ # {
2460
+ # "isDefault": False,
2461
+ # "withdrawFeeRate": "",
2462
+ # "name": "erc20",
2463
+ # "withdrawMin": 30,
2464
+ # "minLimit": 0.0001,
2465
+ # "minDeposit": 20,
2466
+ # "feeAssetCode": "usdt",
2467
+ # "withdrawFee": "30",
2468
+ # "type": 1,
2469
+ # "coin": "usdt",
2470
+ # "network": "eth"
2471
+ # },
2472
+ # ...
2473
+ # ],
2474
+ # "freezeAmt": "0",
2475
+ # "coin": "ada"
2476
+ # }
2477
+ #
2478
+ result = self.deposit_withdraw_fee(fee)
2479
+ networkList = self.safe_value(fee, 'networkList', [])
2480
+ for j in range(0, len(networkList)):
2481
+ networkEntry = networkList[j]
2482
+ networkId = self.safe_string(networkEntry, 'name')
2483
+ networkCode = self.safe_string_upper(self.options['inverse-networks'], networkId, networkId)
2484
+ withdrawFee = self.safe_number(networkEntry, 'withdrawFee')
2485
+ isDefault = self.safe_value(networkEntry, 'isDefault')
2486
+ if withdrawFee is not None:
2487
+ if isDefault:
2488
+ result['withdraw'] = {
2489
+ 'fee': withdrawFee,
2490
+ 'percentage': None,
2491
+ }
2492
+ result['networks'][networkCode] = {
2493
+ 'withdraw': {
2494
+ 'fee': withdrawFee,
2495
+ 'percentage': None,
2496
+ },
2497
+ 'deposit': {
2498
+ 'fee': None,
2499
+ 'percentage': None,
2500
+ },
2501
+ }
2502
+ return result
2503
+
2504
+ def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
2505
+ query = self.omit(params, self.extract_params(path))
2506
+ url = self.urls['api']['rest'] + '/' + self.version + '/' + self.implode_params(path, params)
2507
+ # Every spot endpoint ends with ".do"
2508
+ if api[0] == 'spot':
2509
+ url += '.do'
2510
+ else:
2511
+ url = self.urls['api']['contract'] + '/' + self.implode_params(path, params)
2512
+ if api[1] == 'public':
2513
+ if query:
2514
+ url += '?' + self.urlencode(self.keysort(query))
2515
+ else:
2516
+ self.check_required_credentials()
2517
+ timestamp = str(self.milliseconds())
2518
+ echostr = self.uuid22() + self.uuid16()
2519
+ query = self.extend({
2520
+ 'api_key': self.apiKey,
2521
+ }, query)
2522
+ signatureMethod = None
2523
+ if len(self.secret) > 32:
2524
+ signatureMethod = 'RSA'
2525
+ else:
2526
+ signatureMethod = 'HmacSHA256'
2527
+ auth = self.rawencode(self.keysort(self.extend({
2528
+ 'echostr': echostr,
2529
+ 'signature_method': signatureMethod,
2530
+ 'timestamp': timestamp,
2531
+ }, query)))
2532
+ encoded = self.encode(auth)
2533
+ hash = self.hash(encoded, 'md5')
2534
+ uppercaseHash = hash.upper()
2535
+ sign = None
2536
+ if signatureMethod == 'RSA':
2537
+ cacheSecretAsPem = self.safe_bool(self.options, 'cacheSecretAsPem', True)
2538
+ pem = None
2539
+ if cacheSecretAsPem:
2540
+ pem = self.safe_value(self.options, 'pem')
2541
+ if pem is None:
2542
+ pem = self.convert_secret_to_pem(self.encode(self.secret))
2543
+ self.options['pem'] = pem
2544
+ else:
2545
+ pem = self.convert_secret_to_pem(self.encode(self.secret))
2546
+ sign = self.rsa(uppercaseHash, pem, 'sha256')
2547
+ elif signatureMethod == 'HmacSHA256':
2548
+ sign = self.hmac(self.encode(uppercaseHash), self.encode(self.secret), hashlib.sha256)
2549
+ query['sign'] = sign
2550
+ body = self.urlencode(self.keysort(query))
2551
+ headers = {
2552
+ 'Content-Type': 'application/x-www-form-urlencoded',
2553
+ 'timestamp': timestamp,
2554
+ 'signature_method': signatureMethod,
2555
+ 'echostr': echostr,
2556
+ }
2557
+ return {'url': url, 'method': method, 'body': body, 'headers': headers}
2558
+
2559
+ def convert_secret_to_pem(self, secret):
2560
+ lineLength = 64
2561
+ secretLength = len(secret) - 0
2562
+ numLines = self.parse_to_int(secretLength / lineLength)
2563
+ numLines = self.sum(numLines, 1)
2564
+ pem = "-----BEGIN PRIVATE KEY-----\n" # eslint-disable-line
2565
+ for i in range(0, numLines):
2566
+ start = i * lineLength
2567
+ end = self.sum(start, lineLength)
2568
+ pem += self.secret[start:end] + "\n" # eslint-disable-line
2569
+ return pem + '-----END PRIVATE KEY-----'
2570
+
2571
+ def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
2572
+ if response is None:
2573
+ return None
2574
+ success = self.safe_value(response, 'result')
2575
+ if success == 'false' or not success:
2576
+ errorCode = self.safe_string(response, 'error_code')
2577
+ message = self.safe_string({
2578
+ '10000': 'Internal error',
2579
+ '10001': 'The required parameters can not be empty',
2580
+ '10002': 'Validation failed',
2581
+ '10003': 'Invalid parameter',
2582
+ '10004': 'Request too frequent',
2583
+ '10005': 'Secret key does not exist',
2584
+ '10006': 'User does not exist',
2585
+ '10007': 'Invalid signature',
2586
+ '10008': 'Invalid Trading Pair',
2587
+ '10009': 'Price and/or Amount are required for limit order',
2588
+ '10010': 'Price and/or Amount must be less than minimum requirement',
2589
+ # '10011': 'Market orders can not be missing the amount of the order',
2590
+ # '10012': 'market sell orders can not be missing orders',
2591
+ '10013': 'The amount is too small',
2592
+ '10014': 'Insufficient amount of money in the account',
2593
+ '10015': 'Invalid order type',
2594
+ '10016': 'Insufficient account balance',
2595
+ '10017': 'Server Error',
2596
+ '10018': 'Page size should be between 1 and 50',
2597
+ '10019': 'Cancel NO more than 3 orders in one request',
2598
+ '10020': 'Volume < 0.001',
2599
+ '10021': 'Price < 0.01',
2600
+ '10022': 'Invalid authorization',
2601
+ '10023': 'Market Order is not supported yet',
2602
+ '10024': 'User cannot trade on self pair',
2603
+ '10025': 'Order has been filled',
2604
+ '10026': 'Order has been cancelld',
2605
+ '10027': 'Order is cancelling',
2606
+ '10028': 'Wrong query time',
2607
+ '10029': 'from is not in the query time',
2608
+ '10030': 'from do not match the transaction type of inqury',
2609
+ '10031': 'echostr length must be valid and length must be from 30 to 40',
2610
+ '10033': 'Failed to create order',
2611
+ '10036': 'customID duplicated',
2612
+ '10100': 'Has no privilege to withdraw',
2613
+ '10101': 'Invalid fee rate to withdraw',
2614
+ '10102': 'Too little to withdraw',
2615
+ '10103': 'Exceed daily limitation of withdraw',
2616
+ '10104': 'Cancel was rejected',
2617
+ '10105': 'Request has been cancelled',
2618
+ '10106': 'None trade time',
2619
+ '10107': 'Start price exception',
2620
+ '10108': 'can not create order',
2621
+ '10109': 'wallet address is not mapping',
2622
+ '10110': 'transfer fee is not mapping',
2623
+ '10111': 'mount > 0',
2624
+ '10112': 'fee is too lower',
2625
+ '10113': 'transfer fee is 0',
2626
+ '10600': 'intercepted by replay attacks filter, check timestamp',
2627
+ '10601': 'Interface closed unavailable',
2628
+ '10701': 'invalid asset code',
2629
+ '10702': 'not allowed deposit',
2630
+ }, errorCode, self.json(response))
2631
+ ErrorClass = self.safe_value({
2632
+ '10001': BadRequest,
2633
+ '10002': AuthenticationError,
2634
+ '10003': BadRequest,
2635
+ '10004': RateLimitExceeded,
2636
+ '10005': AuthenticationError,
2637
+ '10006': AuthenticationError,
2638
+ '10007': AuthenticationError,
2639
+ '10008': BadSymbol,
2640
+ '10009': InvalidOrder,
2641
+ '10010': InvalidOrder,
2642
+ '10013': InvalidOrder,
2643
+ '10014': InsufficientFunds,
2644
+ '10015': InvalidOrder,
2645
+ '10016': InsufficientFunds,
2646
+ '10017': ExchangeError,
2647
+ '10018': BadRequest,
2648
+ '10019': BadRequest,
2649
+ '10020': BadRequest,
2650
+ '10021': InvalidOrder,
2651
+ '10022': PermissionDenied, # 'Invalid authorization',
2652
+ '10023': InvalidOrder, # 'Market Order is not supported yet',
2653
+ '10024': PermissionDenied, # 'User cannot trade on self pair',
2654
+ '10025': InvalidOrder, # 'Order has been filled',
2655
+ '10026': InvalidOrder, # 'Order has been cancelled',
2656
+ '10027': InvalidOrder, # 'Order is cancelling',
2657
+ '10028': BadRequest, # 'Wrong query time',
2658
+ '10029': BadRequest, # 'from is not in the query time',
2659
+ '10030': BadRequest, # 'from do not match the transaction type of inqury',
2660
+ '10031': InvalidNonce, # 'echostr length must be valid and length must be from 30 to 40',
2661
+ '10033': ExchangeError, # 'Failed to create order',
2662
+ '10036': DuplicateOrderId, # 'customID duplicated',
2663
+ '10100': PermissionDenied, # 'Has no privilege to withdraw',
2664
+ '10101': BadRequest, # 'Invalid fee rate to withdraw',
2665
+ '10102': InsufficientFunds, # 'Too little to withdraw',
2666
+ '10103': ExchangeError, # 'Exceed daily limitation of withdraw',
2667
+ '10104': ExchangeError, # 'Cancel was rejected',
2668
+ '10105': ExchangeError, # 'Request has been cancelled',
2669
+ '10106': BadRequest, # 'None trade time',
2670
+ '10107': BadRequest, # 'Start price exception',
2671
+ '10108': ExchangeError, # 'can not create order',
2672
+ '10109': InvalidAddress, # 'wallet address is not mapping',
2673
+ '10110': ExchangeError, # 'transfer fee is not mapping',
2674
+ '10111': BadRequest, # 'mount > 0',
2675
+ '10112': BadRequest, # 'fee is too lower',
2676
+ '10113': BadRequest, # 'transfer fee is 0',
2677
+ '10600': BadRequest, # 'intercepted by replay attacks filter, check timestamp',
2678
+ '10601': ExchangeError, # 'Interface closed unavailable',
2679
+ '10701': BadSymbol, # 'invalid asset code',
2680
+ '10702': PermissionDenied, # 'not allowed deposit',
2681
+ }, errorCode, ExchangeError)
2682
+ raise ErrorClass(message)
2683
+ return None