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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (772) hide show
  1. ccxt/__init__.py +358 -0
  2. ccxt/abantether.py +316 -0
  3. ccxt/abstract/__init__.py +0 -0
  4. ccxt/abstract/abantether.py +5 -0
  5. ccxt/abstract/ace.py +15 -0
  6. ccxt/abstract/afratether.py +6 -0
  7. ccxt/abstract/alpaca.py +70 -0
  8. ccxt/abstract/arzinja.py +5 -0
  9. ccxt/abstract/arzplus.py +7 -0
  10. ccxt/abstract/ascendex.py +77 -0
  11. ccxt/abstract/bequant.py +115 -0
  12. ccxt/abstract/bigone.py +45 -0
  13. ccxt/abstract/binance.py +712 -0
  14. ccxt/abstract/binancecoinm.py +712 -0
  15. ccxt/abstract/binanceus.py +764 -0
  16. ccxt/abstract/binanceusdm.py +712 -0
  17. ccxt/abstract/bingx.py +113 -0
  18. ccxt/abstract/bit2c.py +27 -0
  19. ccxt/abstract/bitbank.py +27 -0
  20. ccxt/abstract/bitbay.py +53 -0
  21. ccxt/abstract/bitbns.py +40 -0
  22. ccxt/abstract/bitcoincom.py +115 -0
  23. ccxt/abstract/bitfinex.py +69 -0
  24. ccxt/abstract/bitfinex2.py +139 -0
  25. ccxt/abstract/bitflyer.py +38 -0
  26. ccxt/abstract/bitget.py +508 -0
  27. ccxt/abstract/bithumb.py +32 -0
  28. ccxt/abstract/bitimen.py +7 -0
  29. ccxt/abstract/bitir.py +7 -0
  30. ccxt/abstract/bitmart.py +99 -0
  31. ccxt/abstract/bitmex.py +97 -0
  32. ccxt/abstract/bitopro.py +29 -0
  33. ccxt/abstract/bitpanda.py +35 -0
  34. ccxt/abstract/bitpin.py +7 -0
  35. ccxt/abstract/bitrue.py +72 -0
  36. ccxt/abstract/bitso.py +43 -0
  37. ccxt/abstract/bitstamp.py +258 -0
  38. ccxt/abstract/bitteam.py +29 -0
  39. ccxt/abstract/bitvavo.py +27 -0
  40. ccxt/abstract/bl3p.py +19 -0
  41. ccxt/abstract/blockchaincom.py +28 -0
  42. ccxt/abstract/blofin.py +37 -0
  43. ccxt/abstract/btcalpha.py +18 -0
  44. ccxt/abstract/btcbox.py +13 -0
  45. ccxt/abstract/btcmarkets.py +39 -0
  46. ccxt/abstract/btcturk.py +20 -0
  47. ccxt/abstract/bybit.py +298 -0
  48. ccxt/abstract/cex.py +33 -0
  49. ccxt/abstract/coinbase.py +94 -0
  50. ccxt/abstract/coinbaseadvanced.py +94 -0
  51. ccxt/abstract/coinbaseexchange.py +67 -0
  52. ccxt/abstract/coinbaseinternational.py +39 -0
  53. ccxt/abstract/coincatch.py +94 -0
  54. ccxt/abstract/coincheck.py +33 -0
  55. ccxt/abstract/coinex.py +237 -0
  56. ccxt/abstract/coinlist.py +54 -0
  57. ccxt/abstract/coinmate.py +62 -0
  58. ccxt/abstract/coinmetro.py +34 -0
  59. ccxt/abstract/coinone.py +67 -0
  60. ccxt/abstract/coinsph.py +54 -0
  61. ccxt/abstract/coinspot.py +28 -0
  62. ccxt/abstract/cryptocom.py +107 -0
  63. ccxt/abstract/currencycom.py +68 -0
  64. ccxt/abstract/delta.py +50 -0
  65. ccxt/abstract/deribit.py +125 -0
  66. ccxt/abstract/digifinex.py +91 -0
  67. ccxt/abstract/eterex.py +5 -0
  68. ccxt/abstract/excoino.py +7 -0
  69. ccxt/abstract/exir.py +8 -0
  70. ccxt/abstract/exmo.py +55 -0
  71. ccxt/abstract/exnovin.py +6 -0
  72. ccxt/abstract/farhadexchange.py +5 -0
  73. ccxt/abstract/fmfwio.py +115 -0
  74. ccxt/abstract/gate.py +265 -0
  75. ccxt/abstract/gateio.py +265 -0
  76. ccxt/abstract/gemini.py +58 -0
  77. ccxt/abstract/hashkey.py +67 -0
  78. ccxt/abstract/hitbtc.py +115 -0
  79. ccxt/abstract/hitbtc3.py +115 -0
  80. ccxt/abstract/hitobit.py +8 -0
  81. ccxt/abstract/hollaex.py +33 -0
  82. ccxt/abstract/htx.py +548 -0
  83. ccxt/abstract/huobi.py +548 -0
  84. ccxt/abstract/huobijp.py +114 -0
  85. ccxt/abstract/hyperliquid.py +6 -0
  86. ccxt/abstract/idex.py +26 -0
  87. ccxt/abstract/independentreserve.py +37 -0
  88. ccxt/abstract/indodax.py +26 -0
  89. ccxt/abstract/jibitex.py +7 -0
  90. ccxt/abstract/kraken.py +57 -0
  91. ccxt/abstract/krakenfutures.py +38 -0
  92. ccxt/abstract/kucoin.py +214 -0
  93. ccxt/abstract/kucoinfutures.py +233 -0
  94. ccxt/abstract/kuna.py +182 -0
  95. ccxt/abstract/latoken.py +56 -0
  96. ccxt/abstract/lbank.py +61 -0
  97. ccxt/abstract/luno.py +37 -0
  98. ccxt/abstract/lykke.py +29 -0
  99. ccxt/abstract/mercado.py +25 -0
  100. ccxt/abstract/mexc.py +178 -0
  101. ccxt/abstract/ndax.py +97 -0
  102. ccxt/abstract/nobitex.py +7 -0
  103. ccxt/abstract/novadax.py +29 -0
  104. ccxt/abstract/oceanex.py +22 -0
  105. ccxt/abstract/okcoin.py +74 -0
  106. ccxt/abstract/okexchange.py +8 -0
  107. ccxt/abstract/okx.py +324 -0
  108. ccxt/abstract/ompfinex.py +7 -0
  109. ccxt/abstract/onetrading.py +35 -0
  110. ccxt/abstract/oxfun.py +34 -0
  111. ccxt/abstract/p2b.py +22 -0
  112. ccxt/abstract/paradex.py +40 -0
  113. ccxt/abstract/paymium.py +28 -0
  114. ccxt/abstract/phemex.py +115 -0
  115. ccxt/abstract/poloniex.py +69 -0
  116. ccxt/abstract/poloniexfutures.py +48 -0
  117. ccxt/abstract/probit.py +23 -0
  118. ccxt/abstract/ramzinex.py +7 -0
  119. ccxt/abstract/sarmayex.py +5 -0
  120. ccxt/abstract/sarrafex.py +7 -0
  121. ccxt/abstract/tabdeal.py +7 -0
  122. ccxt/abstract/tetherland.py +5 -0
  123. ccxt/abstract/timex.py +62 -0
  124. ccxt/abstract/tokocrypto.py +37 -0
  125. ccxt/abstract/tradeogre.py +16 -0
  126. ccxt/abstract/twox.py +5 -0
  127. ccxt/abstract/ubitex.py +7 -0
  128. ccxt/abstract/upbit.py +38 -0
  129. ccxt/abstract/vertex.py +19 -0
  130. ccxt/abstract/wallex.py +8 -0
  131. ccxt/abstract/wavesexchange.py +154 -0
  132. ccxt/abstract/wazirx.py +30 -0
  133. ccxt/abstract/whitebit.py +98 -0
  134. ccxt/abstract/woo.py +83 -0
  135. ccxt/abstract/woofipro.py +119 -0
  136. ccxt/abstract/xt.py +152 -0
  137. ccxt/abstract/yobit.py +16 -0
  138. ccxt/abstract/zaif.py +38 -0
  139. ccxt/abstract/zonda.py +53 -0
  140. ccxt/ace.py +1012 -0
  141. ccxt/afratether.py +293 -0
  142. ccxt/alpaca.py +1083 -0
  143. ccxt/arzinja.py +285 -0
  144. ccxt/arzplus.py +412 -0
  145. ccxt/ascendex.py +3330 -0
  146. ccxt/async_support/__init__.py +337 -0
  147. ccxt/async_support/abantether.py +316 -0
  148. ccxt/async_support/ace.py +1012 -0
  149. ccxt/async_support/afratether.py +293 -0
  150. ccxt/async_support/alpaca.py +1083 -0
  151. ccxt/async_support/arzinja.py +285 -0
  152. ccxt/async_support/arzplus.py +412 -0
  153. ccxt/async_support/ascendex.py +3330 -0
  154. ccxt/async_support/base/__init__.py +1 -0
  155. ccxt/async_support/base/exchange.py +1966 -0
  156. ccxt/async_support/base/throttler.py +50 -0
  157. ccxt/async_support/base/ws/__init__.py +38 -0
  158. ccxt/async_support/base/ws/aiohttp_client.py +125 -0
  159. ccxt/async_support/base/ws/cache.py +212 -0
  160. ccxt/async_support/base/ws/client.py +193 -0
  161. ccxt/async_support/base/ws/fast_client.py +96 -0
  162. ccxt/async_support/base/ws/functions.py +59 -0
  163. ccxt/async_support/base/ws/future.py +58 -0
  164. ccxt/async_support/base/ws/order_book.py +78 -0
  165. ccxt/async_support/base/ws/order_book_side.py +174 -0
  166. ccxt/async_support/bequant.py +33 -0
  167. ccxt/async_support/bigone.py +2113 -0
  168. ccxt/async_support/binance.py +12234 -0
  169. ccxt/async_support/binancecoinm.py +45 -0
  170. ccxt/async_support/binanceus.py +211 -0
  171. ccxt/async_support/binanceusdm.py +58 -0
  172. ccxt/async_support/bingx.py +4325 -0
  173. ccxt/async_support/bit2c.py +866 -0
  174. ccxt/async_support/bitbank.py +1001 -0
  175. ccxt/async_support/bitbay.py +17 -0
  176. ccxt/async_support/bitbns.py +1154 -0
  177. ccxt/async_support/bitcoincom.py +17 -0
  178. ccxt/async_support/bitfinex.py +1617 -0
  179. ccxt/async_support/bitfinex2.py +3552 -0
  180. ccxt/async_support/bitflyer.py +995 -0
  181. ccxt/async_support/bitget.py +8273 -0
  182. ccxt/async_support/bithumb.py +1061 -0
  183. ccxt/async_support/bitimen.py +401 -0
  184. ccxt/async_support/bitir.py +490 -0
  185. ccxt/async_support/bitmart.py +4415 -0
  186. ccxt/async_support/bitmex.py +2756 -0
  187. ccxt/async_support/bitopro.py +1630 -0
  188. ccxt/async_support/bitpanda.py +16 -0
  189. ccxt/async_support/bitpin.py +454 -0
  190. ccxt/async_support/bitrue.py +3027 -0
  191. ccxt/async_support/bitso.py +1670 -0
  192. ccxt/async_support/bitstamp.py +2203 -0
  193. ccxt/async_support/bitteam.py +2239 -0
  194. ccxt/async_support/bitvavo.py +1968 -0
  195. ccxt/async_support/bl3p.py +485 -0
  196. ccxt/async_support/blockchaincom.py +1104 -0
  197. ccxt/async_support/blofin.py +2066 -0
  198. ccxt/async_support/btcalpha.py +891 -0
  199. ccxt/async_support/btcbox.py +544 -0
  200. ccxt/async_support/btcmarkets.py +1221 -0
  201. ccxt/async_support/btcturk.py +911 -0
  202. ccxt/async_support/bybit.py +8159 -0
  203. ccxt/async_support/cex.py +1605 -0
  204. ccxt/async_support/coinbase.py +4475 -0
  205. ccxt/async_support/coinbaseadvanced.py +17 -0
  206. ccxt/async_support/coinbaseexchange.py +1734 -0
  207. ccxt/async_support/coinbaseinternational.py +1899 -0
  208. ccxt/async_support/coincatch.py +5069 -0
  209. ccxt/async_support/coincheck.py +815 -0
  210. ccxt/async_support/coinex.py +5526 -0
  211. ccxt/async_support/coinlist.py +2243 -0
  212. ccxt/async_support/coinmate.py +1067 -0
  213. ccxt/async_support/coinmetro.py +1797 -0
  214. ccxt/async_support/coinone.py +1127 -0
  215. ccxt/async_support/coinsph.py +1850 -0
  216. ccxt/async_support/coinspot.py +534 -0
  217. ccxt/async_support/cryptocom.py +2822 -0
  218. ccxt/async_support/currencycom.py +1950 -0
  219. ccxt/async_support/delta.py +3376 -0
  220. ccxt/async_support/deribit.py +3437 -0
  221. ccxt/async_support/digifinex.py +3960 -0
  222. ccxt/async_support/eterex.py +286 -0
  223. ccxt/async_support/excoino.py +399 -0
  224. ccxt/async_support/exir.py +375 -0
  225. ccxt/async_support/exmo.py +2462 -0
  226. ccxt/async_support/exnovin.py +360 -0
  227. ccxt/async_support/farhadexchange.py +266 -0
  228. ccxt/async_support/fmfwio.py +34 -0
  229. ccxt/async_support/gate.py +6976 -0
  230. ccxt/async_support/gateio.py +16 -0
  231. ccxt/async_support/gemini.py +1825 -0
  232. ccxt/async_support/hashkey.py +4150 -0
  233. ccxt/async_support/hitbtc.py +3423 -0
  234. ccxt/async_support/hitbtc3.py +16 -0
  235. ccxt/async_support/hitobit.py +391 -0
  236. ccxt/async_support/hollaex.py +1813 -0
  237. ccxt/async_support/htx.py +8506 -0
  238. ccxt/async_support/huobi.py +16 -0
  239. ccxt/async_support/huobijp.py +1801 -0
  240. ccxt/async_support/hyperliquid.py +2431 -0
  241. ccxt/async_support/idex.py +1766 -0
  242. ccxt/async_support/independentreserve.py +784 -0
  243. ccxt/async_support/indodax.py +1247 -0
  244. ccxt/async_support/jibitex.py +395 -0
  245. ccxt/async_support/kraken.py +2894 -0
  246. ccxt/async_support/krakenfutures.py +2601 -0
  247. ccxt/async_support/kucoin.py +4602 -0
  248. ccxt/async_support/kucoinfutures.py +2698 -0
  249. ccxt/async_support/kuna.py +1841 -0
  250. ccxt/async_support/latoken.py +1664 -0
  251. ccxt/async_support/lbank.py +2683 -0
  252. ccxt/async_support/luno.py +1067 -0
  253. ccxt/async_support/lykke.py +1270 -0
  254. ccxt/async_support/mercado.py +842 -0
  255. ccxt/async_support/mexc.py +5369 -0
  256. ccxt/async_support/ndax.py +2354 -0
  257. ccxt/async_support/nobitex.py +419 -0
  258. ccxt/async_support/novadax.py +1484 -0
  259. ccxt/async_support/oceanex.py +903 -0
  260. ccxt/async_support/okcoin.py +2936 -0
  261. ccxt/async_support/okexchange.py +349 -0
  262. ccxt/async_support/okx.py +7827 -0
  263. ccxt/async_support/ompfinex.py +472 -0
  264. ccxt/async_support/onetrading.py +1911 -0
  265. ccxt/async_support/oxfun.py +2773 -0
  266. ccxt/async_support/p2b.py +1194 -0
  267. ccxt/async_support/paradex.py +2015 -0
  268. ccxt/async_support/paymium.py +564 -0
  269. ccxt/async_support/phemex.py +4473 -0
  270. ccxt/async_support/poloniex.py +2232 -0
  271. ccxt/async_support/poloniexfutures.py +1717 -0
  272. ccxt/async_support/probit.py +1734 -0
  273. ccxt/async_support/ramzinex.py +476 -0
  274. ccxt/async_support/sarmayex.py +357 -0
  275. ccxt/async_support/sarrafex.py +478 -0
  276. ccxt/async_support/tabdeal.py +364 -0
  277. ccxt/async_support/tetherland.py +349 -0
  278. ccxt/async_support/timex.py +1593 -0
  279. ccxt/async_support/tokocrypto.py +2405 -0
  280. ccxt/async_support/tradeogre.py +608 -0
  281. ccxt/async_support/twox.py +326 -0
  282. ccxt/async_support/ubitex.py +409 -0
  283. ccxt/async_support/upbit.py +1833 -0
  284. ccxt/async_support/vertex.py +2922 -0
  285. ccxt/async_support/wallex.py +445 -0
  286. ccxt/async_support/wavesexchange.py +2473 -0
  287. ccxt/async_support/wazirx.py +1224 -0
  288. ccxt/async_support/whitebit.py +2469 -0
  289. ccxt/async_support/woo.py +3114 -0
  290. ccxt/async_support/woofipro.py +2533 -0
  291. ccxt/async_support/xt.py +4454 -0
  292. ccxt/async_support/yobit.py +1283 -0
  293. ccxt/async_support/zaif.py +725 -0
  294. ccxt/async_support/zonda.py +1828 -0
  295. ccxt/base/__init__.py +27 -0
  296. ccxt/base/decimal_to_precision.py +174 -0
  297. ccxt/base/errors.py +242 -0
  298. ccxt/base/exchange.py +5941 -0
  299. ccxt/base/precise.py +287 -0
  300. ccxt/base/types.py +502 -0
  301. ccxt/bequant.py +33 -0
  302. ccxt/bigone.py +2112 -0
  303. ccxt/binance.py +12233 -0
  304. ccxt/binancecoinm.py +45 -0
  305. ccxt/binanceus.py +211 -0
  306. ccxt/binanceusdm.py +58 -0
  307. ccxt/bingx.py +4324 -0
  308. ccxt/bit2c.py +866 -0
  309. ccxt/bitbank.py +1001 -0
  310. ccxt/bitbay.py +17 -0
  311. ccxt/bitbns.py +1154 -0
  312. ccxt/bitcoincom.py +17 -0
  313. ccxt/bitfinex.py +1617 -0
  314. ccxt/bitfinex2.py +3552 -0
  315. ccxt/bitflyer.py +995 -0
  316. ccxt/bitget.py +8272 -0
  317. ccxt/bithumb.py +1061 -0
  318. ccxt/bitimen.py +401 -0
  319. ccxt/bitir.py +490 -0
  320. ccxt/bitmart.py +4415 -0
  321. ccxt/bitmex.py +2756 -0
  322. ccxt/bitopro.py +1630 -0
  323. ccxt/bitpanda.py +16 -0
  324. ccxt/bitpin.py +454 -0
  325. ccxt/bitrue.py +3026 -0
  326. ccxt/bitso.py +1670 -0
  327. ccxt/bitstamp.py +2203 -0
  328. ccxt/bitteam.py +2239 -0
  329. ccxt/bitvavo.py +1968 -0
  330. ccxt/bl3p.py +485 -0
  331. ccxt/blockchaincom.py +1104 -0
  332. ccxt/blofin.py +2066 -0
  333. ccxt/btcalpha.py +891 -0
  334. ccxt/btcbox.py +544 -0
  335. ccxt/btcmarkets.py +1221 -0
  336. ccxt/btcturk.py +911 -0
  337. ccxt/bybit.py +8158 -0
  338. ccxt/cex.py +1605 -0
  339. ccxt/coinbase.py +4474 -0
  340. ccxt/coinbaseadvanced.py +17 -0
  341. ccxt/coinbaseexchange.py +1734 -0
  342. ccxt/coinbaseinternational.py +1899 -0
  343. ccxt/coincatch.py +5069 -0
  344. ccxt/coincheck.py +815 -0
  345. ccxt/coinex.py +5525 -0
  346. ccxt/coinlist.py +2243 -0
  347. ccxt/coinmate.py +1067 -0
  348. ccxt/coinmetro.py +1797 -0
  349. ccxt/coinone.py +1127 -0
  350. ccxt/coinsph.py +1850 -0
  351. ccxt/coinspot.py +534 -0
  352. ccxt/cryptocom.py +2822 -0
  353. ccxt/currencycom.py +1950 -0
  354. ccxt/delta.py +3376 -0
  355. ccxt/deribit.py +3437 -0
  356. ccxt/digifinex.py +3959 -0
  357. ccxt/eterex.py +286 -0
  358. ccxt/excoino.py +399 -0
  359. ccxt/exir.py +375 -0
  360. ccxt/exmo.py +2462 -0
  361. ccxt/exnovin.py +360 -0
  362. ccxt/farhadexchange.py +266 -0
  363. ccxt/fmfwio.py +34 -0
  364. ccxt/gate.py +6975 -0
  365. ccxt/gateio.py +16 -0
  366. ccxt/gemini.py +1824 -0
  367. ccxt/hashkey.py +4150 -0
  368. ccxt/hitbtc.py +3423 -0
  369. ccxt/hitbtc3.py +16 -0
  370. ccxt/hitobit.py +391 -0
  371. ccxt/hollaex.py +1813 -0
  372. ccxt/htx.py +8505 -0
  373. ccxt/huobi.py +16 -0
  374. ccxt/huobijp.py +1801 -0
  375. ccxt/hyperliquid.py +2430 -0
  376. ccxt/idex.py +1766 -0
  377. ccxt/independentreserve.py +784 -0
  378. ccxt/indodax.py +1247 -0
  379. ccxt/jibitex.py +395 -0
  380. ccxt/kraken.py +2894 -0
  381. ccxt/krakenfutures.py +2601 -0
  382. ccxt/kucoin.py +4601 -0
  383. ccxt/kucoinfutures.py +2698 -0
  384. ccxt/kuna.py +1841 -0
  385. ccxt/latoken.py +1664 -0
  386. ccxt/lbank.py +2682 -0
  387. ccxt/luno.py +1067 -0
  388. ccxt/lykke.py +1270 -0
  389. ccxt/mercado.py +842 -0
  390. ccxt/mexc.py +5369 -0
  391. ccxt/ndax.py +2354 -0
  392. ccxt/nobitex.py +419 -0
  393. ccxt/novadax.py +1484 -0
  394. ccxt/oceanex.py +903 -0
  395. ccxt/okcoin.py +2936 -0
  396. ccxt/okexchange.py +349 -0
  397. ccxt/okx.py +7826 -0
  398. ccxt/ompfinex.py +472 -0
  399. ccxt/onetrading.py +1911 -0
  400. ccxt/oxfun.py +2772 -0
  401. ccxt/p2b.py +1194 -0
  402. ccxt/paradex.py +2015 -0
  403. ccxt/paymium.py +564 -0
  404. ccxt/phemex.py +4473 -0
  405. ccxt/poloniex.py +2232 -0
  406. ccxt/poloniexfutures.py +1717 -0
  407. ccxt/pro/__init__.py +149 -0
  408. ccxt/pro/alpaca.py +685 -0
  409. ccxt/pro/ascendex.py +916 -0
  410. ccxt/pro/bequant.py +38 -0
  411. ccxt/pro/binance.py +3488 -0
  412. ccxt/pro/binancecoinm.py +28 -0
  413. ccxt/pro/binanceus.py +48 -0
  414. ccxt/pro/binanceusdm.py +31 -0
  415. ccxt/pro/bingx.py +1264 -0
  416. ccxt/pro/bitcoincom.py +34 -0
  417. ccxt/pro/bitfinex.py +621 -0
  418. ccxt/pro/bitfinex2.py +1083 -0
  419. ccxt/pro/bitget.py +1692 -0
  420. ccxt/pro/bithumb.py +368 -0
  421. ccxt/pro/bitmart.py +1449 -0
  422. ccxt/pro/bitmex.py +1656 -0
  423. ccxt/pro/bitopro.py +445 -0
  424. ccxt/pro/bitpanda.py +15 -0
  425. ccxt/pro/bitrue.py +447 -0
  426. ccxt/pro/bitstamp.py +522 -0
  427. ccxt/pro/bitvavo.py +1270 -0
  428. ccxt/pro/blockchaincom.py +738 -0
  429. ccxt/pro/blofin.py +692 -0
  430. ccxt/pro/bybit.py +2000 -0
  431. ccxt/pro/cex.py +1440 -0
  432. ccxt/pro/coinbase.py +678 -0
  433. ccxt/pro/coinbaseadvanced.py +16 -0
  434. ccxt/pro/coinbaseexchange.py +895 -0
  435. ccxt/pro/coinbaseinternational.py +620 -0
  436. ccxt/pro/coincatch.py +1464 -0
  437. ccxt/pro/coincheck.py +199 -0
  438. ccxt/pro/coinex.py +1061 -0
  439. ccxt/pro/coinone.py +395 -0
  440. ccxt/pro/cryptocom.py +947 -0
  441. ccxt/pro/currencycom.py +536 -0
  442. ccxt/pro/deribit.py +892 -0
  443. ccxt/pro/exmo.py +629 -0
  444. ccxt/pro/gate.py +1416 -0
  445. ccxt/pro/gateio.py +15 -0
  446. ccxt/pro/gemini.py +865 -0
  447. ccxt/pro/hashkey.py +802 -0
  448. ccxt/pro/hitbtc.py +1216 -0
  449. ccxt/pro/hollaex.py +563 -0
  450. ccxt/pro/htx.py +2215 -0
  451. ccxt/pro/huobi.py +15 -0
  452. ccxt/pro/huobijp.py +570 -0
  453. ccxt/pro/hyperliquid.py +525 -0
  454. ccxt/pro/idex.py +672 -0
  455. ccxt/pro/independentreserve.py +270 -0
  456. ccxt/pro/kraken.py +1356 -0
  457. ccxt/pro/krakenfutures.py +1492 -0
  458. ccxt/pro/kucoin.py +1133 -0
  459. ccxt/pro/kucoinfutures.py +1081 -0
  460. ccxt/pro/lbank.py +843 -0
  461. ccxt/pro/luno.py +303 -0
  462. ccxt/pro/mexc.py +1122 -0
  463. ccxt/pro/ndax.py +506 -0
  464. ccxt/pro/okcoin.py +698 -0
  465. ccxt/pro/okx.py +1851 -0
  466. ccxt/pro/onetrading.py +1275 -0
  467. ccxt/pro/oxfun.py +950 -0
  468. ccxt/pro/p2b.py +419 -0
  469. ccxt/pro/paradex.py +352 -0
  470. ccxt/pro/phemex.py +1441 -0
  471. ccxt/pro/poloniex.py +1166 -0
  472. ccxt/pro/poloniexfutures.py +990 -0
  473. ccxt/pro/probit.py +551 -0
  474. ccxt/pro/upbit.py +520 -0
  475. ccxt/pro/vertex.py +943 -0
  476. ccxt/pro/wazirx.py +749 -0
  477. ccxt/pro/whitebit.py +864 -0
  478. ccxt/pro/woo.py +1078 -0
  479. ccxt/pro/woofipro.py +1183 -0
  480. ccxt/pro/xt.py +1067 -0
  481. ccxt/probit.py +1734 -0
  482. ccxt/ramzinex.py +476 -0
  483. ccxt/sarmayex.py +357 -0
  484. ccxt/sarrafex.py +478 -0
  485. ccxt/static_dependencies/__init__.py +1 -0
  486. ccxt/static_dependencies/ecdsa/__init__.py +14 -0
  487. ccxt/static_dependencies/ecdsa/_version.py +520 -0
  488. ccxt/static_dependencies/ecdsa/curves.py +56 -0
  489. ccxt/static_dependencies/ecdsa/der.py +221 -0
  490. ccxt/static_dependencies/ecdsa/ecdsa.py +310 -0
  491. ccxt/static_dependencies/ecdsa/ellipticcurve.py +197 -0
  492. ccxt/static_dependencies/ecdsa/keys.py +332 -0
  493. ccxt/static_dependencies/ecdsa/numbertheory.py +531 -0
  494. ccxt/static_dependencies/ecdsa/rfc6979.py +100 -0
  495. ccxt/static_dependencies/ecdsa/util.py +266 -0
  496. ccxt/static_dependencies/ethereum/__init__.py +7 -0
  497. ccxt/static_dependencies/ethereum/abi/__init__.py +16 -0
  498. ccxt/static_dependencies/ethereum/abi/abi.py +19 -0
  499. ccxt/static_dependencies/ethereum/abi/base.py +152 -0
  500. ccxt/static_dependencies/ethereum/abi/codec.py +217 -0
  501. ccxt/static_dependencies/ethereum/abi/constants.py +3 -0
  502. ccxt/static_dependencies/ethereum/abi/decoding.py +565 -0
  503. ccxt/static_dependencies/ethereum/abi/encoding.py +720 -0
  504. ccxt/static_dependencies/ethereum/abi/exceptions.py +139 -0
  505. ccxt/static_dependencies/ethereum/abi/grammar.py +443 -0
  506. ccxt/static_dependencies/ethereum/abi/packed.py +13 -0
  507. ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
  508. ccxt/static_dependencies/ethereum/abi/registry.py +643 -0
  509. ccxt/static_dependencies/ethereum/abi/tools/__init__.py +3 -0
  510. ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +230 -0
  511. ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
  512. ccxt/static_dependencies/ethereum/abi/utils/numeric.py +83 -0
  513. ccxt/static_dependencies/ethereum/abi/utils/padding.py +27 -0
  514. ccxt/static_dependencies/ethereum/abi/utils/string.py +19 -0
  515. ccxt/static_dependencies/ethereum/account/__init__.py +3 -0
  516. ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +4 -0
  517. ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +239 -0
  518. ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +40 -0
  519. ccxt/static_dependencies/ethereum/account/messages.py +263 -0
  520. ccxt/static_dependencies/ethereum/account/py.typed +0 -0
  521. ccxt/static_dependencies/ethereum/hexbytes/__init__.py +5 -0
  522. ccxt/static_dependencies/ethereum/hexbytes/_utils.py +54 -0
  523. ccxt/static_dependencies/ethereum/hexbytes/main.py +65 -0
  524. ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
  525. ccxt/static_dependencies/ethereum/typing/__init__.py +63 -0
  526. ccxt/static_dependencies/ethereum/typing/abi.py +6 -0
  527. ccxt/static_dependencies/ethereum/typing/bls.py +7 -0
  528. ccxt/static_dependencies/ethereum/typing/discovery.py +5 -0
  529. ccxt/static_dependencies/ethereum/typing/encoding.py +7 -0
  530. ccxt/static_dependencies/ethereum/typing/enums.py +17 -0
  531. ccxt/static_dependencies/ethereum/typing/ethpm.py +9 -0
  532. ccxt/static_dependencies/ethereum/typing/evm.py +20 -0
  533. ccxt/static_dependencies/ethereum/typing/networks.py +1122 -0
  534. ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
  535. ccxt/static_dependencies/ethereum/utils/__init__.py +115 -0
  536. ccxt/static_dependencies/ethereum/utils/abi.py +72 -0
  537. ccxt/static_dependencies/ethereum/utils/address.py +171 -0
  538. ccxt/static_dependencies/ethereum/utils/applicators.py +151 -0
  539. ccxt/static_dependencies/ethereum/utils/conversions.py +190 -0
  540. ccxt/static_dependencies/ethereum/utils/currency.py +107 -0
  541. ccxt/static_dependencies/ethereum/utils/curried/__init__.py +269 -0
  542. ccxt/static_dependencies/ethereum/utils/debug.py +20 -0
  543. ccxt/static_dependencies/ethereum/utils/decorators.py +132 -0
  544. ccxt/static_dependencies/ethereum/utils/encoding.py +6 -0
  545. ccxt/static_dependencies/ethereum/utils/exceptions.py +4 -0
  546. ccxt/static_dependencies/ethereum/utils/functional.py +75 -0
  547. ccxt/static_dependencies/ethereum/utils/hexadecimal.py +74 -0
  548. ccxt/static_dependencies/ethereum/utils/humanize.py +188 -0
  549. ccxt/static_dependencies/ethereum/utils/logging.py +159 -0
  550. ccxt/static_dependencies/ethereum/utils/module_loading.py +31 -0
  551. ccxt/static_dependencies/ethereum/utils/numeric.py +43 -0
  552. ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
  553. ccxt/static_dependencies/ethereum/utils/toolz.py +76 -0
  554. ccxt/static_dependencies/ethereum/utils/types.py +54 -0
  555. ccxt/static_dependencies/ethereum/utils/typing/__init__.py +18 -0
  556. ccxt/static_dependencies/ethereum/utils/typing/misc.py +14 -0
  557. ccxt/static_dependencies/ethereum/utils/units.py +31 -0
  558. ccxt/static_dependencies/keccak/__init__.py +3 -0
  559. ccxt/static_dependencies/keccak/keccak.py +197 -0
  560. ccxt/static_dependencies/lark/__init__.py +38 -0
  561. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  562. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  563. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  564. ccxt/static_dependencies/lark/common.py +86 -0
  565. ccxt/static_dependencies/lark/exceptions.py +292 -0
  566. ccxt/static_dependencies/lark/grammar.py +130 -0
  567. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  568. ccxt/static_dependencies/lark/indenter.py +143 -0
  569. ccxt/static_dependencies/lark/lark.py +658 -0
  570. ccxt/static_dependencies/lark/lexer.py +678 -0
  571. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  572. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  573. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  574. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  575. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  576. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  577. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  578. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  579. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  580. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  581. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  582. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  583. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  584. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  585. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  586. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  587. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  588. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  589. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  590. ccxt/static_dependencies/lark/tree.py +267 -0
  591. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  592. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  593. ccxt/static_dependencies/lark/utils.py +343 -0
  594. ccxt/static_dependencies/lark/visitors.py +596 -0
  595. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  596. ccxt/static_dependencies/marshmallow/base.py +65 -0
  597. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  598. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  599. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  600. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  601. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  602. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  603. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  604. ccxt/static_dependencies/marshmallow/types.py +12 -0
  605. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  606. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  607. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  608. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  609. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  610. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  611. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  612. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  613. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  614. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  615. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  616. ccxt/static_dependencies/msgpack/__init__.py +55 -0
  617. ccxt/static_dependencies/msgpack/exceptions.py +48 -0
  618. ccxt/static_dependencies/msgpack/ext.py +168 -0
  619. ccxt/static_dependencies/msgpack/fallback.py +951 -0
  620. ccxt/static_dependencies/parsimonious/__init__.py +10 -0
  621. ccxt/static_dependencies/parsimonious/exceptions.py +105 -0
  622. ccxt/static_dependencies/parsimonious/expressions.py +479 -0
  623. ccxt/static_dependencies/parsimonious/grammar.py +487 -0
  624. ccxt/static_dependencies/parsimonious/nodes.py +325 -0
  625. ccxt/static_dependencies/parsimonious/utils.py +40 -0
  626. ccxt/static_dependencies/starknet/__init__.py +0 -0
  627. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  628. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  629. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  630. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  631. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  632. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  633. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  634. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  635. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  636. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  637. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  638. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  639. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  640. ccxt/static_dependencies/starknet/common.py +15 -0
  641. ccxt/static_dependencies/starknet/constants.py +39 -0
  642. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  643. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  644. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  645. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  646. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  647. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  648. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  649. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  650. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  651. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  652. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  653. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  654. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  655. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  656. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  657. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  658. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  659. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  660. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  661. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  662. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  663. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  664. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  665. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  666. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  667. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  668. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  669. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  670. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  671. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  672. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  673. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  674. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  675. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  676. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  677. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  678. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  679. ccxt/static_dependencies/starkware/__init__.py +0 -0
  680. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  681. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  682. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  683. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  684. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  685. ccxt/static_dependencies/sympy/__init__.py +0 -0
  686. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  687. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  688. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  689. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  690. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  691. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  692. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  693. ccxt/static_dependencies/toolz/__init__.py +26 -0
  694. ccxt/static_dependencies/toolz/_signatures.py +784 -0
  695. ccxt/static_dependencies/toolz/_version.py +520 -0
  696. ccxt/static_dependencies/toolz/compatibility.py +30 -0
  697. ccxt/static_dependencies/toolz/curried/__init__.py +101 -0
  698. ccxt/static_dependencies/toolz/curried/exceptions.py +22 -0
  699. ccxt/static_dependencies/toolz/curried/operator.py +22 -0
  700. ccxt/static_dependencies/toolz/dicttoolz.py +339 -0
  701. ccxt/static_dependencies/toolz/functoolz.py +1049 -0
  702. ccxt/static_dependencies/toolz/itertoolz.py +1057 -0
  703. ccxt/static_dependencies/toolz/recipes.py +46 -0
  704. ccxt/static_dependencies/toolz/utils.py +9 -0
  705. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  706. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  707. ccxt/tabdeal.py +364 -0
  708. ccxt/test/__init__.py +3 -0
  709. ccxt/test/base/__init__.py +29 -0
  710. ccxt/test/base/test_account.py +26 -0
  711. ccxt/test/base/test_balance.py +56 -0
  712. ccxt/test/base/test_borrow_interest.py +35 -0
  713. ccxt/test/base/test_borrow_rate.py +32 -0
  714. ccxt/test/base/test_calculate_fee.py +51 -0
  715. ccxt/test/base/test_crypto.py +127 -0
  716. ccxt/test/base/test_currency.py +76 -0
  717. ccxt/test/base/test_datetime.py +109 -0
  718. ccxt/test/base/test_decimal_to_precision.py +392 -0
  719. ccxt/test/base/test_deep_extend.py +68 -0
  720. ccxt/test/base/test_deposit_withdrawal.py +50 -0
  721. ccxt/test/base/test_exchange_datetime_functions.py +76 -0
  722. ccxt/test/base/test_funding_rate_history.py +29 -0
  723. ccxt/test/base/test_last_price.py +31 -0
  724. ccxt/test/base/test_ledger_entry.py +45 -0
  725. ccxt/test/base/test_ledger_item.py +48 -0
  726. ccxt/test/base/test_leverage_tier.py +33 -0
  727. ccxt/test/base/test_liquidation.py +50 -0
  728. ccxt/test/base/test_margin_mode.py +24 -0
  729. ccxt/test/base/test_margin_modification.py +35 -0
  730. ccxt/test/base/test_market.py +193 -0
  731. ccxt/test/base/test_number.py +411 -0
  732. ccxt/test/base/test_ohlcv.py +33 -0
  733. ccxt/test/base/test_open_interest.py +32 -0
  734. ccxt/test/base/test_order.py +64 -0
  735. ccxt/test/base/test_order_book.py +69 -0
  736. ccxt/test/base/test_position.py +60 -0
  737. ccxt/test/base/test_shared_methods.py +353 -0
  738. ccxt/test/base/test_status.py +24 -0
  739. ccxt/test/base/test_throttle.py +126 -0
  740. ccxt/test/base/test_ticker.py +92 -0
  741. ccxt/test/base/test_trade.py +47 -0
  742. ccxt/test/base/test_trading_fee.py +26 -0
  743. ccxt/test/base/test_transaction.py +39 -0
  744. ccxt/test/test_async.py +1649 -0
  745. ccxt/test/test_sync.py +1648 -0
  746. ccxt/test/tests_async.py +1558 -0
  747. ccxt/test/tests_helpers.py +287 -0
  748. ccxt/test/tests_init.py +39 -0
  749. ccxt/test/tests_sync.py +1555 -0
  750. ccxt/tetherland.py +349 -0
  751. ccxt/timex.py +1593 -0
  752. ccxt/tokocrypto.py +2405 -0
  753. ccxt/tradeogre.py +608 -0
  754. ccxt/twox.py +326 -0
  755. ccxt/ubitex.py +409 -0
  756. ccxt/upbit.py +1833 -0
  757. ccxt/vertex.py +2922 -0
  758. ccxt/wallex.py +445 -0
  759. ccxt/wavesexchange.py +2472 -0
  760. ccxt/wazirx.py +1224 -0
  761. ccxt/whitebit.py +2469 -0
  762. ccxt/woo.py +3114 -0
  763. ccxt/woofipro.py +2533 -0
  764. ccxt/xt.py +4453 -0
  765. ccxt/yobit.py +1283 -0
  766. ccxt/zaif.py +725 -0
  767. ccxt/zonda.py +1828 -0
  768. ccxt_ir-4.3.46.0.1.dist-info/LICENSE.txt +21 -0
  769. ccxt_ir-4.3.46.0.1.dist-info/METADATA +655 -0
  770. ccxt_ir-4.3.46.0.1.dist-info/RECORD +772 -0
  771. ccxt_ir-4.3.46.0.1.dist-info/WHEEL +6 -0
  772. ccxt_ir-4.3.46.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2533 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+
6
+ from ccxt.async_support.base.exchange import Exchange
7
+ from ccxt.abstract.woofipro import ImplicitAPI
8
+ from ccxt.base.types import Balances, Currencies, Currency, Int, Leverage, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Trade, TradingFees, Transaction
9
+ from typing import List
10
+ from typing import Any
11
+ from ccxt.base.errors import ExchangeError
12
+ from ccxt.base.errors import AuthenticationError
13
+ from ccxt.base.errors import ArgumentsRequired
14
+ from ccxt.base.errors import BadRequest
15
+ from ccxt.base.errors import InsufficientFunds
16
+ from ccxt.base.errors import InvalidOrder
17
+ from ccxt.base.errors import NotSupported
18
+ from ccxt.base.errors import NetworkError
19
+ from ccxt.base.errors import RateLimitExceeded
20
+ from ccxt.base.decimal_to_precision import TICK_SIZE
21
+ from ccxt.base.precise import Precise
22
+
23
+
24
+ class woofipro(Exchange, ImplicitAPI):
25
+
26
+ def describe(self):
27
+ return self.deep_extend(super(woofipro, self).describe(), {
28
+ 'id': 'woofipro',
29
+ 'name': 'WOOFI PRO',
30
+ 'countries': ['KY'], # Cayman Islands
31
+ 'rateLimit': 100,
32
+ 'version': 'v1',
33
+ 'certified': True,
34
+ 'pro': True,
35
+ 'dex': True,
36
+ 'hostname': 'dex.woo.org',
37
+ 'has': {
38
+ 'CORS': None,
39
+ 'spot': False,
40
+ 'margin': False,
41
+ 'swap': True,
42
+ 'future': False,
43
+ 'option': False,
44
+ 'addMargin': False,
45
+ 'cancelAllOrders': True,
46
+ 'cancelOrder': True,
47
+ 'cancelOrders': True,
48
+ 'cancelWithdraw': False,
49
+ 'closeAllPositions': False,
50
+ 'closePosition': False,
51
+ 'createConvertTrade': False,
52
+ 'createDepositAddress': False,
53
+ 'createMarketBuyOrderWithCost': False,
54
+ 'createMarketOrder': False,
55
+ 'createMarketOrderWithCost': False,
56
+ 'createMarketSellOrderWithCost': False,
57
+ 'createOrder': True,
58
+ 'createOrderWithTakeProfitAndStopLoss': True,
59
+ 'createReduceOnlyOrder': True,
60
+ 'createStopLimitOrder': False,
61
+ 'createStopLossOrder': True,
62
+ 'createStopMarketOrder': False,
63
+ 'createStopOrder': False,
64
+ 'createTakeProfitOrder': True,
65
+ 'createTrailingAmountOrder': False,
66
+ 'createTrailingPercentOrder': False,
67
+ 'createTriggerOrder': True,
68
+ 'fetchAccounts': False,
69
+ 'fetchBalance': True,
70
+ 'fetchCanceledOrders': False,
71
+ 'fetchClosedOrder': False,
72
+ 'fetchClosedOrders': True,
73
+ 'fetchConvertCurrencies': False,
74
+ 'fetchConvertQuote': False,
75
+ 'fetchCurrencies': True,
76
+ 'fetchDepositAddress': False,
77
+ 'fetchDeposits': True,
78
+ 'fetchDepositsWithdrawals': True,
79
+ 'fetchFundingHistory': True,
80
+ 'fetchFundingRate': True,
81
+ 'fetchFundingRateHistory': True,
82
+ 'fetchFundingRates': True,
83
+ 'fetchIndexOHLCV': False,
84
+ 'fetchLedger': True,
85
+ 'fetchLeverage': True,
86
+ 'fetchMarginAdjustmentHistory': False,
87
+ 'fetchMarginMode': False,
88
+ 'fetchMarkets': True,
89
+ 'fetchMarkOHLCV': False,
90
+ 'fetchMyTrades': True,
91
+ 'fetchOHLCV': True,
92
+ 'fetchOpenInterestHistory': False,
93
+ 'fetchOpenOrder': False,
94
+ 'fetchOpenOrders': True,
95
+ 'fetchOrder': True,
96
+ 'fetchOrderBook': True,
97
+ 'fetchOrders': True,
98
+ 'fetchOrderTrades': True,
99
+ 'fetchPosition': True,
100
+ 'fetchPositionMode': False,
101
+ 'fetchPositions': True,
102
+ 'fetchPremiumIndexOHLCV': False,
103
+ 'fetchStatus': True,
104
+ 'fetchTicker': False,
105
+ 'fetchTickers': False,
106
+ 'fetchTime': True,
107
+ 'fetchTrades': True,
108
+ 'fetchTradingFee': False,
109
+ 'fetchTradingFees': True,
110
+ 'fetchTransactions': 'emulated',
111
+ 'fetchTransfers': False,
112
+ 'fetchWithdrawals': True,
113
+ 'reduceMargin': False,
114
+ 'setLeverage': True,
115
+ 'setMargin': False,
116
+ 'setPositionMode': False,
117
+ 'transfer': False,
118
+ 'withdraw': True, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://kronosresearch.github.io/wootrade-documents/#token-withdraw
119
+ },
120
+ 'timeframes': {
121
+ '1m': '1m',
122
+ '5m': '5m',
123
+ '15m': '15m',
124
+ '30m': '30m',
125
+ '1h': '1h',
126
+ '4h': '4h',
127
+ '12h': '12h',
128
+ '1d': '1d',
129
+ '1w': '1w',
130
+ '1M': '1mon',
131
+ '1y': '1y',
132
+ },
133
+ 'urls': {
134
+ 'logo': 'https://github.com/ccxt/ccxt/assets/43336371/b1e7b348-a0fc-4605-8b7f-91176958fd69',
135
+ 'api': {
136
+ 'public': 'https://api-evm.orderly.org',
137
+ 'private': 'https://api-evm.orderly.org',
138
+ },
139
+ 'test': {
140
+ 'public': 'https://testnet-api-evm.orderly.org',
141
+ 'private': 'https://testnet-api-evm.orderly.org',
142
+ },
143
+ 'www': 'https://dex.woo.org',
144
+ 'doc': [
145
+ 'https://orderly.network/docs/build-on-evm/building-on-evm',
146
+ ],
147
+ 'fees': [
148
+ 'https://dex.woo.org/en/orderly',
149
+ ],
150
+ 'referral': {
151
+ 'url': 'https://dex.woo.org/en/trade?ref=CCXT',
152
+ 'discount': 0.05,
153
+ },
154
+ },
155
+ 'api': {
156
+ 'v1': {
157
+ 'public': {
158
+ 'get': {
159
+ 'public/volume/stats': 1,
160
+ 'public/broker/name': 1,
161
+ 'public/chain_info/{broker_id}': 1,
162
+ 'public/system_info': 1,
163
+ 'public/vault_balance': 1,
164
+ 'public/insurancefund': 1,
165
+ 'public/chain_info': 1,
166
+ 'faucet/usdc': 1,
167
+ 'public/account': 1,
168
+ 'get_account': 1,
169
+ 'registration_nonce': 1,
170
+ 'get_orderly_key': 1,
171
+ 'public/liquidation': 1,
172
+ 'public/liquidated_positions': 1,
173
+ 'public/config': 1,
174
+ 'public/campaign/ranking': 10,
175
+ 'public/campaign/stats': 10,
176
+ 'public/campaign/user': 10,
177
+ 'public/campaign/stats/details': 10,
178
+ 'public/campaigns': 10,
179
+ 'public/points/leaderboard': 1,
180
+ 'client/points': 1,
181
+ 'public/points/epoch': 1,
182
+ 'public/points/epoch_dates': 1,
183
+ 'public/referral/check_ref_code': 1,
184
+ 'public/referral/verify_ref_code': 1,
185
+ 'referral/admin_info': 1,
186
+ 'referral/info': 1,
187
+ 'referral/referee_info': 1,
188
+ 'referral/referee_rebate_summary': 1,
189
+ 'referral/referee_history': 1,
190
+ 'referral/referral_history': 1,
191
+ 'referral/rebate_summary': 1,
192
+ 'client/distribution_history': 1,
193
+ 'tv/config': 1,
194
+ 'tv/history': 1,
195
+ 'tv/symbol_info': 1,
196
+ 'public/funding_rate_history': 1,
197
+ 'public/funding_rate/{symbol}': 0.33,
198
+ 'public/funding_rates': 1,
199
+ 'public/info': 1,
200
+ 'public/info/{symbol}': 1,
201
+ 'public/market_trades': 1,
202
+ 'public/token': 1,
203
+ 'public/futures': 1,
204
+ 'public/futures/{symbol}': 1,
205
+ },
206
+ 'post': {
207
+ 'register_account': 1,
208
+ },
209
+ },
210
+ 'private': {
211
+ 'get': {
212
+ 'client/key_info': 6,
213
+ 'client/orderly_key_ip_restriction': 6,
214
+ 'order/{oid}': 1,
215
+ 'client/order/{client_order_id}': 1,
216
+ 'algo/order/{oid}': 1,
217
+ 'algo/client/order/{client_order_id}': 1,
218
+ 'orders': 1,
219
+ 'algo/orders': 1,
220
+ 'trade/{tid}': 1,
221
+ 'trades': 1,
222
+ 'order/{oid}/trades': 1,
223
+ 'client/liquidator_liquidations': 1,
224
+ 'liquidations': 1,
225
+ 'asset/history': 60,
226
+ 'client/holding': 1,
227
+ 'withdraw_nonce': 1,
228
+ 'settle_nonce': 1,
229
+ 'pnl_settlement/history': 1,
230
+ 'volume/user/daily': 60,
231
+ 'volume/user/stats': 60,
232
+ 'client/statistics': 60,
233
+ 'client/info': 60,
234
+ 'client/statistics/daily': 60,
235
+ 'positions': 3.33,
236
+ 'position/{symbol}': 3.33,
237
+ 'funding_fee/history': 30,
238
+ 'notification/inbox/notifications': 60,
239
+ 'notification/inbox/unread': 60,
240
+ 'volume/broker/daily': 60,
241
+ 'broker/fee_rate/default': 10,
242
+ 'broker/user_info': 10,
243
+ 'orderbook/{symbol}': 1,
244
+ 'kline': 1,
245
+ },
246
+ 'post': {
247
+ 'orderly_key': 1,
248
+ 'client/set_orderly_key_ip_restriction': 6,
249
+ 'client/reset_orderly_key_ip_restriction': 6,
250
+ 'order': 1,
251
+ 'batch-order': 10,
252
+ 'algo/order': 1,
253
+ 'liquidation': 1,
254
+ 'claim_insurance_fund': 1,
255
+ 'withdraw_request': 1,
256
+ 'settle_pnl': 1,
257
+ 'notification/inbox/mark_read': 60,
258
+ 'notification/inbox/mark_read_all': 60,
259
+ 'client/leverage': 120,
260
+ 'client/maintenance_config': 60,
261
+ 'delegate_signer': 10,
262
+ 'delegate_orderly_key': 10,
263
+ 'delegate_settle_pnl': 10,
264
+ 'delegate_withdraw_request': 10,
265
+ 'broker/fee_rate/set': 10,
266
+ 'broker/fee_rate/set_default': 10,
267
+ 'broker/fee_rate/default': 10,
268
+ 'referral/create': 10,
269
+ 'referral/update': 10,
270
+ 'referral/bind': 10,
271
+ 'referral/edit_split': 10,
272
+ },
273
+ 'put': {
274
+ 'order': 1,
275
+ 'algo/order': 1,
276
+ },
277
+ 'delete': {
278
+ 'order': 1,
279
+ 'algo/order': 1,
280
+ 'client/order': 1,
281
+ 'algo/client/order': 1,
282
+ 'algo/orders': 1,
283
+ 'orders': 1,
284
+ 'batch-order': 1,
285
+ 'client/batch-order': 1,
286
+ },
287
+ },
288
+ },
289
+ },
290
+ 'requiredCredentials': {
291
+ 'apiKey': True,
292
+ 'secret': True,
293
+ 'accountId': True,
294
+ 'privateKey': False,
295
+ },
296
+ 'fees': {
297
+ 'trading': {
298
+ 'tierBased': True,
299
+ 'percentage': True,
300
+ 'maker': self.parse_number('0.0002'),
301
+ 'taker': self.parse_number('0.0005'),
302
+ },
303
+ },
304
+ 'options': {
305
+ 'sandboxMode': False,
306
+ 'brokerId': 'CCXT',
307
+ 'verifyingContractAddress': '0x6F7a338F2aA472838dEFD3283eB360d4Dff5D203',
308
+ },
309
+ 'commonCurrencies': {},
310
+ 'exceptions': {
311
+ 'exact': {
312
+ '-1000': ExchangeError, # UNKNOWN The data does not exist
313
+ '-1001': AuthenticationError, # INVALID_SIGNATURE The api key or secret is in wrong format.
314
+ '-1002': AuthenticationError, # UNAUTHORIZED API key or secret is invalid, it may because key have insufficient permission or the key is expired/revoked.
315
+ '-1003': RateLimitExceeded, # TOO_MANY_REQUEST Rate limit exceed.
316
+ '-1004': BadRequest, # UNKNOWN_PARAM An unknown parameter was sent.
317
+ '-1005': BadRequest, # INVALID_PARAM Some parameters are in wrong format for api.
318
+ '-1006': InvalidOrder, # RESOURCE_NOT_FOUND The data is not found in server. For example, when client try canceling a CANCELLED order, will raise self error.
319
+ '-1007': BadRequest, # DUPLICATE_REQUEST The data is already exists or your request is duplicated.
320
+ '-1008': InvalidOrder, # QUANTITY_TOO_HIGH The quantity of settlement is too high than you can request.
321
+ '-1009': InsufficientFunds, # CAN_NOT_WITHDRAWAL Can not request withdrawal settlement, you need to deposit other arrears first.
322
+ '-1011': NetworkError, # RPC_NOT_CONNECT Can not place/cancel orders, it may because internal network error. Please try again in a few seconds.
323
+ '-1012': BadRequest, # RPC_REJECT The place/cancel order request is rejected by internal module, it may because the account is in liquidation or other internal errors. Please try again in a few seconds.
324
+ '-1101': InsufficientFunds, # RISK_TOO_HIGH The risk exposure for client is too high, it may cause by sending too big order or the leverage is too low. please refer to client info to check the current exposure.
325
+ '-1102': InvalidOrder, # MIN_NOTIONAL The order value(price * size) is too small.
326
+ '-1103': InvalidOrder, # PRICE_FILTER The order price is not following the tick size rule for the symbol.
327
+ '-1104': InvalidOrder, # SIZE_FILTER The order quantity is not following the step size rule for the symbol.
328
+ '-1105': InvalidOrder, # PERCENTAGE_FILTER Price is X% too high or X% too low from the mid price.
329
+ '-1201': BadRequest, # LIQUIDATION_REQUEST_RATIO_TOO_SMALL total notional < 10000, least req ratio should = 1
330
+ '-1202': BadRequest, # LIQUIDATION_STATUS_ERROR No need to liquidation because user margin is enough.
331
+ '29': BadRequest, # {"success":false,"code":29,"message":"Verify contract is invalid"}
332
+ '9': AuthenticationError, # {"success":false,"code":9,"message":"Address and signature do not match"}
333
+ '3': AuthenticationError, # {"success":false,"code":3,"message":"Signature error"}
334
+ '2': BadRequest, # {"success":false,"code":2,"message":"Timestamp expired"}
335
+ '15': BadRequest, # {"success":false,"code":15,"message":"BrokerId is not exist"}
336
+ },
337
+ 'broad': {
338
+ },
339
+ },
340
+ 'precisionMode': TICK_SIZE,
341
+ })
342
+
343
+ def set_sandbox_mode(self, enable: bool):
344
+ super(woofipro, self).set_sandbox_mode(enable)
345
+ self.options['sandboxMode'] = enable
346
+
347
+ async def fetch_status(self, params={}):
348
+ """
349
+ the latest known information on the availability of the exchange API
350
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-system-maintenance-status
351
+ :param dict [params]: extra parameters specific to the exchange API endpoint
352
+ :returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
353
+ """
354
+ response = await self.v1PublicGetPublicSystemInfo(params)
355
+ #
356
+ # {
357
+ # "success": True,
358
+ # "data": {
359
+ # "status": 0,
360
+ # "msg": "System is functioning properly."
361
+ # },
362
+ # "timestamp": "1709274106602"
363
+ # }
364
+ #
365
+ data = self.safe_dict(response, 'data', {})
366
+ status = self.safe_string(data, 'status')
367
+ if status is None:
368
+ status = 'error'
369
+ elif status == '0':
370
+ status = 'ok'
371
+ else:
372
+ status = 'maintenance'
373
+ return {
374
+ 'status': status,
375
+ 'updated': None,
376
+ 'eta': None,
377
+ 'url': None,
378
+ 'info': response,
379
+ }
380
+
381
+ async def fetch_time(self, params={}):
382
+ """
383
+ fetches the current integer timestamp in milliseconds from the exchange server
384
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-system-maintenance-status
385
+ :param dict [params]: extra parameters specific to the exchange API endpoint
386
+ :returns int: the current integer timestamp in milliseconds from the exchange server
387
+ """
388
+ response = await self.v1PublicGetPublicSystemInfo(params)
389
+ #
390
+ # {
391
+ # "success": True,
392
+ # "data": {
393
+ # "status": 0,
394
+ # "msg": "System is functioning properly."
395
+ # },
396
+ # "timestamp": "1709274106602"
397
+ # }
398
+ #
399
+ return self.safe_integer(response, 'timestamp')
400
+
401
+ def parse_market(self, market: dict) -> Market:
402
+ #
403
+ # {
404
+ # "symbol": "PERP_BTC_USDC",
405
+ # "quote_min": 123,
406
+ # "quote_max": 100000,
407
+ # "quote_tick": 0.1,
408
+ # "base_min": 0.00001,
409
+ # "base_max": 20,
410
+ # "base_tick": 0.00001,
411
+ # "min_notional": 1,
412
+ # "price_range": 0.02,
413
+ # "price_scope": 0.4,
414
+ # "std_liquidation_fee": 0.03,
415
+ # "liquidator_fee": 0.015,
416
+ # "claim_insurance_fund_discount": 0.0075,
417
+ # "funding_period": 8,
418
+ # "cap_funding": 0.000375,
419
+ # "floor_funding": -0.000375,
420
+ # "interest_rate": 0.0001,
421
+ # "created_time": 1684140107326,
422
+ # "updated_time": 1685345968053,
423
+ # "base_mmr": 0.05,
424
+ # "base_imr": 0.1,
425
+ # "imr_factor": 0.0002512,
426
+ # "liquidation_tier": "1"
427
+ # }
428
+ #
429
+ marketId = self.safe_string(market, 'symbol')
430
+ parts = marketId.split('_')
431
+ marketType = 'swap'
432
+ baseId = self.safe_string(parts, 1)
433
+ quoteId = self.safe_string(parts, 2)
434
+ base = self.safe_currency_code(baseId)
435
+ quote = self.safe_currency_code(quoteId)
436
+ settleId: Str = self.safe_string(parts, 2)
437
+ settle: Str = self.safe_currency_code(settleId)
438
+ symbol = base + '/' + quote + ':' + settle
439
+ return {
440
+ 'id': marketId,
441
+ 'symbol': symbol,
442
+ 'base': base,
443
+ 'quote': quote,
444
+ 'settle': settle,
445
+ 'baseId': baseId,
446
+ 'quoteId': quoteId,
447
+ 'settleId': settleId,
448
+ 'type': marketType,
449
+ 'spot': False,
450
+ 'margin': False,
451
+ 'swap': True,
452
+ 'future': False,
453
+ 'option': False,
454
+ 'active': None,
455
+ 'contract': True,
456
+ 'linear': True,
457
+ 'inverse': None,
458
+ 'contractSize': self.parse_number('1'),
459
+ 'expiry': None,
460
+ 'expiryDatetime': None,
461
+ 'strike': None,
462
+ 'optionType': None,
463
+ 'precision': {
464
+ 'amount': self.safe_number(market, 'base_tick'),
465
+ 'price': self.safe_number(market, 'quote_tick'),
466
+ },
467
+ 'limits': {
468
+ 'leverage': {
469
+ 'min': None,
470
+ 'max': None,
471
+ },
472
+ 'amount': {
473
+ 'min': self.safe_number(market, 'base_min'),
474
+ 'max': self.safe_number(market, 'base_max'),
475
+ },
476
+ 'price': {
477
+ 'min': self.safe_number(market, 'quote_min'),
478
+ 'max': self.safe_number(market, 'quote_max'),
479
+ },
480
+ 'cost': {
481
+ 'min': self.safe_number(market, 'min_notional'),
482
+ 'max': None,
483
+ },
484
+ },
485
+ 'created': self.safe_integer(market, 'created_time'),
486
+ 'info': market,
487
+ }
488
+
489
+ async def fetch_markets(self, params={}) -> List[Market]:
490
+ """
491
+ retrieves data on all markets for woofipro
492
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-available-symbols
493
+ :param dict [params]: extra parameters specific to the exchange API endpoint
494
+ :returns dict[]: an array of objects representing market data
495
+ """
496
+ response = await self.v1PublicGetPublicInfo(params)
497
+ #
498
+ # {
499
+ # "success": True,
500
+ # "timestamp": 1702989203989,
501
+ # "data": {
502
+ # "rows": [
503
+ # {
504
+ # "symbol": "PERP_BTC_USDC",
505
+ # "quote_min": 123,
506
+ # "quote_max": 100000,
507
+ # "quote_tick": 0.1,
508
+ # "base_min": 0.00001,
509
+ # "base_max": 20,
510
+ # "base_tick": 0.00001,
511
+ # "min_notional": 1,
512
+ # "price_range": 0.02,
513
+ # "price_scope": 0.4,
514
+ # "std_liquidation_fee": 0.03,
515
+ # "liquidator_fee": 0.015,
516
+ # "claim_insurance_fund_discount": 0.0075,
517
+ # "funding_period": 8,
518
+ # "cap_funding": 0.000375,
519
+ # "floor_funding": -0.000375,
520
+ # "interest_rate": 0.0001,
521
+ # "created_time": 1684140107326,
522
+ # "updated_time": 1685345968053,
523
+ # "base_mmr": 0.05,
524
+ # "base_imr": 0.1,
525
+ # "imr_factor": 0.0002512,
526
+ # "liquidation_tier": "1"
527
+ # }
528
+ # ]
529
+ # }
530
+ # }
531
+ #
532
+ data = self.safe_dict(response, 'data', {})
533
+ rows = self.safe_list(data, 'rows', [])
534
+ return self.parse_markets(rows)
535
+
536
+ async def fetch_currencies(self, params={}) -> Currencies:
537
+ """
538
+ fetches all available currencies on an exchange
539
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-token-info
540
+ :param dict [params]: extra parameters specific to the exchange API endpoint
541
+ :returns dict: an associative dictionary of currencies
542
+ """
543
+ result: dict = {}
544
+ response = await self.v1PublicGetPublicToken(params)
545
+ #
546
+ # {
547
+ # "success": True,
548
+ # "timestamp": 1702989203989,
549
+ # "data": {
550
+ # "rows": [{
551
+ # "token": "USDC",
552
+ # "decimals": 6,
553
+ # "minimum_withdraw_amount": 0.000001,
554
+ # "token_hash": "0xd6aca1be9729c13d677335161321649cccae6a591554772516700f986f942eaa",
555
+ # "chain_details": [{
556
+ # "chain_id": 43113,
557
+ # "contract_address": "0x5d64c9cfb0197775b4b3ad9be4d3c7976e0d8dc3",
558
+ # "cross_chain_withdrawal_fee": 123,
559
+ # "decimals": 6,
560
+ # "withdraw_fee": 2
561
+ # }]
562
+ # }
563
+ # ]
564
+ # }
565
+ # }
566
+ #
567
+ data = self.safe_dict(response, 'data', {})
568
+ tokenRows = self.safe_list(data, 'rows', [])
569
+ for i in range(0, len(tokenRows)):
570
+ token = tokenRows[i]
571
+ currencyId = self.safe_string(token, 'token')
572
+ networks = self.safe_list(token, 'chain_details')
573
+ code = self.safe_currency_code(currencyId)
574
+ minPrecision = None
575
+ resultingNetworks: dict = {}
576
+ for j in range(0, len(networks)):
577
+ network = networks[j]
578
+ # TODO: transform chain id to human readable name
579
+ networkId = self.safe_string(network, 'chain_id')
580
+ precision = self.parse_precision(self.safe_string(network, 'decimals'))
581
+ if precision is not None:
582
+ minPrecision = precision if (minPrecision is None) else Precise.string_min(precision, minPrecision)
583
+ resultingNetworks[networkId] = {
584
+ 'id': networkId,
585
+ 'network': networkId,
586
+ 'limits': {
587
+ 'withdraw': {
588
+ 'min': None,
589
+ 'max': None,
590
+ },
591
+ 'deposit': {
592
+ 'min': None,
593
+ 'max': None,
594
+ },
595
+ },
596
+ 'active': None,
597
+ 'deposit': None,
598
+ 'withdraw': None,
599
+ 'fee': self.safe_number(network, 'withdrawal_fee'),
600
+ 'precision': self.parse_number(precision),
601
+ 'info': network,
602
+ }
603
+ result[code] = {
604
+ 'id': currencyId,
605
+ 'name': currencyId,
606
+ 'code': code,
607
+ 'precision': self.parse_number(minPrecision),
608
+ 'active': None,
609
+ 'fee': None,
610
+ 'networks': resultingNetworks,
611
+ 'deposit': None,
612
+ 'withdraw': None,
613
+ 'limits': {
614
+ 'deposit': {
615
+ 'min': None,
616
+ 'max': None,
617
+ },
618
+ 'withdraw': {
619
+ 'min': self.safe_number(token, 'minimum_withdraw_amount'),
620
+ 'max': None,
621
+ },
622
+ },
623
+ 'info': token,
624
+ }
625
+ return result
626
+
627
+ def parse_token_and_fee_temp(self, item, feeTokenKey, feeAmountKey):
628
+ feeCost = self.safe_string(item, feeAmountKey)
629
+ fee = None
630
+ if feeCost is not None:
631
+ feeCurrencyId = self.safe_string(item, feeTokenKey)
632
+ feeCurrencyCode = self.safe_currency_code(feeCurrencyId)
633
+ fee = {
634
+ 'cost': feeCost,
635
+ 'currency': feeCurrencyCode,
636
+ }
637
+ return fee
638
+
639
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
640
+ #
641
+ # public/market_trades
642
+ #
643
+ # {
644
+ # "symbol": "SPOT_BTC_USDT",
645
+ # "side": "SELL",
646
+ # "executed_price": 46222.35,
647
+ # "executed_quantity": 0.0012,
648
+ # "executed_timestamp": "1683878609166"
649
+ # }
650
+ #
651
+ # fetchOrderTrades, fetchOrder
652
+ #
653
+ # {
654
+ # "id": "99119876",
655
+ # "symbol": "SPOT_WOO_USDT",
656
+ # "fee": "0.0024",
657
+ # "side": "BUY",
658
+ # "executed_timestamp": "1641481113084",
659
+ # "order_id": "87001234",
660
+ # "order_tag": "default", <-- self param only in "fetchOrderTrades"
661
+ # "executed_price": "1",
662
+ # "executed_quantity": "12",
663
+ # "fee_asset": "WOO",
664
+ # "is_maker": "1"
665
+ # }
666
+ #
667
+ isFromFetchOrder = ('id' in trade)
668
+ timestamp = self.safe_integer(trade, 'executed_timestamp')
669
+ marketId = self.safe_string(trade, 'symbol')
670
+ market = self.safe_market(marketId, market)
671
+ symbol = market['symbol']
672
+ price = self.safe_string(trade, 'executed_price')
673
+ amount = self.safe_string(trade, 'executed_quantity')
674
+ order_id = self.safe_string(trade, 'order_id')
675
+ fee = self.parse_token_and_fee_temp(trade, 'fee_asset', 'fee')
676
+ cost = Precise.string_mul(price, amount)
677
+ side = self.safe_string_lower(trade, 'side')
678
+ id = self.safe_string(trade, 'id')
679
+ takerOrMaker: Str = None
680
+ if isFromFetchOrder:
681
+ isMaker = self.safe_string(trade, 'is_maker') == '1'
682
+ takerOrMaker = 'maker' if isMaker else 'taker'
683
+ return self.safe_trade({
684
+ 'id': id,
685
+ 'timestamp': timestamp,
686
+ 'datetime': self.iso8601(timestamp),
687
+ 'symbol': symbol,
688
+ 'side': side,
689
+ 'price': price,
690
+ 'amount': amount,
691
+ 'cost': cost,
692
+ 'order': order_id,
693
+ 'takerOrMaker': takerOrMaker,
694
+ 'type': None,
695
+ 'fee': fee,
696
+ 'info': trade,
697
+ }, market)
698
+
699
+ async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
700
+ """
701
+ get the list of most recent trades for a particular symbol
702
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-market-trades
703
+ :param str symbol: unified symbol of the market to fetch trades for
704
+ :param int [since]: timestamp in ms of the earliest trade to fetch
705
+ :param int [limit]: the maximum amount of trades to fetch
706
+ :param dict [params]: extra parameters specific to the exchange API endpoint
707
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
708
+ """
709
+ await self.load_markets()
710
+ market = self.market(symbol)
711
+ request: dict = {
712
+ 'symbol': market['id'],
713
+ }
714
+ if limit is not None:
715
+ request['limit'] = limit
716
+ response = await self.v1PublicGetPublicMarketTrades(self.extend(request, params))
717
+ #
718
+ # {
719
+ # "success": True,
720
+ # "timestamp": 1702989203989,
721
+ # "data": {
722
+ # "rows": [{
723
+ # "symbol": "PERP_ETH_USDC",
724
+ # "side": "BUY",
725
+ # "executed_price": 2050,
726
+ # "executed_quantity": 1,
727
+ # "executed_timestamp": 1683878609166
728
+ # }]
729
+ # }
730
+ # }
731
+ #
732
+ data = self.safe_dict(response, 'data', {})
733
+ rows = self.safe_list(data, 'rows', [])
734
+ return self.parse_trades(rows, market, since, limit)
735
+
736
+ def parse_funding_rate(self, fundingRate, market: Market = None):
737
+ #
738
+ # {
739
+ # "symbol":"PERP_AAVE_USDT",
740
+ # "est_funding_rate":-0.00003447,
741
+ # "est_funding_rate_timestamp":1653633959001,
742
+ # "last_funding_rate":-0.00002094,
743
+ # "last_funding_rate_timestamp":1653631200000,
744
+ # "next_funding_time":1653634800000,
745
+ # "sum_unitary_funding": 521.367
746
+ # }
747
+ #
748
+ #
749
+ symbol = self.safe_string(fundingRate, 'symbol')
750
+ market = self.market(symbol)
751
+ nextFundingTimestamp = self.safe_integer(fundingRate, 'next_funding_time')
752
+ estFundingRateTimestamp = self.safe_integer(fundingRate, 'est_funding_rate_timestamp')
753
+ lastFundingRateTimestamp = self.safe_integer(fundingRate, 'last_funding_rate_timestamp')
754
+ return {
755
+ 'info': fundingRate,
756
+ 'symbol': market['symbol'],
757
+ 'markPrice': None,
758
+ 'indexPrice': None,
759
+ 'interestRate': self.parse_number('0'),
760
+ 'estimatedSettlePrice': None,
761
+ 'timestamp': estFundingRateTimestamp,
762
+ 'datetime': self.iso8601(estFundingRateTimestamp),
763
+ 'fundingRate': self.safe_number(fundingRate, 'est_funding_rate'),
764
+ 'fundingTimestamp': nextFundingTimestamp,
765
+ 'fundingDatetime': self.iso8601(nextFundingTimestamp),
766
+ 'nextFundingRate': None,
767
+ 'nextFundingTimestamp': None,
768
+ 'nextFundingDatetime': None,
769
+ 'previousFundingRate': self.safe_number(fundingRate, 'last_funding_rate'),
770
+ 'previousFundingTimestamp': lastFundingRateTimestamp,
771
+ 'previousFundingDatetime': self.iso8601(lastFundingRateTimestamp),
772
+ }
773
+
774
+ async def fetch_funding_rate(self, symbol: str, params={}):
775
+ """
776
+ fetch the current funding rate
777
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-predicted-funding-rate-for-one-market
778
+ :param str symbol: unified market symbol
779
+ :param dict [params]: extra parameters specific to the exchange API endpoint
780
+ :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
781
+ """
782
+ await self.load_markets()
783
+ market = self.market(symbol)
784
+ request: dict = {
785
+ 'symbol': market['id'],
786
+ }
787
+ response = await self.v1PublicGetPublicFundingRateSymbol(self.extend(request, params))
788
+ #
789
+ # {
790
+ # "success": True,
791
+ # "timestamp": 1702989203989,
792
+ # "data": {
793
+ # "symbol": "PERP_ETH_USDC",
794
+ # "est_funding_rate": 123,
795
+ # "est_funding_rate_timestamp": 1683880020000,
796
+ # "last_funding_rate": 0.0001,
797
+ # "last_funding_rate_timestamp": 1683878400000,
798
+ # "next_funding_time": 1683907200000,
799
+ # "sum_unitary_funding": 521.367
800
+ # }
801
+ # }
802
+ #
803
+ data = self.safe_dict(response, 'data', {})
804
+ return self.parse_funding_rate(data, market)
805
+
806
+ async def fetch_funding_rates(self, symbols: Strings = None, params={}):
807
+ """
808
+ fetch the current funding rates
809
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-predicted-funding-rates-for-all-markets
810
+ :param str[] symbols: unified market symbols
811
+ :param dict [params]: extra parameters specific to the exchange API endpoint
812
+ :returns dict[]: an array of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-structure>`
813
+ """
814
+ await self.load_markets()
815
+ symbols = self.market_symbols(symbols)
816
+ response = await self.v1PublicGetPublicFundingRates(params)
817
+ #
818
+ # {
819
+ # "success": True,
820
+ # "timestamp": 1702989203989,
821
+ # "data": {
822
+ # "rows": [{
823
+ # "symbol": "PERP_ETH_USDC",
824
+ # "est_funding_rate": 123,
825
+ # "est_funding_rate_timestamp": 1683880020000,
826
+ # "last_funding_rate": 0.0001,
827
+ # "last_funding_rate_timestamp": 1683878400000,
828
+ # "next_funding_time": 1683907200000,
829
+ # "sum_unitary_funding": 521.367
830
+ # }]
831
+ # }
832
+ # }
833
+ #
834
+ data = self.safe_dict(response, 'data', {})
835
+ rows = self.safe_list(data, 'rows', [])
836
+ result = self.parse_funding_rates(rows)
837
+ return self.filter_by_array(result, 'symbol', symbols)
838
+
839
+ async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
840
+ """
841
+ fetches historical funding rate prices
842
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-funding-rate-history-for-one-market
843
+ :param str symbol: unified symbol of the market to fetch the funding rate history for
844
+ :param int [since]: timestamp in ms of the earliest funding rate to fetch
845
+ :param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
846
+ :param dict [params]: extra parameters specific to the exchange API endpoint
847
+ :param int [params.until]: timestamp in ms of the latest funding rate
848
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
849
+ :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>`
850
+ """
851
+ await self.load_markets()
852
+ paginate = False
853
+ paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
854
+ if paginate:
855
+ return await self.fetch_paginated_call_incremental('fetchFundingRateHistory', symbol, since, limit, params, 'page', 25)
856
+ request: dict = {}
857
+ if symbol is not None:
858
+ market = self.market(symbol)
859
+ symbol = market['symbol']
860
+ request['symbol'] = market['id']
861
+ if since is not None:
862
+ request['start_t'] = since
863
+ request, params = self.handle_until_option('end_t', request, params, 0.001)
864
+ response = await self.v1PublicGetPublicFundingRateHistory(self.extend(request, params))
865
+ #
866
+ # {
867
+ # "success": True,
868
+ # "timestamp": 1702989203989,
869
+ # "data": {
870
+ # "rows": [{
871
+ # "symbol": "PERP_ETH_USDC",
872
+ # "funding_rate": 0.0001,
873
+ # "funding_rate_timestamp": 1684224000000,
874
+ # "next_funding_time": 1684252800000
875
+ # }],
876
+ # "meta": {
877
+ # "total": 9,
878
+ # "records_per_page": 25,
879
+ # "current_page": 1
880
+ # }
881
+ # }
882
+ # }
883
+ #
884
+ data = self.safe_dict(response, 'data', {})
885
+ result = self.safe_list(data, 'rows', [])
886
+ rates = []
887
+ for i in range(0, len(result)):
888
+ entry = result[i]
889
+ marketId = self.safe_string(entry, 'symbol')
890
+ timestamp = self.safe_integer(entry, 'funding_rate_timestamp')
891
+ rates.append({
892
+ 'info': entry,
893
+ 'symbol': self.safe_symbol(marketId),
894
+ 'fundingRate': self.safe_number(entry, 'funding_rate'),
895
+ 'timestamp': timestamp,
896
+ 'datetime': self.iso8601(timestamp),
897
+ })
898
+ sorted = self.sort_by(rates, 'timestamp')
899
+ return self.filter_by_symbol_since_limit(sorted, symbol, since, limit)
900
+
901
+ async def fetch_trading_fees(self, params={}) -> TradingFees:
902
+ """
903
+ fetch the trading fees for multiple markets
904
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-account-information
905
+ :param dict [params]: extra parameters specific to the exchange API endpoint
906
+ :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
907
+ """
908
+ await self.load_markets()
909
+ response = await self.v1PrivateGetClientInfo(params)
910
+ #
911
+ # {
912
+ # "success": True,
913
+ # "timestamp": 1702989203989,
914
+ # "data": {
915
+ # "account_id": "<string>",
916
+ # "email": "test@test.com",
917
+ # "account_mode": "FUTURES",
918
+ # "max_leverage": 20,
919
+ # "taker_fee_rate": 123,
920
+ # "maker_fee_rate": 123,
921
+ # "futures_taker_fee_rate": 123,
922
+ # "futures_maker_fee_rate": 123,
923
+ # "maintenance_cancel_orders": True,
924
+ # "imr_factor": {
925
+ # "PERP_BTC_USDC": 123,
926
+ # "PERP_ETH_USDC": 123,
927
+ # "PERP_NEAR_USDC": 123
928
+ # },
929
+ # "max_notional": {
930
+ # "PERP_BTC_USDC": 123,
931
+ # "PERP_ETH_USDC": 123,
932
+ # "PERP_NEAR_USDC": 123
933
+ # }
934
+ # }
935
+ # }
936
+ #
937
+ data = self.safe_dict(response, 'data', {})
938
+ maker = self.safe_string(data, 'futures_maker_fee_rate')
939
+ taker = self.safe_string(data, 'futures_taker_fee_rate')
940
+ result: dict = {}
941
+ for i in range(0, len(self.symbols)):
942
+ symbol = self.symbols[i]
943
+ result[symbol] = {
944
+ 'info': response,
945
+ 'symbol': symbol,
946
+ 'maker': self.parse_number(Precise.string_div(maker, '10000')),
947
+ 'taker': self.parse_number(Precise.string_div(taker, '10000')),
948
+ 'percentage': True,
949
+ 'tierBased': True,
950
+ }
951
+ return result
952
+
953
+ async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
954
+ """
955
+ fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
956
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/orderbook-snapshot
957
+ :param str symbol: unified symbol of the market to fetch the order book for
958
+ :param int [limit]: the maximum amount of order book entries to return
959
+ :param dict [params]: extra parameters specific to the exchange API endpoint
960
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
961
+ """
962
+ await self.load_markets()
963
+ market = self.market(symbol)
964
+ request: dict = {
965
+ 'symbol': market['id'],
966
+ }
967
+ if limit is not None:
968
+ limit = min(limit, 1000)
969
+ request['max_level'] = limit
970
+ response = await self.v1PrivateGetOrderbookSymbol(self.extend(request, params))
971
+ #
972
+ # {
973
+ # "success": True,
974
+ # "timestamp": 1702989203989,
975
+ # "data": {
976
+ # "asks": [{
977
+ # "price": 10669.4,
978
+ # "quantity": 1.56263218
979
+ # }],
980
+ # "bids": [{
981
+ # "price": 10669.4,
982
+ # "quantity": 1.56263218
983
+ # }],
984
+ # "timestamp": 123
985
+ # }
986
+ # }
987
+ #
988
+ data = self.safe_dict(response, 'data', {})
989
+ timestamp = self.safe_integer(data, 'timestamp')
990
+ return self.parse_order_book(data, symbol, timestamp, 'bids', 'asks', 'price', 'quantity')
991
+
992
+ def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
993
+ return [
994
+ self.safe_integer(ohlcv, 'start_timestamp'),
995
+ self.safe_number(ohlcv, 'open'),
996
+ self.safe_number(ohlcv, 'high'),
997
+ self.safe_number(ohlcv, 'low'),
998
+ self.safe_number(ohlcv, 'close'),
999
+ self.safe_number(ohlcv, 'volume'),
1000
+ ]
1001
+
1002
+ async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
1003
+ """
1004
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-kline
1005
+ fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1006
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
1007
+ :param str timeframe: the length of time each candle represents
1008
+ :param int [since]: timestamp in ms of the earliest candle to fetch
1009
+ :param int [limit]: max=1000, max=100 when since is defined and is less than(now - (999 * (timeframe in ms)))
1010
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1011
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
1012
+ """
1013
+ await self.load_markets()
1014
+ market = self.market(symbol)
1015
+ request: dict = {
1016
+ 'symbol': market['id'],
1017
+ 'type': self.safe_string(self.timeframes, timeframe, timeframe),
1018
+ }
1019
+ if limit is not None:
1020
+ request['limit'] = min(limit, 1000)
1021
+ response = await self.v1PrivateGetKline(self.extend(request, params))
1022
+ data = self.safe_dict(response, 'data', {})
1023
+ #
1024
+ # {
1025
+ # "success": True,
1026
+ # "timestamp": 1702989203989,
1027
+ # "data": {
1028
+ # "rows": [{
1029
+ # "open": 66166.23,
1030
+ # "close": 66124.56,
1031
+ # "low": 66038.06,
1032
+ # "high": 66176.97,
1033
+ # "volume": 23.45528526,
1034
+ # "amount": 1550436.21725288,
1035
+ # "symbol": "PERP_BTC_USDC",
1036
+ # "type": "1m",
1037
+ # "start_timestamp": 1636388220000,
1038
+ # "end_timestamp": 1636388280000
1039
+ # }]
1040
+ # }
1041
+ # }
1042
+ #
1043
+ rows = self.safe_list(data, 'rows', [])
1044
+ return self.parse_ohlcvs(rows, market, timeframe, since, limit)
1045
+
1046
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1047
+ #
1048
+ # Possible input functions:
1049
+ # * createOrder
1050
+ # * createOrders
1051
+ # * cancelOrder
1052
+ # * fetchOrder
1053
+ # * fetchOrders
1054
+ # isFromFetchOrder = ('order_tag' in order); TO_DO
1055
+ #
1056
+ # stop order after creating it:
1057
+ # {
1058
+ # "orderId": "1578938",
1059
+ # "clientOrderId": "0",
1060
+ # "algoType": "STOP_LOSS",
1061
+ # "quantity": "0.1"
1062
+ # }
1063
+ # stop order after fetching it:
1064
+ # {
1065
+ # "algoOrderId": "1578958",
1066
+ # "clientOrderId": "0",
1067
+ # "rootAlgoOrderId": "1578958",
1068
+ # "parentAlgoOrderId": "0",
1069
+ # "symbol": "SPOT_LTC_USDT",
1070
+ # "orderTag": "default",
1071
+ # "algoType": "STOP_LOSS",
1072
+ # "side": "BUY",
1073
+ # "quantity": "0.1",
1074
+ # "isTriggered": False,
1075
+ # "triggerPrice": "100",
1076
+ # "triggerStatus": "USELESS",
1077
+ # "type": "LIMIT",
1078
+ # "rootAlgoStatus": "CANCELLED",
1079
+ # "algoStatus": "CANCELLED",
1080
+ # "triggerPriceType": "MARKET_PRICE",
1081
+ # "price": "75",
1082
+ # "triggerTime": "0",
1083
+ # "totalExecutedQuantity": "0",
1084
+ # "averageExecutedPrice": "0",
1085
+ # "totalFee": "0",
1086
+ # "feeAsset": '',
1087
+ # "reduceOnly": False,
1088
+ # "createdTime": "1686149609.744",
1089
+ # "updatedTime": "1686149903.362"
1090
+ # }
1091
+ #
1092
+ timestamp = self.safe_integer_n(order, ['timestamp', 'created_time', 'createdTime'])
1093
+ orderId = self.safe_string_n(order, ['order_id', 'orderId', 'algoOrderId'])
1094
+ clientOrderId = self.omit_zero(self.safe_string_2(order, 'client_order_id', 'clientOrderId')) # Somehow, self always returns 0 for limit order
1095
+ marketId = self.safe_string(order, 'symbol')
1096
+ market = self.safe_market(marketId, market)
1097
+ symbol = market['symbol']
1098
+ price = self.safe_string_2(order, 'order_price', 'price')
1099
+ amount = self.safe_string_2(order, 'order_quantity', 'quantity') # This is base amount
1100
+ cost = self.safe_string_2(order, 'order_amount', 'amount') # This is quote amount
1101
+ orderType = self.safe_string_lower_2(order, 'order_type', 'type')
1102
+ status = self.safe_value_2(order, 'status', 'algoStatus')
1103
+ success = self.safe_bool(order, 'success')
1104
+ if success is not None:
1105
+ status = 'NEW' if (success) else 'REJECTED'
1106
+ side = self.safe_string_lower(order, 'side')
1107
+ filled = self.omit_zero(self.safe_value_2(order, 'executed', 'totalExecutedQuantity'))
1108
+ average = self.omit_zero(self.safe_string_2(order, 'average_executed_price', 'averageExecutedPrice'))
1109
+ remaining = Precise.string_sub(cost, filled)
1110
+ fee = self.safe_value_2(order, 'total_fee', 'totalFee')
1111
+ feeCurrency = self.safe_string_2(order, 'fee_asset', 'feeAsset')
1112
+ transactions = self.safe_value(order, 'Transactions')
1113
+ stopPrice = self.safe_number(order, 'triggerPrice')
1114
+ takeProfitPrice: Num = None
1115
+ stopLossPrice: Num = None
1116
+ childOrders = self.safe_value(order, 'childOrders')
1117
+ if childOrders is not None:
1118
+ first = self.safe_value(childOrders, 0)
1119
+ innerChildOrders = self.safe_value(first, 'childOrders', [])
1120
+ innerChildOrdersLength = len(innerChildOrders)
1121
+ if innerChildOrdersLength > 0:
1122
+ takeProfitOrder = self.safe_value(innerChildOrders, 0)
1123
+ stopLossOrder = self.safe_value(innerChildOrders, 1)
1124
+ takeProfitPrice = self.safe_number(takeProfitOrder, 'triggerPrice')
1125
+ stopLossPrice = self.safe_number(stopLossOrder, 'triggerPrice')
1126
+ lastUpdateTimestamp = self.safe_integer_2(order, 'updatedTime', 'updated_time')
1127
+ return self.safe_order({
1128
+ 'id': orderId,
1129
+ 'clientOrderId': clientOrderId,
1130
+ 'timestamp': timestamp,
1131
+ 'datetime': self.iso8601(timestamp),
1132
+ 'lastTradeTimestamp': None,
1133
+ 'lastUpdateTimestamp': lastUpdateTimestamp,
1134
+ 'status': self.parse_order_status(status),
1135
+ 'symbol': symbol,
1136
+ 'type': self.parse_order_type(orderType),
1137
+ 'timeInForce': self.parse_time_in_force(orderType),
1138
+ 'postOnly': None, # TO_DO
1139
+ 'reduceOnly': self.safe_bool(order, 'reduce_only'),
1140
+ 'side': side,
1141
+ 'price': price,
1142
+ 'stopPrice': stopPrice,
1143
+ 'triggerPrice': stopPrice,
1144
+ 'takeProfitPrice': takeProfitPrice,
1145
+ 'stopLossPrice': stopLossPrice,
1146
+ 'average': average,
1147
+ 'amount': amount,
1148
+ 'filled': filled,
1149
+ 'remaining': remaining, # TO_DO
1150
+ 'cost': cost,
1151
+ 'trades': transactions,
1152
+ 'fee': {
1153
+ 'cost': fee,
1154
+ 'currency': feeCurrency,
1155
+ },
1156
+ 'info': order,
1157
+ }, market)
1158
+
1159
+ def parse_time_in_force(self, timeInForce: Str):
1160
+ timeInForces: dict = {
1161
+ 'ioc': 'IOC',
1162
+ 'fok': 'FOK',
1163
+ 'post_only': 'PO',
1164
+ }
1165
+ return self.safe_string(timeInForces, timeInForce, None)
1166
+
1167
+ def parse_order_status(self, status: Str):
1168
+ if status is not None:
1169
+ statuses: dict = {
1170
+ 'NEW': 'open',
1171
+ 'FILLED': 'closed',
1172
+ 'CANCEL_SENT': 'canceled',
1173
+ 'CANCEL_ALL_SENT': 'canceled',
1174
+ 'CANCELLED': 'canceled',
1175
+ 'PARTIAL_FILLED': 'open',
1176
+ 'REJECTED': 'rejected',
1177
+ 'INCOMPLETE': 'open',
1178
+ 'COMPLETED': 'closed',
1179
+ }
1180
+ return self.safe_string(statuses, status, status)
1181
+ return status
1182
+
1183
+ def parse_order_type(self, type: Str):
1184
+ types: dict = {
1185
+ 'LIMIT': 'limit',
1186
+ 'MARKET': 'market',
1187
+ 'POST_ONLY': 'limit',
1188
+ }
1189
+ return self.safe_string_lower(types, type, type)
1190
+
1191
+ def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1192
+ """
1193
+ * @ignore
1194
+ helper function to build the request
1195
+ :param str symbol: unified symbol of the market to create an order in
1196
+ :param str type: 'market' or 'limit'
1197
+ :param str side: 'buy' or 'sell'
1198
+ :param float amount: how much you want to trade in units of the base currency
1199
+ :param float [price]: the price that the order is to be fullfilled, in units of the quote currency, ignored in market orders
1200
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1201
+ :returns dict: request to be sent to the exchange
1202
+ """
1203
+ reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only')
1204
+ orderType = type.upper()
1205
+ market = self.market(symbol)
1206
+ orderSide = side.upper()
1207
+ request: dict = {
1208
+ 'symbol': market['id'],
1209
+ 'side': orderSide,
1210
+ }
1211
+ stopPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
1212
+ stopLoss = self.safe_value(params, 'stopLoss')
1213
+ takeProfit = self.safe_value(params, 'takeProfit')
1214
+ algoType = self.safe_string(params, 'algoType')
1215
+ isStop = stopPrice is not None or stopLoss is not None or takeProfit is not None or (self.safe_value(params, 'childOrders') is not None)
1216
+ isMarket = orderType == 'MARKET'
1217
+ timeInForce = self.safe_string_lower(params, 'timeInForce')
1218
+ postOnly = self.is_post_only(isMarket, None, params)
1219
+ orderQtyKey = 'quantity' if isStop else 'order_quantity'
1220
+ priceKey = 'price' if isStop else 'order_price'
1221
+ typeKey = 'type' if isStop else 'order_type'
1222
+ request[typeKey] = orderType # LIMIT/MARKET/IOC/FOK/POST_ONLY/ASK/BID
1223
+ if not isStop:
1224
+ if postOnly:
1225
+ request['order_type'] = 'POST_ONLY'
1226
+ elif timeInForce == 'fok':
1227
+ request['order_type'] = 'FOK'
1228
+ elif timeInForce == 'ioc':
1229
+ request['order_type'] = 'IOC'
1230
+ if reduceOnly:
1231
+ request['reduce_only'] = reduceOnly
1232
+ if price is not None:
1233
+ request[priceKey] = self.price_to_precision(symbol, price)
1234
+ if isMarket and not isStop:
1235
+ request[orderQtyKey] = self.amount_to_precision(symbol, amount)
1236
+ elif algoType != 'POSITIONAL_TP_SL':
1237
+ request[orderQtyKey] = self.amount_to_precision(symbol, amount)
1238
+ clientOrderId = self.safe_string_n(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
1239
+ if clientOrderId is not None:
1240
+ request['client_order_id'] = clientOrderId
1241
+ if stopPrice is not None:
1242
+ request['trigger_price'] = self.price_to_precision(symbol, stopPrice)
1243
+ request['algo_type'] = 'STOP'
1244
+ elif (stopLoss is not None) or (takeProfit is not None):
1245
+ request['algo_type'] = 'TP_SL'
1246
+ outterOrder: dict = {
1247
+ 'symbol': market['id'],
1248
+ 'reduce_only': False,
1249
+ 'algo_type': 'POSITIONAL_TP_SL',
1250
+ 'child_orders': [],
1251
+ }
1252
+ closeSide = 'SELL' if (orderSide == 'BUY') else 'BUY'
1253
+ if stopLoss is not None:
1254
+ stopLossPrice = self.safe_number_2(stopLoss, 'triggerPrice', 'price', stopLoss)
1255
+ stopLossOrder: dict = {
1256
+ 'side': closeSide,
1257
+ 'algo_type': 'TP_SL',
1258
+ 'trigger_price': self.price_to_precision(symbol, stopLossPrice),
1259
+ 'type': 'LIMIT',
1260
+ 'reduce_only': True,
1261
+ }
1262
+ outterOrder['child_orders'].append(stopLossOrder)
1263
+ if takeProfit is not None:
1264
+ takeProfitPrice = self.safe_number_2(takeProfit, 'triggerPrice', 'price', takeProfit)
1265
+ takeProfitOrder: dict = {
1266
+ 'side': closeSide,
1267
+ 'algo_type': 'TP_SL',
1268
+ 'trigger_price': self.price_to_precision(symbol, takeProfitPrice),
1269
+ 'type': 'LIMIT',
1270
+ 'reduce_only': True,
1271
+ }
1272
+ outterOrder['child_orders'].append(takeProfitOrder)
1273
+ request['child_orders'] = [outterOrder]
1274
+ params = self.omit(params, ['reduceOnly', 'reduce_only', 'clOrdID', 'clientOrderId', 'client_order_id', 'postOnly', 'timeInForce', 'stopPrice', 'triggerPrice', 'stopLoss', 'takeProfit'])
1275
+ return self.extend(request, params)
1276
+
1277
+ async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1278
+ """
1279
+ create a trade order
1280
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/create-order
1281
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/create-algo-order
1282
+ :param str symbol: unified symbol of the market to create an order in
1283
+ :param str type: 'market' or 'limit'
1284
+ :param str side: 'buy' or 'sell'
1285
+ :param float amount: how much of currency you want to trade in units of base currency
1286
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1287
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1288
+ :param float [params.triggerPrice]: The price a trigger order is triggered at
1289
+ :param dict [params.takeProfit]: *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered(perpetual swap markets only)
1290
+ :param float [params.takeProfit.triggerPrice]: take profit trigger price
1291
+ :param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered(perpetual swap markets only)
1292
+ :param float [params.stopLoss.triggerPrice]: stop loss trigger price
1293
+ :param float [params.algoType]: 'STOP'or 'TP_SL' or 'POSITIONAL_TP_SL'
1294
+ :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
1295
+ :param str [params.clientOrderId]: a unique id for the order
1296
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1297
+ """
1298
+ await self.load_markets()
1299
+ market = self.market(symbol)
1300
+ request = self.create_order_request(symbol, type, side, amount, price, params)
1301
+ stopPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
1302
+ stopLoss = self.safe_value(params, 'stopLoss')
1303
+ takeProfit = self.safe_value(params, 'takeProfit')
1304
+ isStop = stopPrice is not None or stopLoss is not None or takeProfit is not None or (self.safe_value(params, 'childOrders') is not None)
1305
+ response = None
1306
+ if isStop:
1307
+ response = await self.v1PrivatePostAlgoOrder(request)
1308
+ #
1309
+ # {
1310
+ # "success": True,
1311
+ # "timestamp": 1702989203989,
1312
+ # "data": {
1313
+ # "order_id": 13,
1314
+ # "client_order_id": "testclientid",
1315
+ # "algo_type": "STOP",
1316
+ # "quantity": 100.12
1317
+ # }
1318
+ # }
1319
+ #
1320
+ else:
1321
+ response = await self.v1PrivatePostOrder(request)
1322
+ #
1323
+ # {
1324
+ # "success": True,
1325
+ # "timestamp": 1702989203989,
1326
+ # "data": {
1327
+ # "order_id": 13,
1328
+ # "client_order_id": "testclientid",
1329
+ # "order_type": "LIMIT",
1330
+ # "order_price": 100.12,
1331
+ # "order_quantity": 0.987654,
1332
+ # "order_amount": 0.8,
1333
+ # "error_message": "none"
1334
+ # }
1335
+ # }
1336
+ #
1337
+ data = self.safe_dict(response, 'data')
1338
+ data['timestamp'] = self.safe_integer(response, 'timestamp')
1339
+ order = self.parse_order(data, market)
1340
+ order['type'] = type
1341
+ return order
1342
+
1343
+ async def create_orders(self, orders: List[OrderRequest], params={}):
1344
+ """
1345
+ *contract only* create a list of trade orders
1346
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/batch-create-order
1347
+ :param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
1348
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1349
+ """
1350
+ await self.load_markets()
1351
+ ordersRequests = []
1352
+ for i in range(0, len(orders)):
1353
+ rawOrder = orders[i]
1354
+ marketId = self.safe_string(rawOrder, 'symbol')
1355
+ type = self.safe_string(rawOrder, 'type')
1356
+ side = self.safe_string(rawOrder, 'side')
1357
+ amount = self.safe_value(rawOrder, 'amount')
1358
+ price = self.safe_value(rawOrder, 'price')
1359
+ orderParams = self.safe_dict(rawOrder, 'params', {})
1360
+ stopPrice = self.safe_string_2(orderParams, 'triggerPrice', 'stopPrice')
1361
+ stopLoss = self.safe_value(orderParams, 'stopLoss')
1362
+ takeProfit = self.safe_value(orderParams, 'takeProfit')
1363
+ isStop = stopPrice is not None or stopLoss is not None or takeProfit is not None or (self.safe_value(orderParams, 'childOrders') is not None)
1364
+ if isStop:
1365
+ raise NotSupported(self.id + 'createOrders() only support non-stop order')
1366
+ orderRequest = self.create_order_request(marketId, type, side, amount, price, orderParams)
1367
+ ordersRequests.append(orderRequest)
1368
+ request: dict = {
1369
+ 'orders': ordersRequests,
1370
+ }
1371
+ response = await self.v1PrivatePostBatchOrder(self.extend(request, params))
1372
+ #
1373
+ # {
1374
+ # "success": True,
1375
+ # "timestamp": 1702989203989,
1376
+ # "data": {
1377
+ # "rows": [{
1378
+ # "order_id": 13,
1379
+ # "client_order_id": "testclientid",
1380
+ # "order_type": "LIMIT",
1381
+ # "order_price": 100.12,
1382
+ # "order_quantity": 0.987654,
1383
+ # "order_amount": 0.8,
1384
+ # "error_message": "none"
1385
+ # }]
1386
+ # }
1387
+ # }
1388
+ #
1389
+ data = self.safe_dict(response, 'data', {})
1390
+ rows = self.safe_list(data, 'rows', [])
1391
+ return self.parse_orders(rows)
1392
+
1393
+ async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
1394
+ """
1395
+ edit a trade order
1396
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/edit-order
1397
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/edit-algo-order
1398
+ :param str id: order id
1399
+ :param str symbol: unified symbol of the market to create an order in
1400
+ :param str type: 'market' or 'limit'
1401
+ :param str side: 'buy' or 'sell'
1402
+ :param float amount: how much of currency you want to trade in units of base currency
1403
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1404
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1405
+ :param float [params.triggerPrice]: The price a trigger order is triggered at
1406
+ :param float [params.stopLossPrice]: price to trigger stop-loss orders
1407
+ :param float [params.takeProfitPrice]: price to trigger take-profit orders
1408
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1409
+ """
1410
+ await self.load_markets()
1411
+ market = self.market(symbol)
1412
+ request: dict = {
1413
+ 'order_id': id,
1414
+ }
1415
+ stopPrice = self.safe_string_n(params, ['triggerPrice', 'stopPrice', 'takeProfitPrice', 'stopLossPrice'])
1416
+ if stopPrice is not None:
1417
+ request['triggerPrice'] = self.price_to_precision(symbol, stopPrice)
1418
+ isStop = (stopPrice is not None) or (self.safe_value(params, 'childOrders') is not None)
1419
+ orderQtyKey = 'quantity' if isStop else 'order_quantity'
1420
+ priceKey = 'price' if isStop else 'order_price'
1421
+ if price is not None:
1422
+ request[priceKey] = self.price_to_precision(symbol, price)
1423
+ if amount is not None:
1424
+ request[orderQtyKey] = self.amount_to_precision(symbol, amount)
1425
+ params = self.omit(params, ['stopPrice', 'triggerPrice', 'takeProfitPrice', 'stopLossPrice', 'trailingTriggerPrice', 'trailingAmount', 'trailingPercent'])
1426
+ response = None
1427
+ if isStop:
1428
+ response = await self.v1PrivatePutAlgoOrder(self.extend(request, params))
1429
+ else:
1430
+ request['symbol'] = market['id']
1431
+ request['side'] = side.upper()
1432
+ orderType = type.upper()
1433
+ timeInForce = self.safe_string_lower(params, 'timeInForce')
1434
+ isMarket = orderType == 'MARKET'
1435
+ postOnly = self.is_post_only(isMarket, None, params)
1436
+ if postOnly:
1437
+ request['order_type'] = 'POST_ONLY'
1438
+ elif timeInForce == 'fok':
1439
+ request['order_type'] = 'FOK'
1440
+ elif timeInForce == 'ioc':
1441
+ request['order_type'] = 'IOC'
1442
+ else:
1443
+ request['order_type'] = orderType
1444
+ clientOrderId = self.safe_string_n(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
1445
+ params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id', 'postOnly', 'timeInForce'])
1446
+ if clientOrderId is not None:
1447
+ request['client_order_id'] = clientOrderId
1448
+ # request['side'] = side.upper()
1449
+ # request['symbol'] = market['id']
1450
+ response = await self.v1PrivatePutOrder(self.extend(request, params))
1451
+ #
1452
+ # {
1453
+ # "success": True,
1454
+ # "timestamp": 1702989203989,
1455
+ # "data": {
1456
+ # "status": "EDIT_SENT"
1457
+ # }
1458
+ # }
1459
+ #
1460
+ data = self.safe_dict(response, 'data', {})
1461
+ data['timestamp'] = self.safe_integer(response, 'timestamp')
1462
+ return self.parse_order(data, market)
1463
+
1464
+ async def cancel_order(self, id: str, symbol: Str = None, params={}):
1465
+ """
1466
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/cancel-order
1467
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/cancel-order-by-client_order_id
1468
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/cancel-algo-order
1469
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/cancel-algo-order-by-client_order_id
1470
+ cancels an open order
1471
+ :param str id: order id
1472
+ :param str symbol: unified symbol of the market the order was made in
1473
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1474
+ :param boolean [params.trigger]: whether the order is a stop/algo order
1475
+ :param str [params.clientOrderId]: a unique id for the order
1476
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1477
+ """
1478
+ stop = self.safe_bool_2(params, 'stop', 'trigger', False)
1479
+ params = self.omit(params, ['stop', 'trigger'])
1480
+ if not stop and (symbol is None):
1481
+ raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
1482
+ await self.load_markets()
1483
+ market: Market = None
1484
+ if symbol is not None:
1485
+ market = self.market(symbol)
1486
+ request: dict = {
1487
+ 'symbol': market['id'],
1488
+ }
1489
+ clientOrderIdUnified = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
1490
+ clientOrderIdExchangeSpecific = self.safe_string(params, 'client_order_id', clientOrderIdUnified)
1491
+ isByClientOrder = clientOrderIdExchangeSpecific is not None
1492
+ response = None
1493
+ if stop:
1494
+ if isByClientOrder:
1495
+ request['client_order_id'] = clientOrderIdExchangeSpecific
1496
+ params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
1497
+ response = await self.v1PrivateDeleteAlgoClientOrder(self.extend(request, params))
1498
+ else:
1499
+ request['order_id'] = id
1500
+ response = await self.v1PrivateDeleteAlgoOrder(self.extend(request, params))
1501
+ else:
1502
+ if isByClientOrder:
1503
+ request['client_order_id'] = clientOrderIdExchangeSpecific
1504
+ params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
1505
+ response = await self.v1PrivateDeleteClientOrder(self.extend(request, params))
1506
+ else:
1507
+ request['order_id'] = id
1508
+ response = await self.v1PrivateDeleteOrder(self.extend(request, params))
1509
+ #
1510
+ # {
1511
+ # "success": True,
1512
+ # "timestamp": 1702989203989,
1513
+ # "data": {
1514
+ # "status": "CANCEL_SENT"
1515
+ # }
1516
+ # }
1517
+ #
1518
+ # {
1519
+ # "success": True,
1520
+ # "timestamp": 1702989203989,
1521
+ # "status": "CANCEL_SENT"
1522
+ # }
1523
+ #
1524
+ extendParams: dict = {'symbol': symbol}
1525
+ if isByClientOrder:
1526
+ extendParams['client_order_id'] = clientOrderIdExchangeSpecific
1527
+ else:
1528
+ extendParams['id'] = id
1529
+ if stop:
1530
+ return self.extend(self.parse_order(response), extendParams)
1531
+ data = self.safe_dict(response, 'data', {})
1532
+ return self.extend(self.parse_order(data), extendParams)
1533
+
1534
+ async def cancel_orders(self, ids: List[str], symbol: Str = None, params={}):
1535
+ """
1536
+ cancel multiple orders
1537
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/batch-cancel-orders
1538
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/batch-cancel-orders-by-client_order_id
1539
+ :param str[] ids: order ids
1540
+ :param str [symbol]: unified market symbol
1541
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1542
+ :param str[] [params.client_order_ids]: max length 10 e.g. ["my_id_1","my_id_2"], encode the double quotes. No space after comma
1543
+ :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1544
+ """
1545
+ await self.load_markets()
1546
+ clientOrderIds = self.safe_list_n(params, ['clOrdIDs', 'clientOrderIds', 'client_order_ids'])
1547
+ params = self.omit(params, ['clOrdIDs', 'clientOrderIds', 'client_order_ids'])
1548
+ request: dict = {}
1549
+ response = None
1550
+ if clientOrderIds:
1551
+ request['client_order_ids'] = ','.join(clientOrderIds)
1552
+ response = await self.v1PrivateDeleteClientBatchOrder(self.extend(request, params))
1553
+ else:
1554
+ request['order_ids'] = ','.join(ids)
1555
+ response = await self.v1PrivateDeleteBatchOrder(self.extend(request, params))
1556
+ #
1557
+ # {
1558
+ # "success": True,
1559
+ # "timestamp": 1702989203989,
1560
+ # "data": {
1561
+ # "status": "CANCEL_ALL_SENT"
1562
+ # }
1563
+ # }
1564
+ #
1565
+ return [self.safe_order({
1566
+ 'info': response,
1567
+ })]
1568
+
1569
+ async def cancel_all_orders(self, symbol: Str = None, params={}):
1570
+ """
1571
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/cancel-all-pending-algo-orders
1572
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/cancel-orders-in-bulk
1573
+ cancel all open orders in a market
1574
+ :param str symbol: unified market symbol
1575
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1576
+ :param boolean [params.trigger]: whether the order is a stop/algo order
1577
+ :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1578
+ """
1579
+ await self.load_markets()
1580
+ stop = self.safe_bool_2(params, 'stop', 'trigger')
1581
+ params = self.omit(params, ['stop', 'trigger'])
1582
+ request: dict = {}
1583
+ if symbol is not None:
1584
+ market = self.market(symbol)
1585
+ request['symbol'] = market['id']
1586
+ response = None
1587
+ if stop:
1588
+ response = await self.v1PrivateDeleteAlgoOrders(self.extend(request, params))
1589
+ else:
1590
+ response = await self.v1PrivateDeleteOrders(self.extend(request, params))
1591
+ # stop
1592
+ # {
1593
+ # "success": True,
1594
+ # "timestamp": 1702989203989,
1595
+ # "status": "CANCEL_ALL_SENT"
1596
+ # }
1597
+ #
1598
+ # {
1599
+ # "success": True,
1600
+ # "timestamp": 1702989203989,
1601
+ # "data": {
1602
+ # "status": "CANCEL_ALL_SENT"
1603
+ # }
1604
+ # }
1605
+ #
1606
+ return [
1607
+ {
1608
+ 'info': response,
1609
+ },
1610
+ ]
1611
+
1612
+ async def fetch_order(self, id: str, symbol: Str = None, params={}):
1613
+ """
1614
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-order-by-order_id
1615
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-order-by-client_order_id
1616
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-algo-order-by-order_id
1617
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-algo-order-by-client_order_id
1618
+ fetches information on an order made by the user
1619
+ :param str symbol: unified symbol of the market the order was made in
1620
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1621
+ :param boolean [params.trigger]: whether the order is a stop/algo order
1622
+ :param str [params.clientOrderId]: a unique id for the order
1623
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1624
+ """
1625
+ await self.load_markets()
1626
+ market = self.market(symbol) if (symbol is not None) else None
1627
+ stop = self.safe_bool_2(params, 'stop', 'trigger', False)
1628
+ request: dict = {}
1629
+ clientOrderId = self.safe_string_n(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
1630
+ params = self.omit(params, ['stop', 'trigger', 'clOrdID', 'clientOrderId', 'client_order_id'])
1631
+ response = None
1632
+ if stop:
1633
+ if clientOrderId:
1634
+ request['client_order_id'] = clientOrderId
1635
+ response = await self.v1PrivateGetAlgoClientOrderClientOrderId(self.extend(request, params))
1636
+ else:
1637
+ request['oid'] = id
1638
+ response = await self.v1PrivateGetAlgoOrderOid(self.extend(request, params))
1639
+ else:
1640
+ if clientOrderId:
1641
+ request['client_order_id'] = clientOrderId
1642
+ response = await self.v1PrivateGetClientOrderClientOrderId(self.extend(request, params))
1643
+ else:
1644
+ request['oid'] = id
1645
+ response = await self.v1PrivateGetOrderOid(self.extend(request, params))
1646
+ #
1647
+ # {
1648
+ # "success": True,
1649
+ # "timestamp": 1702989203989,
1650
+ # "data": {
1651
+ # "order_id": 78151,
1652
+ # "user_id": 12345,
1653
+ # "price": 0.67772,
1654
+ # "type": "LIMIT",
1655
+ # "quantity": 20,
1656
+ # "amount": 10,
1657
+ # "executed_quantity": 20,
1658
+ # "total_executed_quantity": 20,
1659
+ # "visible_quantity": 1,
1660
+ # "symbol": "PERP_WOO_USDC",
1661
+ # "side": "BUY",
1662
+ # "status": "FILLED",
1663
+ # "total_fee": 0.5,
1664
+ # "fee_asset": "WOO",
1665
+ # "client_order_id": 1,
1666
+ # "average_executed_price": 0.67772,
1667
+ # "created_time": 1653563963000,
1668
+ # "updated_time": 1653564213000,
1669
+ # "realized_pnl": 123
1670
+ # }
1671
+ # }
1672
+ #
1673
+ orders = self.safe_dict(response, 'data', response)
1674
+ return self.parse_order(orders, market)
1675
+
1676
+ async def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1677
+ """
1678
+ fetches information on multiple orders made by the user
1679
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-orders
1680
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-algo-orders
1681
+ :param str symbol: unified market symbol of the market orders were made in
1682
+ :param int [since]: the earliest time in ms to fetch orders for
1683
+ :param int [limit]: the maximum number of order structures to retrieve
1684
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1685
+ :param boolean [params.trigger]: whether the order is a stop/algo order
1686
+ :param boolean [params.is_triggered]: whether the order has been triggered(False by default)
1687
+ :param str [params.side]: 'buy' or 'sell'
1688
+ :param boolean [params.paginate]: set to True if you want to fetch orders with pagination
1689
+ :param int params['until']: timestamp in ms of the latest order to fetch
1690
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1691
+ """
1692
+ await self.load_markets()
1693
+ paginate = False
1694
+ isTrigger = self.safe_bool_2(params, 'stop', 'trigger', False)
1695
+ maxLimit = 100 if (isTrigger) else 500
1696
+ paginate, params = self.handle_option_and_params(params, 'fetchOrders', 'paginate')
1697
+ if paginate:
1698
+ return await self.fetch_paginated_call_incremental('fetchOrders', symbol, since, limit, params, 'page', maxLimit)
1699
+ request: dict = {}
1700
+ market: Market = None
1701
+ params = self.omit(params, ['stop', 'trigger'])
1702
+ if symbol is not None:
1703
+ market = self.market(symbol)
1704
+ request['symbol'] = market['id']
1705
+ if since is not None:
1706
+ request['start_t'] = since
1707
+ if limit is not None:
1708
+ request['size'] = limit
1709
+ else:
1710
+ request['size'] = maxLimit
1711
+ if isTrigger:
1712
+ request['algo_type'] = 'STOP'
1713
+ request, params = self.handle_until_option('end_t', request, params)
1714
+ response = None
1715
+ if isTrigger:
1716
+ response = await self.v1PrivateGetAlgoOrders(self.extend(request, params))
1717
+ else:
1718
+ response = await self.v1PrivateGetOrders(self.extend(request, params))
1719
+ #
1720
+ # {
1721
+ # "success": True,
1722
+ # "timestamp": 1702989203989,
1723
+ # "data": {
1724
+ # "meta": {
1725
+ # "total": 9,
1726
+ # "records_per_page": 25,
1727
+ # "current_page": 1
1728
+ # },
1729
+ # "rows": [{
1730
+ # "order_id": 78151,
1731
+ # "user_id": 12345,
1732
+ # "price": 0.67772,
1733
+ # "type": "LIMIT",
1734
+ # "quantity": 20,
1735
+ # "amount": 10,
1736
+ # "executed_quantity": 20,
1737
+ # "total_executed_quantity": 20,
1738
+ # "visible_quantity": 1,
1739
+ # "symbol": "PERP_WOO_USDC",
1740
+ # "side": "BUY",
1741
+ # "status": "FILLED",
1742
+ # "total_fee": 0.5,
1743
+ # "fee_asset": "WOO",
1744
+ # "client_order_id": 1,
1745
+ # "average_executed_price": 0.67772,
1746
+ # "created_time": 1653563963000,
1747
+ # "updated_time": 1653564213000,
1748
+ # "realized_pnl": 123
1749
+ # }]
1750
+ # }
1751
+ # }
1752
+ #
1753
+ data = self.safe_value(response, 'data', response)
1754
+ orders = self.safe_list(data, 'rows')
1755
+ return self.parse_orders(orders, market, since, limit)
1756
+
1757
+ async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1758
+ """
1759
+ fetches information on multiple orders made by the user
1760
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-orders
1761
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-algo-orders
1762
+ :param str symbol: unified market symbol of the market orders were made in
1763
+ :param int [since]: the earliest time in ms to fetch orders for
1764
+ :param int [limit]: the maximum number of order structures to retrieve
1765
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1766
+ :param boolean [params.trigger]: whether the order is a stop/algo order
1767
+ :param boolean [params.is_triggered]: whether the order has been triggered(False by default)
1768
+ :param str [params.side]: 'buy' or 'sell'
1769
+ :param int params['until']: timestamp in ms of the latest order to fetch
1770
+ :param boolean [params.paginate]: set to True if you want to fetch orders with pagination
1771
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1772
+ """
1773
+ await self.load_markets()
1774
+ extendedParams = self.extend(params, {'status': 'INCOMPLETE'})
1775
+ return await self.fetch_orders(symbol, since, limit, extendedParams)
1776
+
1777
+ async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1778
+ """
1779
+ fetches information on multiple orders made by the user
1780
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-orders
1781
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-algo-orders
1782
+ :param str symbol: unified market symbol of the market orders were made in
1783
+ :param int [since]: the earliest time in ms to fetch orders for
1784
+ :param int [limit]: the maximum number of order structures to retrieve
1785
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1786
+ :param boolean [params.trigger]: whether the order is a stop/algo order
1787
+ :param boolean [params.is_triggered]: whether the order has been triggered(False by default)
1788
+ :param str [params.side]: 'buy' or 'sell'
1789
+ :param int params['until']: timestamp in ms of the latest order to fetch
1790
+ :param boolean [params.paginate]: set to True if you want to fetch orders with pagination
1791
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1792
+ """
1793
+ await self.load_markets()
1794
+ extendedParams = self.extend(params, {'status': 'COMPLETED'})
1795
+ return await self.fetch_orders(symbol, since, limit, extendedParams)
1796
+
1797
+ async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1798
+ """
1799
+ fetch all the trades made from a single order
1800
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-all-trades-of-specific-order
1801
+ :param str id: order id
1802
+ :param str symbol: unified market symbol
1803
+ :param int [since]: the earliest time in ms to fetch trades for
1804
+ :param int [limit]: the maximum number of trades to retrieve
1805
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1806
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1807
+ """
1808
+ await self.load_markets()
1809
+ market: Market = None
1810
+ if symbol is not None:
1811
+ market = self.market(symbol)
1812
+ request: dict = {
1813
+ 'oid': id,
1814
+ }
1815
+ response = await self.v1PrivateGetOrderOidTrades(self.extend(request, params))
1816
+ #
1817
+ # {
1818
+ # "success": True,
1819
+ # "timestamp": 1702989203989,
1820
+ # "data": {
1821
+ # "rows": [{
1822
+ # "id": 2,
1823
+ # "symbol": "PERP_BTC_USDC",
1824
+ # "fee": 0.0001,
1825
+ # "fee_asset": "USDC",
1826
+ # "side": "BUY",
1827
+ # "order_id": 1,
1828
+ # "executed_price": 123,
1829
+ # "executed_quantity": 0.05,
1830
+ # "executed_timestamp": 1567382401000,
1831
+ # "is_maker": 1,
1832
+ # "realized_pnl": 123
1833
+ # }]
1834
+ # }
1835
+ # }
1836
+ #
1837
+ data = self.safe_dict(response, 'data', {})
1838
+ trades = self.safe_list(data, 'rows', [])
1839
+ return self.parse_trades(trades, market, since, limit, params)
1840
+
1841
+ async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1842
+ """
1843
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-trades
1844
+ fetch all trades made by the user
1845
+ :param str symbol: unified market symbol
1846
+ :param int [since]: the earliest time in ms to fetch trades for
1847
+ :param int [limit]: the maximum number of trades structures to retrieve
1848
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1849
+ :param boolean [params.paginate]: set to True if you want to fetch trades with pagination
1850
+ :param int params['until']: timestamp in ms of the latest trade to fetch
1851
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1852
+ """
1853
+ await self.load_markets()
1854
+ paginate = False
1855
+ paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
1856
+ if paginate:
1857
+ return await self.fetch_paginated_call_incremental('fetchMyTrades', symbol, since, limit, params, 'page', 500)
1858
+ request: dict = {}
1859
+ market: Market = None
1860
+ if symbol is not None:
1861
+ market = self.market(symbol)
1862
+ request['symbol'] = market['id']
1863
+ if since is not None:
1864
+ request['start_t'] = since
1865
+ if limit is not None:
1866
+ request['size'] = limit
1867
+ else:
1868
+ request['size'] = 500
1869
+ request, params = self.handle_until_option('end_t', request, params)
1870
+ response = await self.v1PrivateGetTrades(self.extend(request, params))
1871
+ #
1872
+ # {
1873
+ # "success": True,
1874
+ # "timestamp": 1702989203989,
1875
+ # "data": {
1876
+ # "meta": {
1877
+ # "total": 9,
1878
+ # "records_per_page": 25,
1879
+ # "current_page": 1
1880
+ # },
1881
+ # "rows": [{
1882
+ # "id": 2,
1883
+ # "symbol": "PERP_BTC_USDC",
1884
+ # "fee": 0.0001,
1885
+ # "fee_asset": "USDC",
1886
+ # "side": "BUY",
1887
+ # "order_id": 1,
1888
+ # "executed_price": 123,
1889
+ # "executed_quantity": 0.05,
1890
+ # "executed_timestamp": 1567382401000,
1891
+ # "is_maker": 1,
1892
+ # "realized_pnl": 123
1893
+ # }]
1894
+ # }
1895
+ # }
1896
+ #
1897
+ data = self.safe_dict(response, 'data', {})
1898
+ trades = self.safe_list(data, 'rows', [])
1899
+ return self.parse_trades(trades, market, since, limit, params)
1900
+
1901
+ def parse_balance(self, response) -> Balances:
1902
+ result: dict = {
1903
+ 'info': response,
1904
+ }
1905
+ balances = self.safe_list(response, 'holding', [])
1906
+ for i in range(0, len(balances)):
1907
+ balance = balances[i]
1908
+ code = self.safe_currency_code(self.safe_string(balance, 'token'))
1909
+ account = self.account()
1910
+ account['total'] = self.safe_string(balance, 'holding')
1911
+ account['frozen'] = self.safe_string(balance, 'frozen')
1912
+ result[code] = account
1913
+ return self.safe_balance(result)
1914
+
1915
+ async def fetch_balance(self, params={}) -> Balances:
1916
+ """
1917
+ query for balance and get the amount of funds available for trading or funds locked in orders
1918
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-current-holding
1919
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1920
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1921
+ """
1922
+ await self.load_markets()
1923
+ response = await self.v1PrivateGetClientHolding(params)
1924
+ #
1925
+ # {
1926
+ # "success": True,
1927
+ # "timestamp": 1702989203989,
1928
+ # "data": {
1929
+ # "holding": [{
1930
+ # "updated_time": 1580794149000,
1931
+ # "token": "BTC",
1932
+ # "holding": -28.000752,
1933
+ # "frozen": 123,
1934
+ # "pending_short": -2000
1935
+ # }]
1936
+ # }
1937
+ # }
1938
+ #
1939
+ data = self.safe_dict(response, 'data')
1940
+ return self.parse_balance(data)
1941
+
1942
+ async def get_asset_history_rows(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> Any:
1943
+ await self.load_markets()
1944
+ request: dict = {}
1945
+ currency: Currency = None
1946
+ if code is not None:
1947
+ currency = self.currency(code)
1948
+ request['balance_token'] = currency['id']
1949
+ if since is not None:
1950
+ request['start_t'] = since
1951
+ if limit is not None:
1952
+ request['pageSize'] = limit
1953
+ transactionType = self.safe_string(params, 'type')
1954
+ params = self.omit(params, 'type')
1955
+ if transactionType is not None:
1956
+ request['type'] = transactionType
1957
+ response = await self.v1PrivateGetAssetHistory(self.extend(request, params))
1958
+ #
1959
+ # {
1960
+ # "success": True,
1961
+ # "timestamp": 1702989203989,
1962
+ # "data": {
1963
+ # "meta": {
1964
+ # "total": 9,
1965
+ # "records_per_page": 25,
1966
+ # "current_page": 1
1967
+ # },
1968
+ # "rows": [{
1969
+ # "id": "230707030600002",
1970
+ # "tx_id": "0x4b0714c63cc7abae72bf68e84e25860b88ca651b7d27dad1e32bf4c027fa5326",
1971
+ # "side": "WITHDRAW",
1972
+ # "token": "USDC",
1973
+ # "amount": 555,
1974
+ # "fee": 123,
1975
+ # "trans_status": "FAILED",
1976
+ # "created_time": 1688699193034,
1977
+ # "updated_time": 1688699193096,
1978
+ # "chain_id": "986532"
1979
+ # }]
1980
+ # }
1981
+ # }
1982
+ #
1983
+ data = self.safe_dict(response, 'data', {})
1984
+ return [currency, self.safe_list(data, 'rows', [])]
1985
+
1986
+ def parse_ledger_entry(self, item: dict, currency: Currency = None):
1987
+ code = self.safe_string(item, 'token')
1988
+ amount = self.safe_number(item, 'amount')
1989
+ side = self.safe_string(item, 'token_side')
1990
+ direction = 'in' if (side == 'DEPOSIT') else 'out'
1991
+ timestamp = self.safe_integer(item, 'created_time')
1992
+ fee = self.parse_token_and_fee_temp(item, 'fee_token', 'fee_amount')
1993
+ return {
1994
+ 'id': self.safe_string(item, 'id'),
1995
+ 'currency': code,
1996
+ 'account': self.safe_string(item, 'account'),
1997
+ 'referenceAccount': None,
1998
+ 'referenceId': self.safe_string(item, 'tx_id'),
1999
+ 'status': self.parse_transaction_status(self.safe_string(item, 'status')),
2000
+ 'amount': amount,
2001
+ 'before': None,
2002
+ 'after': None,
2003
+ 'fee': fee,
2004
+ 'direction': direction,
2005
+ 'timestamp': timestamp,
2006
+ 'datetime': self.iso8601(timestamp),
2007
+ 'type': self.parse_ledger_entry_type(self.safe_string(item, 'type')),
2008
+ 'info': item,
2009
+ }
2010
+
2011
+ def parse_ledger_entry_type(self, type):
2012
+ types: dict = {
2013
+ 'BALANCE': 'transaction', # Funds moved in/out wallet
2014
+ 'COLLATERAL': 'transfer', # Funds moved between portfolios
2015
+ }
2016
+ return self.safe_string(types, type, type)
2017
+
2018
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
2019
+ """
2020
+ fetch the history of changes, actions done by the user or operations that altered balance of the user
2021
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-asset-history
2022
+ :param str code: unified currency code, default is None
2023
+ :param int [since]: timestamp in ms of the earliest ledger entry, default is None
2024
+ :param int [limit]: max number of ledger entrys to return, default is None
2025
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2026
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
2027
+ """
2028
+ currency, rows = await self.get_asset_history_rows(code, since, limit, params)
2029
+ return self.parse_ledger(rows, currency, since, limit, params)
2030
+
2031
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
2032
+ # example in fetchLedger
2033
+ code = self.safe_string(transaction, 'token')
2034
+ movementDirection = self.safe_string_lower(transaction, 'token_side')
2035
+ if movementDirection == 'withdraw':
2036
+ movementDirection = 'withdrawal'
2037
+ fee = self.parse_token_and_fee_temp(transaction, 'fee_token', 'fee_amount')
2038
+ addressTo = self.safe_string(transaction, 'target_address')
2039
+ addressFrom = self.safe_string(transaction, 'source_address')
2040
+ timestamp = self.safe_integer(transaction, 'created_time')
2041
+ return {
2042
+ 'info': transaction,
2043
+ 'id': self.safe_string_2(transaction, 'id', 'withdraw_id'),
2044
+ 'txid': self.safe_string(transaction, 'tx_id'),
2045
+ 'timestamp': timestamp,
2046
+ 'datetime': self.iso8601(timestamp),
2047
+ 'address': None,
2048
+ 'addressFrom': addressFrom,
2049
+ 'addressTo': addressTo,
2050
+ 'tag': self.safe_string(transaction, 'extra'),
2051
+ 'tagFrom': None,
2052
+ 'tagTo': None,
2053
+ 'type': movementDirection,
2054
+ 'amount': self.safe_number(transaction, 'amount'),
2055
+ 'currency': code,
2056
+ 'status': self.parse_transaction_status(self.safe_string(transaction, 'status')),
2057
+ 'updated': self.safe_integer(transaction, 'updated_time'),
2058
+ 'comment': None,
2059
+ 'internal': None,
2060
+ 'fee': fee,
2061
+ 'network': None,
2062
+ }
2063
+
2064
+ def parse_transaction_status(self, status: Str):
2065
+ statuses: dict = {
2066
+ 'NEW': 'pending',
2067
+ 'CONFIRMING': 'pending',
2068
+ 'PROCESSING': 'pending',
2069
+ 'COMPLETED': 'ok',
2070
+ 'CANCELED': 'canceled',
2071
+ }
2072
+ return self.safe_string(statuses, status, status)
2073
+
2074
+ async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2075
+ """
2076
+ fetch all deposits made to an account
2077
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-asset-history
2078
+ :param str code: unified currency code
2079
+ :param int [since]: the earliest time in ms to fetch deposits for
2080
+ :param int [limit]: the maximum number of deposits structures to retrieve
2081
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2082
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2083
+ """
2084
+ request: dict = {
2085
+ 'side': 'DEPOSIT',
2086
+ }
2087
+ return await self.fetch_deposits_withdrawals(code, since, limit, self.extend(request, params))
2088
+
2089
+ async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2090
+ """
2091
+ fetch all withdrawals made from an account
2092
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-asset-history
2093
+ :param str code: unified currency code
2094
+ :param int [since]: the earliest time in ms to fetch withdrawals for
2095
+ :param int [limit]: the maximum number of withdrawals structures to retrieve
2096
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2097
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2098
+ """
2099
+ request: dict = {
2100
+ 'side': 'WITHDRAW',
2101
+ }
2102
+ return await self.fetch_deposits_withdrawals(code, since, limit, self.extend(request, params))
2103
+
2104
+ async def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2105
+ """
2106
+ fetch history of deposits and withdrawals
2107
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-asset-history
2108
+ :param str [code]: unified currency code for the currency of the deposit/withdrawals, default is None
2109
+ :param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
2110
+ :param int [limit]: max number of deposit/withdrawals to return, default is None
2111
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2112
+ :returns dict: a list of `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
2113
+ """
2114
+ request: dict = {}
2115
+ currency, rows = await self.get_asset_history_rows(code, since, limit, self.extend(request, params))
2116
+ #
2117
+ # {
2118
+ # "rows":[],
2119
+ # "meta":{
2120
+ # "total":0,
2121
+ # "records_per_page":25,
2122
+ # "current_page":1
2123
+ # },
2124
+ # "success":true
2125
+ # }
2126
+ #
2127
+ return self.parse_transactions(rows, currency, since, limit, params)
2128
+
2129
+ async def get_withdraw_nonce(self, params={}):
2130
+ response = await self.v1PrivateGetWithdrawNonce(params)
2131
+ #
2132
+ # {
2133
+ # "success": True,
2134
+ # "timestamp": 1702989203989,
2135
+ # "data": {
2136
+ # "withdraw_nonce": 1
2137
+ # }
2138
+ # }
2139
+ #
2140
+ data = self.safe_dict(response, 'data', {})
2141
+ return self.safe_number(data, 'withdraw_nonce')
2142
+
2143
+ def hash_message(self, message):
2144
+ return '0x' + self.hash(message, 'keccak', 'hex')
2145
+
2146
+ def sign_hash(self, hash, privateKey):
2147
+ signature = self.ecdsa(hash[-64:], privateKey[-64:], 'secp256k1', None)
2148
+ r = signature['r']
2149
+ s = signature['s']
2150
+ v = self.int_to_base16(self.sum(27, signature['v']))
2151
+ return '0x' + r.rjust(64, '0') + s.rjust(64, '0') + v
2152
+
2153
+ def sign_message(self, message, privateKey):
2154
+ return self.sign_hash(self.hash_message(message), privateKey[-64:])
2155
+
2156
+ async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
2157
+ """
2158
+ make a withdrawal
2159
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/create-withdraw-request
2160
+ :param str code: unified currency code
2161
+ :param float amount: the amount to withdraw
2162
+ :param str address: the address to withdraw to
2163
+ :param str tag:
2164
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2165
+ :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
2166
+ """
2167
+ await self.load_markets()
2168
+ self.check_address(address)
2169
+ if code is not None:
2170
+ code = code.upper()
2171
+ if code != 'USDC':
2172
+ raise NotSupported(self.id + 'withdraw() only support USDC')
2173
+ currency = self.currency(code)
2174
+ verifyingContractAddress = self.safe_string(self.options, 'verifyingContractAddress')
2175
+ chainId = self.safe_string(params, 'chainId')
2176
+ currencyNetworks = self.safe_dict(currency, 'networks', {})
2177
+ coinNetwork = self.safe_dict(currencyNetworks, chainId, {})
2178
+ coinNetworkId = self.safe_number(coinNetwork, 'id')
2179
+ if coinNetworkId is None:
2180
+ raise BadRequest(self.id + ' withdraw() require chainId parameter')
2181
+ withdrawNonce = await self.get_withdraw_nonce(params)
2182
+ nonce = self.nonce()
2183
+ domain: dict = {
2184
+ 'chainId': chainId,
2185
+ 'name': 'Orderly',
2186
+ 'verifyingContract': verifyingContractAddress,
2187
+ 'version': '1',
2188
+ }
2189
+ messageTypes: dict = {
2190
+ 'Withdraw': [
2191
+ {'name': 'brokerId', 'type': 'string'},
2192
+ {'name': 'chainId', 'type': 'uint256'},
2193
+ {'name': 'receiver', 'type': 'address'},
2194
+ {'name': 'token', 'type': 'string'},
2195
+ {'name': 'amount', 'type': 'uint256'},
2196
+ {'name': 'withdrawNonce', 'type': 'uint64'},
2197
+ {'name': 'timestamp', 'type': 'uint64'},
2198
+ ],
2199
+ }
2200
+ withdrawRequest: dict = {
2201
+ 'brokerId': self.safe_string(self.options, 'keyBrokerId', 'woofi_pro'),
2202
+ 'chainId': self.parse_to_int(chainId),
2203
+ 'receiver': address,
2204
+ 'token': code,
2205
+ 'amount': str(amount),
2206
+ 'withdrawNonce': withdrawNonce,
2207
+ 'timestamp': nonce,
2208
+ }
2209
+ msg = self.eth_encode_structured_data(domain, messageTypes, withdrawRequest)
2210
+ signature = self.sign_message(msg, self.privateKey)
2211
+ request: dict = {
2212
+ 'signature': signature,
2213
+ 'userAddress': address,
2214
+ 'verifyingContract': verifyingContractAddress,
2215
+ 'message': withdrawRequest,
2216
+ }
2217
+ params = self.omit(params, 'chainId')
2218
+ response = await self.v1PrivatePostWithdrawRequest(self.extend(request, params))
2219
+ #
2220
+ # {
2221
+ # "success": True,
2222
+ # "timestamp": 1702989203989,
2223
+ # "data": {
2224
+ # "withdraw_id": 123
2225
+ # }
2226
+ # }
2227
+ #
2228
+ data = self.safe_dict(response, 'data', {})
2229
+ return self.parse_transaction(data, currency)
2230
+
2231
+ def parse_leverage(self, leverage, market=None) -> Leverage:
2232
+ leverageValue = self.safe_integer(leverage, 'max_leverage')
2233
+ return {
2234
+ 'info': leverage,
2235
+ 'symbol': market['symbol'],
2236
+ 'marginMode': None,
2237
+ 'longLeverage': leverageValue,
2238
+ 'shortLeverage': leverageValue,
2239
+ }
2240
+
2241
+ async def fetch_leverage(self, symbol: str, params={}) -> Leverage:
2242
+ """
2243
+ fetch the set leverage for a market
2244
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-account-information
2245
+ :param str symbol: unified market symbol
2246
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2247
+ :returns dict: a `leverage structure <https://docs.ccxt.com/#/?id=leverage-structure>`
2248
+ """
2249
+ await self.load_markets()
2250
+ market = self.market(symbol)
2251
+ response = await self.v1PrivateGetClientInfo(params)
2252
+ #
2253
+ # {
2254
+ # "success": True,
2255
+ # "timestamp": 1702989203989,
2256
+ # "data": {
2257
+ # "account_id": "<string>",
2258
+ # "email": "test@test.com",
2259
+ # "account_mode": "FUTURES",
2260
+ # "max_leverage": 20,
2261
+ # "taker_fee_rate": 123,
2262
+ # "maker_fee_rate": 123,
2263
+ # "futures_taker_fee_rate": 123,
2264
+ # "futures_maker_fee_rate": 123,
2265
+ # "maintenance_cancel_orders": True,
2266
+ # "imr_factor": {
2267
+ # "PERP_BTC_USDC": 123,
2268
+ # "PERP_ETH_USDC": 123,
2269
+ # "PERP_NEAR_USDC": 123
2270
+ # },
2271
+ # "max_notional": {
2272
+ # "PERP_BTC_USDC": 123,
2273
+ # "PERP_ETH_USDC": 123,
2274
+ # "PERP_NEAR_USDC": 123
2275
+ # }
2276
+ # }
2277
+ # }
2278
+ #
2279
+ data = self.safe_dict(response, 'data', {})
2280
+ return self.parse_leverage(data, market)
2281
+
2282
+ async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
2283
+ """
2284
+ set the level of leverage for a market
2285
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/update-leverage-setting
2286
+ :param str symbol: unified market symbol
2287
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2288
+ :returns dict: response from the exchange
2289
+ """
2290
+ await self.load_markets()
2291
+ if (leverage < 1) or (leverage > 50):
2292
+ raise BadRequest(self.id + ' leverage should be between 1 and 50')
2293
+ request: dict = {
2294
+ 'leverage': leverage,
2295
+ }
2296
+ return await self.v1PrivatePostClientLeverage(self.extend(request, params))
2297
+
2298
+ def parse_position(self, position: dict, market: Market = None):
2299
+ #
2300
+ # {
2301
+ # "IMR_withdraw_orders": 0.1,
2302
+ # "MMR_with_orders": 0.05,
2303
+ # "average_open_price": 27908.14386047,
2304
+ # "cost_position": -139329.358492,
2305
+ # "est_liq_price": 117335.92899428,
2306
+ # "fee_24_h": 123,
2307
+ # "imr": 0.1,
2308
+ # "last_sum_unitary_funding": 70.38,
2309
+ # "mark_price": 27794.9,
2310
+ # "mmr": 0.05,
2311
+ # "pending_long_qty": 123,
2312
+ # "pending_short_qty": 123,
2313
+ # "pnl_24_h": 123,
2314
+ # "position_qty": -5,
2315
+ # "settle_price": 27865.8716984,
2316
+ # "symbol": "PERP_BTC_USDC",
2317
+ # "timestamp": 1685429350571,
2318
+ # "unsettled_pnl": 354.858492
2319
+ # }
2320
+ #
2321
+ contract = self.safe_string(position, 'symbol')
2322
+ market = self.safe_market(contract, market)
2323
+ size = self.safe_string(position, 'position_qty')
2324
+ side: Str = None
2325
+ if Precise.string_gt(size, '0'):
2326
+ side = 'long'
2327
+ else:
2328
+ side = 'short'
2329
+ contractSize = self.safe_string(market, 'contractSize')
2330
+ markPrice = self.safe_string(position, 'mark_price')
2331
+ timestamp = self.safe_integer(position, 'timestamp')
2332
+ entryPrice = self.safe_string(position, 'average_open_price')
2333
+ unrealisedPnl = self.safe_string(position, 'unsettled_pnl')
2334
+ size = Precise.string_abs(size)
2335
+ notional = Precise.string_mul(size, markPrice)
2336
+ return self.safe_position({
2337
+ 'info': position,
2338
+ 'id': None,
2339
+ 'symbol': self.safe_string(market, 'symbol'),
2340
+ 'timestamp': timestamp,
2341
+ 'datetime': self.iso8601(timestamp),
2342
+ 'lastUpdateTimestamp': None,
2343
+ 'initialMargin': None,
2344
+ 'initialMarginPercentage': None,
2345
+ 'maintenanceMargin': None,
2346
+ 'maintenanceMarginPercentage': None,
2347
+ 'entryPrice': self.parse_number(entryPrice),
2348
+ 'notional': self.parse_number(notional),
2349
+ 'leverage': None,
2350
+ 'unrealizedPnl': self.parse_number(unrealisedPnl),
2351
+ 'contracts': self.parse_number(size),
2352
+ 'contractSize': self.parse_number(contractSize),
2353
+ 'marginRatio': None,
2354
+ 'liquidationPrice': self.safe_number(position, 'est_liq_price'),
2355
+ 'markPrice': self.parse_number(markPrice),
2356
+ 'lastPrice': None,
2357
+ 'collateral': None,
2358
+ 'marginMode': 'cross',
2359
+ 'marginType': None,
2360
+ 'side': side,
2361
+ 'percentage': None,
2362
+ 'hedged': None,
2363
+ 'stopLossPrice': None,
2364
+ 'takeProfitPrice': None,
2365
+ })
2366
+
2367
+ async def fetch_position(self, symbol: Str = None, params={}):
2368
+ """
2369
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-one-position-info
2370
+ fetch data on an open position
2371
+ :param str symbol: unified market symbol of the market the position is held in
2372
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2373
+ :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
2374
+ """
2375
+ await self.load_markets()
2376
+ market = self.market(symbol)
2377
+ request: dict = {
2378
+ 'symbol': market['id'],
2379
+ }
2380
+ response = await self.v1PrivateGetPositionSymbol(self.extend(request, params))
2381
+ #
2382
+ # {
2383
+ # "success": True,
2384
+ # "timestamp": 1702989203989,
2385
+ # "data": {
2386
+ # "IMR_withdraw_orders": 0.1,
2387
+ # "MMR_with_orders": 0.05,
2388
+ # "average_open_price": 27908.14386047,
2389
+ # "cost_position": -139329.358492,
2390
+ # "est_liq_price": 117335.92899428,
2391
+ # "fee_24_h": 123,
2392
+ # "imr": 0.1,
2393
+ # "last_sum_unitary_funding": 70.38,
2394
+ # "mark_price": 27794.9,
2395
+ # "mmr": 0.05,
2396
+ # "pending_long_qty": 123,
2397
+ # "pending_short_qty": 123,
2398
+ # "pnl_24_h": 123,
2399
+ # "position_qty": -5,
2400
+ # "settle_price": 27865.8716984,
2401
+ # "symbol": "PERP_BTC_USDC",
2402
+ # "timestamp": 1685429350571,
2403
+ # "unsettled_pnl": 354.858492
2404
+ # }
2405
+ # }
2406
+ #
2407
+ data = self.safe_dict(response, 'data')
2408
+ return self.parse_position(data, market)
2409
+
2410
+ async def fetch_positions(self, symbols: Strings = None, params={}):
2411
+ """
2412
+ fetch all open positions
2413
+ :see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-all-positions-info
2414
+ :param str[] [symbols]: list of unified market symbols
2415
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2416
+ :param str [method]: method name to call, "positionRisk", "account" or "option", default is "positionRisk"
2417
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
2418
+ """
2419
+ await self.load_markets()
2420
+ response = await self.v1PrivateGetPositions(params)
2421
+ #
2422
+ # {
2423
+ # "success": True,
2424
+ # "timestamp": 1702989203989,
2425
+ # "data": {
2426
+ # "current_margin_ratio_with_orders": 1.2385,
2427
+ # "free_collateral": 450315.09115,
2428
+ # "initial_margin_ratio": 0.1,
2429
+ # "initial_margin_ratio_with_orders": 0.1,
2430
+ # "maintenance_margin_ratio": 0.05,
2431
+ # "maintenance_margin_ratio_with_orders": 0.05,
2432
+ # "margin_ratio": 1.2385,
2433
+ # "open_margin_ratio": 1.2102,
2434
+ # "total_collateral_value": 489865.71329,
2435
+ # "total_pnl_24_h": 123,
2436
+ # "rows": [{
2437
+ # "IMR_withdraw_orders": 0.1,
2438
+ # "MMR_with_orders": 0.05,
2439
+ # "average_open_price": 27908.14386047,
2440
+ # "cost_position": -139329.358492,
2441
+ # "est_liq_price": 117335.92899428,
2442
+ # "fee_24_h": 123,
2443
+ # "imr": 0.1,
2444
+ # "last_sum_unitary_funding": 70.38,
2445
+ # "mark_price": 27794.9,
2446
+ # "mmr": 0.05,
2447
+ # "pending_long_qty": 123,
2448
+ # "pending_short_qty": 123,
2449
+ # "pnl_24_h": 123,
2450
+ # "position_qty": -5,
2451
+ # "settle_price": 27865.8716984,
2452
+ # "symbol": "PERP_BTC_USDC",
2453
+ # "timestamp": 1685429350571,
2454
+ # "unsettled_pnl": 354.858492
2455
+ # }]
2456
+ # }
2457
+ # }
2458
+ #
2459
+ result = self.safe_dict(response, 'data', {})
2460
+ positions = self.safe_list(result, 'rows', [])
2461
+ return self.parse_positions(positions, symbols)
2462
+
2463
+ def nonce(self):
2464
+ return self.milliseconds()
2465
+
2466
+ def sign(self, path, section='public', method='GET', params={}, headers=None, body=None):
2467
+ version = section[0]
2468
+ access = section[1]
2469
+ pathWithParams = self.implode_params(path, params)
2470
+ url = self.implode_hostname(self.urls['api'][access])
2471
+ url += '/' + version + '/'
2472
+ params = self.omit(params, self.extract_params(path))
2473
+ params = self.keysort(params)
2474
+ if access == 'public':
2475
+ url += pathWithParams
2476
+ if params:
2477
+ url += '?' + self.urlencode(params)
2478
+ else:
2479
+ self.check_required_credentials()
2480
+ if (method == 'POST' or method == 'PUT') and (path == 'algo/order' or path == 'order' or path == 'batch-order'):
2481
+ isSandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
2482
+ if not isSandboxMode:
2483
+ brokerId = self.safe_string(self.options, 'brokerId', 'CCXT')
2484
+ if path == 'batch-order':
2485
+ ordersList = self.safe_list(params, 'orders', [])
2486
+ for i in range(0, len(ordersList)):
2487
+ params['orders'][i]['order_tag'] = brokerId
2488
+ else:
2489
+ params['order_tag'] = brokerId
2490
+ params = self.keysort(params)
2491
+ auth = ''
2492
+ ts = str(self.nonce())
2493
+ url += pathWithParams
2494
+ headers = {
2495
+ 'orderly-account-id': self.accountId,
2496
+ 'orderly-key': self.apiKey,
2497
+ 'orderly-timestamp': ts,
2498
+ }
2499
+ auth = ts + method + '/' + version + '/' + pathWithParams
2500
+ if method == 'POST' or method == 'PUT':
2501
+ body = self.json(params)
2502
+ auth += body
2503
+ headers['content-type'] = 'application/json'
2504
+ else:
2505
+ if params:
2506
+ url += '?' + self.urlencode(params)
2507
+ auth += '?' + self.rawencode(params)
2508
+ headers['content-type'] = 'application/x-www-form-urlencoded'
2509
+ if method == 'DELETE':
2510
+ body = ''
2511
+ secret = self.secret
2512
+ if secret.find('ed25519:') >= 0:
2513
+ parts = secret.split('ed25519:')
2514
+ secret = parts[1]
2515
+ signature = self.eddsa(self.encode(auth), self.base58_to_binary(secret), 'ed25519')
2516
+ headers['orderly-signature'] = self.urlencode_base64(self.base64_to_binary(signature))
2517
+ return {'url': url, 'method': method, 'body': body, 'headers': headers}
2518
+
2519
+ def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
2520
+ if not response:
2521
+ return None # fallback to default error handler
2522
+ #
2523
+ # 400 Bad Request {"success":false,"code":-1012,"message":"Amount is required for buy market orders when margin disabled."}
2524
+ # {"code":"-1011","message":"The system is under maintenance.","success":false}
2525
+ #
2526
+ success = self.safe_bool(response, 'success')
2527
+ errorCode = self.safe_string(response, 'code')
2528
+ if not success:
2529
+ feedback = self.id + ' ' + self.json(response)
2530
+ self.throw_broadly_matched_exception(self.exceptions['broad'], body, feedback)
2531
+ self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
2532
+ raise ExchangeError(feedback)
2533
+ return None