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