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,1617 @@
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.bitfinex import ImplicitAPI
8
+ import hashlib
9
+ from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction, TransferEntry
10
+ from typing import List
11
+ from ccxt.base.errors import ExchangeError
12
+ from ccxt.base.errors import AuthenticationError
13
+ from ccxt.base.errors import PermissionDenied
14
+ from ccxt.base.errors import ArgumentsRequired
15
+ from ccxt.base.errors import BadSymbol
16
+ from ccxt.base.errors import InsufficientFunds
17
+ from ccxt.base.errors import InvalidOrder
18
+ from ccxt.base.errors import OrderNotFound
19
+ from ccxt.base.errors import NotSupported
20
+ from ccxt.base.errors import RateLimitExceeded
21
+ from ccxt.base.errors import ExchangeNotAvailable
22
+ from ccxt.base.errors import InvalidNonce
23
+ from ccxt.base.decimal_to_precision import ROUND
24
+ from ccxt.base.decimal_to_precision import TRUNCATE
25
+ from ccxt.base.decimal_to_precision import DECIMAL_PLACES
26
+ from ccxt.base.decimal_to_precision import SIGNIFICANT_DIGITS
27
+ from ccxt.base.precise import Precise
28
+
29
+
30
+ class bitfinex(Exchange, ImplicitAPI):
31
+
32
+ def describe(self):
33
+ return self.deep_extend(super(bitfinex, self).describe(), {
34
+ 'id': 'bitfinex',
35
+ 'name': 'Bitfinex',
36
+ 'countries': ['VG'],
37
+ 'version': 'v1',
38
+ # cheapest is 90 requests a minute = 1.5 requests per second on average =>( 1000ms / 1.5) = 666.666 ms between requests on average
39
+ 'rateLimit': 666.666,
40
+ 'pro': True,
41
+ # new metainfo interface
42
+ 'has': {
43
+ 'CORS': None,
44
+ 'spot': True,
45
+ 'margin': None, # has but unimplemented
46
+ 'swap': None, # has but unimplemented
47
+ 'future': None,
48
+ 'option': None,
49
+ 'cancelAllOrders': True,
50
+ 'cancelOrder': True,
51
+ 'createDepositAddress': True,
52
+ 'createOrder': True,
53
+ 'editOrder': True,
54
+ 'fetchBalance': True,
55
+ 'fetchClosedOrders': True,
56
+ 'fetchDepositAddress': True,
57
+ 'fetchDeposits': False,
58
+ 'fetchDepositsWithdrawals': True,
59
+ 'fetchDepositWithdrawFee': 'emulated',
60
+ 'fetchDepositWithdrawFees': True,
61
+ 'fetchIndexOHLCV': False,
62
+ 'fetchLeverageTiers': False,
63
+ 'fetchMarginMode': False,
64
+ 'fetchMarkets': True,
65
+ 'fetchMarkOHLCV': False,
66
+ 'fetchMyTrades': True,
67
+ 'fetchOHLCV': True,
68
+ 'fetchOpenOrders': True,
69
+ 'fetchOrder': True,
70
+ 'fetchOrderBook': True,
71
+ 'fetchPositionMode': False,
72
+ 'fetchPositions': True,
73
+ 'fetchPremiumIndexOHLCV': False,
74
+ 'fetchTicker': True,
75
+ 'fetchTickers': True,
76
+ 'fetchTime': False,
77
+ 'fetchTrades': True,
78
+ 'fetchTradingFee': False,
79
+ 'fetchTradingFees': True,
80
+ 'fetchTransactionFees': True,
81
+ 'fetchTransactions': 'emulated',
82
+ 'transfer': True,
83
+ 'withdraw': True,
84
+ },
85
+ 'timeframes': {
86
+ '1m': '1m',
87
+ '5m': '5m',
88
+ '15m': '15m',
89
+ '30m': '30m',
90
+ '1h': '1h',
91
+ '3h': '3h',
92
+ '4h': '4h',
93
+ '6h': '6h',
94
+ '12h': '12h',
95
+ '1d': '1D',
96
+ '1w': '7D',
97
+ '2w': '14D',
98
+ '1M': '1M',
99
+ },
100
+ 'urls': {
101
+ 'logo': 'https://user-images.githubusercontent.com/1294454/27766244-e328a50c-5ed2-11e7-947b-041416579bb3.jpg',
102
+ 'api': {
103
+ 'v2': 'https://api-pub.bitfinex.com', # https://github.com/ccxt/ccxt/issues/5109
104
+ 'public': 'https://api.bitfinex.com',
105
+ 'private': 'https://api.bitfinex.com',
106
+ },
107
+ 'www': 'https://www.bitfinex.com',
108
+ 'referral': 'https://www.bitfinex.com/?refcode=P61eYxFL',
109
+ 'doc': [
110
+ 'https://docs.bitfinex.com/v1/docs',
111
+ 'https://github.com/bitfinexcom/bitfinex-api-node',
112
+ ],
113
+ },
114
+ 'api': {
115
+ # v2 symbol ids require a 't' prefix
116
+ # just the public part of it(use bitfinex2 for everything else)
117
+ 'v2': {
118
+ 'get': {
119
+ 'platform/status': 3, # 30 requests per minute
120
+ 'tickers': 1, # 90 requests a minute
121
+ 'ticker/{symbol}': 1,
122
+ 'tickers/hist': 1,
123
+ 'trades/{symbol}/hist': 1,
124
+ 'book/{symbol}/{precision}': 0.375, # 240 requests per minute = 4 requests per second(1000ms / rateLimit) / 4 = 0.37500375
125
+ 'book/{symbol}/P0': 0.375,
126
+ 'book/{symbol}/P1': 0.375,
127
+ 'book/{symbol}/P2': 0.375,
128
+ 'book/{symbol}/P3': 0.375,
129
+ 'book/{symbol}/R0': 0.375,
130
+ 'stats1/{key}:{size}:{symbol}:{side}/{section}': 1, # 90 requests a minute
131
+ 'stats1/{key}:{size}:{symbol}/{section}': 1,
132
+ 'stats1/{key}:{size}:{symbol}:long/last': 1,
133
+ 'stats1/{key}:{size}:{symbol}:long/hist': 1,
134
+ 'stats1/{key}:{size}:{symbol}:short/last': 1,
135
+ 'stats1/{key}:{size}:{symbol}:short/hist': 1,
136
+ 'candles/trade:{timeframe}:{symbol}/{section}': 1, # 90 requests a minute
137
+ 'candles/trade:{timeframe}:{symbol}/last': 1,
138
+ 'candles/trade:{timeframe}:{symbol}/hist': 1,
139
+ },
140
+ },
141
+ 'public': {
142
+ 'get': {
143
+ 'book/{symbol}': 1, # 90 requests a minute
144
+ # 'candles/{symbol}':0,
145
+ 'lendbook/{currency}': 6, # 15 requests a minute
146
+ 'lends/{currency}': 3, # 30 requests a minute
147
+ 'pubticker/{symbol}': 3, # 30 requests a minute = 0.5 requests per second =>(1000ms / rateLimit) / 0.5 = 3.00003
148
+ 'stats/{symbol}': 6, # 15 requests a minute = 0.25 requests per second =>(1000ms / rateLimit ) /0.25 = 6.00006(endpoint returns red html... or 'unknown symbol')
149
+ 'symbols': 18, # 5 requests a minute = 0.08333 requests per second =>(1000ms / rateLimit) / 0.08333 = 18.0009
150
+ 'symbols_details': 18, # 5 requests a minute
151
+ 'tickers': 1, # endpoint not mentioned in v1 docs... but still responds
152
+ 'trades/{symbol}': 3, # 60 requests a minute = 1 request per second =>(1000ms / rateLimit) / 1 = 1.5 ... but only works if set to 3
153
+ },
154
+ },
155
+ 'private': {
156
+ 'post': {
157
+ 'account_fees': 18,
158
+ 'account_infos': 6,
159
+ 'balances': 9.036, # 10 requests a minute = 0.166 requests per second =>(1000ms / rateLimit) / 0.166 = 9.036
160
+ 'basket_manage': 6,
161
+ 'credits': 6,
162
+ 'deposit/new': 18,
163
+ 'funding/close': 6,
164
+ 'history': 6, # 15 requests a minute
165
+ 'history/movements': 6,
166
+ 'key_info': 6,
167
+ 'margin_infos': 3, # 30 requests a minute
168
+ 'mytrades': 3,
169
+ 'mytrades_funding': 6,
170
+ 'offer/cancel': 6,
171
+ 'offer/new': 6,
172
+ 'offer/status': 6,
173
+ 'offers': 6,
174
+ 'offers/hist': 90.03, # one request per minute
175
+ 'order/cancel': 0.2,
176
+ 'order/cancel/all': 0.2,
177
+ 'order/cancel/multi': 0.2,
178
+ 'order/cancel/replace': 0.2,
179
+ 'order/new': 0.2, # 450 requests a minute = 7.5 request a second =>(1000ms / rateLimit) / 7.5 = 0.2000002
180
+ 'order/new/multi': 0.2,
181
+ 'order/status': 0.2,
182
+ 'orders': 0.2,
183
+ 'orders/hist': 90.03, # one request per minute = 0.1666 =>(1000ms / rateLimit) / 0.01666 = 90.03
184
+ 'position/claim': 18,
185
+ 'position/close': 18,
186
+ 'positions': 18,
187
+ 'summary': 18,
188
+ 'taken_funds': 6,
189
+ 'total_taken_funds': 6,
190
+ 'transfer': 18,
191
+ 'unused_taken_funds': 6,
192
+ 'withdraw': 18,
193
+ },
194
+ },
195
+ },
196
+ 'fees': {
197
+ 'trading': {
198
+ 'feeSide': 'get',
199
+ 'tierBased': True,
200
+ 'percentage': True,
201
+ 'maker': self.parse_number('0.001'),
202
+ 'taker': self.parse_number('0.002'),
203
+ 'tiers': {
204
+ 'taker': [
205
+ [self.parse_number('0'), self.parse_number('0.002')],
206
+ [self.parse_number('500000'), self.parse_number('0.002')],
207
+ [self.parse_number('1000000'), self.parse_number('0.002')],
208
+ [self.parse_number('2500000'), self.parse_number('0.002')],
209
+ [self.parse_number('5000000'), self.parse_number('0.002')],
210
+ [self.parse_number('7500000'), self.parse_number('0.002')],
211
+ [self.parse_number('10000000'), self.parse_number('0.0018')],
212
+ [self.parse_number('15000000'), self.parse_number('0.0016')],
213
+ [self.parse_number('20000000'), self.parse_number('0.0014')],
214
+ [self.parse_number('25000000'), self.parse_number('0.0012')],
215
+ [self.parse_number('30000000'), self.parse_number('0.001')],
216
+ ],
217
+ 'maker': [
218
+ [self.parse_number('0'), self.parse_number('0.001')],
219
+ [self.parse_number('500000'), self.parse_number('0.0008')],
220
+ [self.parse_number('1000000'), self.parse_number('0.0006')],
221
+ [self.parse_number('2500000'), self.parse_number('0.0004')],
222
+ [self.parse_number('5000000'), self.parse_number('0.0002')],
223
+ [self.parse_number('7500000'), self.parse_number('0')],
224
+ [self.parse_number('10000000'), self.parse_number('0')],
225
+ [self.parse_number('15000000'), self.parse_number('0')],
226
+ [self.parse_number('20000000'), self.parse_number('0')],
227
+ [self.parse_number('25000000'), self.parse_number('0')],
228
+ [self.parse_number('30000000'), self.parse_number('0')],
229
+ ],
230
+ },
231
+ },
232
+ 'funding': {
233
+ 'tierBased': False, # True for tier-based/progressive
234
+ 'percentage': False, # fixed commission
235
+ # Actually deposit fees are free for larger deposits(> $1000 USD equivalent)
236
+ # these values below are deprecated, we should not hardcode fees and limits anymore
237
+ # to be reimplemented with bitfinex funding fees from their API or web endpoints
238
+ 'deposit': {},
239
+ 'withdraw': {},
240
+ },
241
+ },
242
+ # todo rewrite for https://api-pub.bitfinex.com//v2/conf/pub:map:tx:method
243
+ 'commonCurrencies': {
244
+ 'ALG': 'ALGO', # https://github.com/ccxt/ccxt/issues/6034
245
+ 'AMP': 'AMPL',
246
+ 'ATO': 'ATOM', # https://github.com/ccxt/ccxt/issues/5118
247
+ 'BCHABC': 'XEC',
248
+ 'BCHN': 'BCH',
249
+ 'DAT': 'DATA',
250
+ 'DOG': 'MDOGE',
251
+ 'DSH': 'DASH',
252
+ # https://github.com/ccxt/ccxt/issues/7399
253
+ # https://coinmarketcap.com/currencies/pnetwork/
254
+ # https://en.cryptonomist.ch/blog/eidoo/the-edo-to-pnt-upgrade-what-you-need-to-know-updated/
255
+ 'EDO': 'PNT',
256
+ 'EUS': 'EURS',
257
+ 'EUT': 'EURT',
258
+ 'IDX': 'ID',
259
+ 'IOT': 'IOTA',
260
+ 'IQX': 'IQ',
261
+ 'LUNA': 'LUNC',
262
+ 'LUNA2': 'LUNA',
263
+ 'MNA': 'MANA',
264
+ 'ORS': 'ORS Group', # conflict with Origin Sport #3230
265
+ 'PAS': 'PASS',
266
+ 'QSH': 'QASH',
267
+ 'QTM': 'QTUM',
268
+ 'RBT': 'RBTC',
269
+ 'SNG': 'SNGLS',
270
+ 'STJ': 'STORJ',
271
+ 'TERRAUST': 'USTC',
272
+ 'TSD': 'TUSD',
273
+ 'YGG': 'YEED', # conflict with Yield Guild Games
274
+ 'YYW': 'YOYOW',
275
+ 'UDC': 'USDC',
276
+ 'UST': 'USDT',
277
+ 'VSY': 'VSYS',
278
+ 'WAX': 'WAXP',
279
+ 'XCH': 'XCHF',
280
+ 'ZBT': 'ZB',
281
+ },
282
+ 'exceptions': {
283
+ 'exact': {
284
+ 'temporarily_unavailable': ExchangeNotAvailable, # Sorry, the service is temporarily unavailable. See https://www.bitfinex.com/ for more info.
285
+ 'Order could not be cancelled.': OrderNotFound, # non-existent order
286
+ 'No such order found.': OrderNotFound, # ?
287
+ 'Order price must be positive.': InvalidOrder, # on price <= 0
288
+ 'Could not find a key matching the given X-BFX-APIKEY.': AuthenticationError,
289
+ 'Key price should be a decimal number, e.g. "123.456"': InvalidOrder, # on isNaN(price)
290
+ 'Key amount should be a decimal number, e.g. "123.456"': InvalidOrder, # on isNaN(amount)
291
+ 'ERR_RATE_LIMIT': RateLimitExceeded,
292
+ 'Ratelimit': RateLimitExceeded,
293
+ 'Nonce is too small.': InvalidNonce,
294
+ 'No summary found.': ExchangeError, # fetchTradingFees(summary) endpoint can give self vague error message
295
+ 'Cannot evaluate your available balance, please try again': ExchangeNotAvailable,
296
+ 'Unknown symbol': BadSymbol,
297
+ 'Cannot complete transfer. Exchange balance insufficient.': InsufficientFunds,
298
+ 'Momentary balance check. Please wait few seconds and try the transfer again.': ExchangeError,
299
+ },
300
+ 'broad': {
301
+ 'Invalid X-BFX-SIGNATURE': AuthenticationError,
302
+ 'This API key does not have permission': PermissionDenied, # authenticated but not authorized
303
+ 'not enough exchange balance for ': InsufficientFunds, # when buying cost is greater than the available quote currency
304
+ 'minimum size for ': InvalidOrder, # when amount below limits.amount.min
305
+ 'Invalid order': InvalidOrder, # ?
306
+ 'The available balance is only': InsufficientFunds, # {"status":"error","message":"Cannot withdraw 1.0027 ETH from your exchange wallet. The available balance is only 0.0 ETH. If you have limit orders, open positions, unused or active margin funding, self will decrease your available balance. To increase it, you can cancel limit orders or reduce/close your positions.","withdrawal_id":0,"fees":"0.0027"}
307
+ },
308
+ },
309
+ 'precisionMode': SIGNIFICANT_DIGITS,
310
+ 'options': {
311
+ 'currencyNames': {
312
+ 'AGI': 'agi',
313
+ 'AID': 'aid',
314
+ 'AIO': 'aio',
315
+ 'ANT': 'ant',
316
+ 'AVT': 'aventus', # #1811
317
+ 'BAT': 'bat',
318
+ # https://github.com/ccxt/ccxt/issues/5833
319
+ 'BCH': 'bab', # undocumented
320
+ # 'BCH': 'bcash', # undocumented
321
+ 'BCI': 'bci',
322
+ 'BFT': 'bft',
323
+ 'BSV': 'bsv',
324
+ 'BTC': 'bitcoin',
325
+ 'BTG': 'bgold',
326
+ 'CFI': 'cfi',
327
+ 'COMP': 'comp',
328
+ 'DAI': 'dai',
329
+ 'DADI': 'dad',
330
+ 'DASH': 'dash',
331
+ 'DATA': 'datacoin',
332
+ 'DTH': 'dth',
333
+ 'EDO': 'eidoo', # #1811
334
+ 'ELF': 'elf',
335
+ 'EOS': 'eos',
336
+ 'ETC': 'ethereumc',
337
+ 'ETH': 'ethereum',
338
+ 'ETP': 'metaverse',
339
+ 'FUN': 'fun',
340
+ 'GNT': 'golem',
341
+ 'IOST': 'ios',
342
+ 'IOTA': 'iota',
343
+ # https://github.com/ccxt/ccxt/issues/5833
344
+ 'LEO': 'let', # ETH chain
345
+ # 'LEO': 'les', # EOS chain
346
+ 'LINK': 'link',
347
+ 'LRC': 'lrc',
348
+ 'LTC': 'litecoin',
349
+ 'LYM': 'lym',
350
+ 'MANA': 'mna',
351
+ 'MIT': 'mit',
352
+ 'MKR': 'mkr',
353
+ 'MTN': 'mtn',
354
+ 'NEO': 'neo',
355
+ 'ODE': 'ode',
356
+ 'OMG': 'omisego',
357
+ 'OMNI': 'mastercoin',
358
+ 'QASH': 'qash',
359
+ 'QTUM': 'qtum', # #1811
360
+ 'RCN': 'rcn',
361
+ 'RDN': 'rdn',
362
+ 'REP': 'rep',
363
+ 'REQ': 'req',
364
+ 'RLC': 'rlc',
365
+ 'SAN': 'santiment',
366
+ 'SNGLS': 'sng',
367
+ 'SNT': 'status',
368
+ 'SPANK': 'spk',
369
+ 'STORJ': 'stj',
370
+ 'TNB': 'tnb',
371
+ 'TRX': 'trx',
372
+ 'TUSD': 'tsd',
373
+ 'USD': 'wire',
374
+ 'USDC': 'udc', # https://github.com/ccxt/ccxt/issues/5833
375
+ 'UTK': 'utk',
376
+ 'USDT': 'tetheruso', # Tether on Omni
377
+ # 'USDT': 'tetheruse', # Tether on ERC20
378
+ # 'USDT': 'tetherusl', # Tether on Liquid
379
+ # 'USDT': 'tetherusx', # Tether on Tron
380
+ # 'USDT': 'tetheruss', # Tether on EOS
381
+ 'VEE': 'vee',
382
+ 'WAX': 'wax',
383
+ 'XLM': 'xlm',
384
+ 'XMR': 'monero',
385
+ 'XRP': 'ripple',
386
+ 'XVG': 'xvg',
387
+ 'YOYOW': 'yoyow',
388
+ 'ZEC': 'zcash',
389
+ 'ZRX': 'zrx',
390
+ 'XTZ': 'xtz',
391
+ },
392
+ 'orderTypes': {
393
+ 'limit': 'exchange limit',
394
+ 'market': 'exchange market',
395
+ },
396
+ 'fiat': {
397
+ 'USD': 'USD',
398
+ 'EUR': 'EUR',
399
+ 'JPY': 'JPY',
400
+ 'GBP': 'GBP',
401
+ 'CNH': 'CNH',
402
+ },
403
+ 'accountsByType': {
404
+ 'spot': 'exchange',
405
+ 'margin': 'trading',
406
+ 'funding': 'deposit',
407
+ 'swap': 'trading',
408
+ },
409
+ },
410
+ })
411
+
412
+ async def fetch_transaction_fees(self, codes: Strings = None, params={}):
413
+ """
414
+ * @deprecated
415
+ please use fetchDepositWithdrawFees instead
416
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-fees
417
+ :param str[]|None codes: list of unified currency codes
418
+ :param dict [params]: extra parameters specific to the exchange API endpoint
419
+ :returns dict[]: a list of `fees structures <https://docs.ccxt.com/#/?id=fee-structure>`
420
+ """
421
+ await self.load_markets()
422
+ result: dict = {}
423
+ response = await self.privatePostAccountFees(params)
424
+ #
425
+ # {
426
+ # "withdraw": {
427
+ # "BTC": "0.0004",
428
+ # }
429
+ # }
430
+ #
431
+ fees = self.safe_value(response, 'withdraw')
432
+ ids = list(fees.keys())
433
+ for i in range(0, len(ids)):
434
+ id = ids[i]
435
+ code = self.safe_currency_code(id)
436
+ if (codes is not None) and not self.in_array(code, codes):
437
+ continue
438
+ result[code] = {
439
+ 'withdraw': self.safe_number(fees, id),
440
+ 'deposit': {},
441
+ 'info': self.safe_number(fees, id),
442
+ }
443
+ return result
444
+
445
+ async def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
446
+ """
447
+ fetch deposit and withdraw fees
448
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-fees
449
+ :param str[]|None codes: list of unified currency codes
450
+ :param dict [params]: extra parameters specific to the exchange API endpoint
451
+ :returns dict[]: a list of `fees structures <https://docs.ccxt.com/#/?id=fee-structure>`
452
+ """
453
+ await self.load_markets()
454
+ response = await self.privatePostAccountFees(params)
455
+ #
456
+ # {
457
+ # "withdraw": {
458
+ # "BTC": "0.0004",
459
+ # ...
460
+ # }
461
+ # }
462
+ #
463
+ withdraw = self.safe_list(response, 'withdraw')
464
+ return self.parse_deposit_withdraw_fees(withdraw, codes)
465
+
466
+ def parse_deposit_withdraw_fee(self, fee, currency: Currency = None):
467
+ #
468
+ # '0.0004'
469
+ #
470
+ return {
471
+ 'withdraw': {
472
+ 'fee': self.parse_number(fee),
473
+ 'percentage': None,
474
+ },
475
+ 'deposit': {
476
+ 'fee': None,
477
+ 'percentage': None,
478
+ },
479
+ 'networks': {},
480
+ 'info': fee,
481
+ }
482
+
483
+ async def fetch_trading_fees(self, params={}) -> TradingFees:
484
+ """
485
+ fetch the trading fees for multiple markets
486
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-summary
487
+ :param dict [params]: extra parameters specific to the exchange API endpoint
488
+ :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
489
+ """
490
+ await self.load_markets()
491
+ response = await self.privatePostSummary(params)
492
+ #
493
+ # {
494
+ # "time": "2022-02-23T16:05:47.659000Z",
495
+ # "status": {resid_hint: null, login_last: "2022-02-23T16:05:48Z"},
496
+ # "is_locked": False,
497
+ # "leo_lev": "0",
498
+ # "leo_amount_avg": "0.0",
499
+ # "trade_vol_30d": [
500
+ # {
501
+ # "curr": "Total(USD)",
502
+ # "vol": "0.0",
503
+ # "vol_safe": "0.0",
504
+ # "vol_maker": "0.0",
505
+ # "vol_BFX": "0.0",
506
+ # "vol_BFX_safe": "0.0",
507
+ # "vol_BFX_maker": "0.0"
508
+ # }
509
+ # ],
510
+ # "fees_funding_30d": {},
511
+ # "fees_funding_total_30d": "0",
512
+ # "fees_trading_30d": {},
513
+ # "fees_trading_total_30d": "0",
514
+ # "rebates_trading_30d": {},
515
+ # "rebates_trading_total_30d": "0",
516
+ # "maker_fee": "0.001",
517
+ # "taker_fee": "0.002",
518
+ # "maker_fee_2crypto": "0.001",
519
+ # "maker_fee_2stablecoin": "0.001",
520
+ # "maker_fee_2fiat": "0.001",
521
+ # "maker_fee_2deriv": "0.0002",
522
+ # "taker_fee_2crypto": "0.002",
523
+ # "taker_fee_2stablecoin": "0.002",
524
+ # "taker_fee_2fiat": "0.002",
525
+ # "taker_fee_2deriv": "0.00065",
526
+ # "deriv_maker_rebate": "0.0002",
527
+ # "deriv_taker_fee": "0.00065",
528
+ # "trade_last": null
529
+ # }
530
+ #
531
+ result: dict = {}
532
+ fiat = self.safe_value(self.options, 'fiat', {})
533
+ makerFee = self.safe_number(response, 'maker_fee')
534
+ takerFee = self.safe_number(response, 'taker_fee')
535
+ makerFee2Fiat = self.safe_number(response, 'maker_fee_2fiat')
536
+ takerFee2Fiat = self.safe_number(response, 'taker_fee_2fiat')
537
+ makerFee2Deriv = self.safe_number(response, 'maker_fee_2deriv')
538
+ takerFee2Deriv = self.safe_number(response, 'taker_fee_2deriv')
539
+ for i in range(0, len(self.symbols)):
540
+ symbol = self.symbols[i]
541
+ market = self.market(symbol)
542
+ fee = {
543
+ 'info': response,
544
+ 'symbol': symbol,
545
+ 'percentage': True,
546
+ 'tierBased': True,
547
+ }
548
+ if market['quote'] in fiat:
549
+ fee['maker'] = makerFee2Fiat
550
+ fee['taker'] = takerFee2Fiat
551
+ elif market['contract']:
552
+ fee['maker'] = makerFee2Deriv
553
+ fee['taker'] = takerFee2Deriv
554
+ else:
555
+ fee['maker'] = makerFee
556
+ fee['taker'] = takerFee
557
+ result[symbol] = fee
558
+ return result
559
+
560
+ async def fetch_markets(self, params={}) -> List[Market]:
561
+ """
562
+ retrieves data on all markets for bitfinex
563
+ :see: https://docs.bitfinex.com/v1/reference/rest-public-symbols
564
+ :see: https://docs.bitfinex.com/v1/reference/rest-public-symbol-details
565
+ :param dict [params]: extra parameters specific to the exchange API endpoint
566
+ :returns dict[]: an array of objects representing market data
567
+ """
568
+ ids = await self.publicGetSymbols()
569
+ #
570
+ # ["btcusd", "ltcusd", "ltcbtc"]
571
+ #
572
+ details = await self.publicGetSymbolsDetails()
573
+ #
574
+ # [
575
+ # {
576
+ # "pair":"btcusd",
577
+ # "price_precision":5,
578
+ # "initial_margin":"10.0",
579
+ # "minimum_margin":"5.0",
580
+ # "maximum_order_size":"2000.0",
581
+ # "minimum_order_size":"0.0002",
582
+ # "expiration":"NA",
583
+ # "margin":true
584
+ # },
585
+ # ]
586
+ #
587
+ result = []
588
+ for i in range(0, len(details)):
589
+ market = details[i]
590
+ id = self.safe_string(market, 'pair')
591
+ if not self.in_array(id, ids):
592
+ continue
593
+ id = id.upper()
594
+ baseId = None
595
+ quoteId = None
596
+ if id.find(':') >= 0:
597
+ parts = id.split(':')
598
+ baseId = parts[0]
599
+ quoteId = parts[1]
600
+ else:
601
+ baseId = id[0:3]
602
+ quoteId = id[3:6]
603
+ base = self.safe_currency_code(baseId)
604
+ quote = self.safe_currency_code(quoteId)
605
+ symbol = base + '/' + quote
606
+ type = 'spot'
607
+ if id.find('F0') > -1:
608
+ type = 'swap'
609
+ result.append({
610
+ 'id': id,
611
+ 'symbol': symbol,
612
+ 'base': base,
613
+ 'quote': quote,
614
+ 'settle': None,
615
+ 'baseId': baseId,
616
+ 'quoteId': quoteId,
617
+ 'settleId': None,
618
+ 'type': type,
619
+ 'spot': (type == 'spot'),
620
+ 'margin': self.safe_value(market, 'margin'),
621
+ 'swap': (type == 'swap'),
622
+ 'future': False,
623
+ 'option': False,
624
+ 'active': True,
625
+ 'contract': (type == 'swap'),
626
+ 'linear': None,
627
+ 'inverse': None,
628
+ 'contractSize': None,
629
+ 'expiry': None,
630
+ 'expiryDatetime': None,
631
+ 'strike': None,
632
+ 'optionType': None,
633
+ 'precision': {
634
+ # https://docs.bitfinex.com/docs/introduction#amount-precision
635
+ # The amount field allows up to 8 decimals.
636
+ # Anything exceeding self will be rounded to the 8th decimal.
637
+ 'amount': int('8'),
638
+ 'price': self.safe_integer(market, 'price_precision'),
639
+ },
640
+ 'limits': {
641
+ 'leverage': {
642
+ 'min': None,
643
+ 'max': None,
644
+ },
645
+ 'amount': {
646
+ 'min': self.safe_number(market, 'minimum_order_size'),
647
+ 'max': self.safe_number(market, 'maximum_order_size'),
648
+ },
649
+ 'price': {
650
+ 'min': self.parse_number('1e-8'),
651
+ 'max': None,
652
+ },
653
+ 'cost': {
654
+ 'min': None,
655
+ 'max': None,
656
+ },
657
+ },
658
+ 'created': None,
659
+ 'info': market,
660
+ })
661
+ return result
662
+
663
+ def amount_to_precision(self, symbol, amount):
664
+ # https://docs.bitfinex.com/docs/introduction#amount-precision
665
+ # The amount field allows up to 8 decimals.
666
+ # Anything exceeding self will be rounded to the 8th decimal.
667
+ symbol = self.safe_symbol(symbol)
668
+ return self.decimal_to_precision(amount, TRUNCATE, self.markets[symbol]['precision']['amount'], DECIMAL_PLACES)
669
+
670
+ def price_to_precision(self, symbol, price):
671
+ symbol = self.safe_symbol(symbol)
672
+ price = self.decimal_to_precision(price, ROUND, self.markets[symbol]['precision']['price'], self.precisionMode)
673
+ # https://docs.bitfinex.com/docs/introduction#price-precision
674
+ # The precision level of all trading prices is based on significant figures.
675
+ # All pairs on Bitfinex use up to 5 significant digits and up to 8 decimals(e.g. 1.2345, 123.45, 1234.5, 0.00012345).
676
+ # Prices submit with a precision larger than 5 will be cut by the API.
677
+ return self.decimal_to_precision(price, TRUNCATE, 8, DECIMAL_PLACES)
678
+
679
+ async def fetch_balance(self, params={}) -> Balances:
680
+ """
681
+ query for balance and get the amount of funds available for trading or funds locked in orders
682
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-wallet-balances
683
+ :param dict [params]: extra parameters specific to the exchange API endpoint
684
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
685
+ """
686
+ await self.load_markets()
687
+ accountsByType = self.safe_value(self.options, 'accountsByType', {})
688
+ requestedType = self.safe_string(params, 'type', 'exchange')
689
+ accountType = self.safe_string(accountsByType, requestedType, requestedType)
690
+ if accountType is None:
691
+ keys = list(accountsByType.keys())
692
+ raise ExchangeError(self.id + ' fetchBalance() type parameter must be one of ' + ', '.join(keys))
693
+ query = self.omit(params, 'type')
694
+ response = await self.privatePostBalances(query)
695
+ # [{type: "deposit",
696
+ # "currency": "btc",
697
+ # "amount": "0.00116721",
698
+ # "available": "0.00116721"},
699
+ # {type: "exchange",
700
+ # "currency": "ust",
701
+ # "amount": "0.0000002",
702
+ # "available": "0.0000002"},
703
+ # {type: "trading",
704
+ # "currency": "btc",
705
+ # "amount": "0.0005",
706
+ # "available": "0.0005"}],
707
+ result: dict = {'info': response}
708
+ isDerivative = requestedType == 'derivatives'
709
+ for i in range(0, len(response)):
710
+ balance = response[i]
711
+ type = self.safe_string(balance, 'type')
712
+ currencyId = self.safe_string_lower(balance, 'currency', '')
713
+ start = len(currencyId) - 2
714
+ isDerivativeCode = currencyId[start:] == 'f0'
715
+ # self will only filter the derivative codes if the requestedType is 'derivatives'
716
+ derivativeCondition = (not isDerivative or isDerivativeCode)
717
+ if (accountType == type) and derivativeCondition:
718
+ code = self.safe_currency_code(currencyId)
719
+ # bitfinex had BCH previously, now it's BAB, but the old
720
+ # BCH symbol is kept for backward-compatibility
721
+ # we need a workaround here so that the old BCH balance
722
+ # would not override the new BAB balance(BAB is unified to BCH)
723
+ # https://github.com/ccxt/ccxt/issues/4989
724
+ if not (code in result):
725
+ account = self.account()
726
+ account['free'] = self.safe_string(balance, 'available')
727
+ account['total'] = self.safe_string(balance, 'amount')
728
+ result[code] = account
729
+ return self.safe_balance(result)
730
+
731
+ async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
732
+ """
733
+ transfer currency internally between wallets on the same account
734
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-transfer-between-wallets
735
+ :param str code: unified currency code
736
+ :param float amount: amount to transfer
737
+ :param str fromAccount: account to transfer from
738
+ :param str toAccount: account to transfer to
739
+ :param dict [params]: extra parameters specific to the exchange API endpoint
740
+ :returns dict: a `transfer structure <https://docs.ccxt.com/#/?id=transfer-structure>`
741
+ """
742
+ # transferring between derivatives wallet and regular wallet is not documented in their API
743
+ # however we support it in CCXT(from just looking at web inspector)
744
+ await self.load_markets()
745
+ accountsByType = self.safe_value(self.options, 'accountsByType', {})
746
+ fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
747
+ toId = self.safe_string(accountsByType, toAccount, toAccount)
748
+ currency = self.currency(code)
749
+ fromCurrencyId = self.convert_derivatives_id(currency['id'], fromAccount)
750
+ toCurrencyId = self.convert_derivatives_id(currency['id'], toAccount)
751
+ requestedAmount = self.currency_to_precision(code, amount)
752
+ request: dict = {
753
+ 'amount': requestedAmount,
754
+ 'currency': fromCurrencyId,
755
+ 'currency_to': toCurrencyId,
756
+ 'walletfrom': fromId,
757
+ 'walletto': toId,
758
+ }
759
+ response = await self.privatePostTransfer(self.extend(request, params))
760
+ #
761
+ # [
762
+ # {
763
+ # "status": "success",
764
+ # "message": "0.0001 Bitcoin transfered from Margin to Exchange"
765
+ # }
766
+ # ]
767
+ #
768
+ result = self.safe_value(response, 0)
769
+ message = self.safe_string(result, 'message')
770
+ if message is None:
771
+ raise ExchangeError(self.id + ' transfer failed')
772
+ return self.extend(self.parse_transfer(result, currency), {
773
+ 'fromAccount': fromAccount,
774
+ 'toAccount': toAccount,
775
+ 'amount': self.parse_number(requestedAmount),
776
+ })
777
+
778
+ def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
779
+ #
780
+ # {
781
+ # "status": "success",
782
+ # "message": "0.0001 Bitcoin transfered from Margin to Exchange"
783
+ # }
784
+ #
785
+ return {
786
+ 'info': transfer,
787
+ 'id': None,
788
+ 'timestamp': None,
789
+ 'datetime': None,
790
+ 'currency': self.safe_currency_code(None, currency),
791
+ 'amount': None,
792
+ 'fromAccount': None,
793
+ 'toAccount': None,
794
+ 'status': self.parse_transfer_status(self.safe_string(transfer, 'status')),
795
+ }
796
+
797
+ def parse_transfer_status(self, status: Str) -> Str:
798
+ statuses: dict = {
799
+ 'SUCCESS': 'ok',
800
+ }
801
+ return self.safe_string(statuses, status, status)
802
+
803
+ def convert_derivatives_id(self, currencyId, type):
804
+ start = len(currencyId) - 2
805
+ isDerivativeCode = currencyId[start:] == 'F0'
806
+ if (type != 'derivatives' and type != 'trading' and type != 'margin') and isDerivativeCode:
807
+ currencyId = currencyId[0:start]
808
+ elif type == 'derivatives' and not isDerivativeCode:
809
+ currencyId = currencyId + 'F0'
810
+ return currencyId
811
+
812
+ async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
813
+ """
814
+ fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
815
+ :see: https://docs.bitfinex.com/v1/reference/rest-public-orderbook
816
+ :param str symbol: unified symbol of the market to fetch the order book for
817
+ :param int [limit]: the maximum amount of order book entries to return
818
+ :param dict [params]: extra parameters specific to the exchange API endpoint
819
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
820
+ """
821
+ await self.load_markets()
822
+ market = self.market(symbol)
823
+ request: dict = {
824
+ 'symbol': market['id'],
825
+ }
826
+ if limit is not None:
827
+ request['limit_bids'] = limit
828
+ request['limit_asks'] = limit
829
+ response = await self.publicGetBookSymbol(self.extend(request, params))
830
+ return self.parse_order_book(response, market['symbol'], None, 'bids', 'asks', 'price', 'amount')
831
+
832
+ async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
833
+ """
834
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
835
+ :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
836
+ :param dict [params]: extra parameters specific to the exchange API endpoint
837
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
838
+ """
839
+ await self.load_markets()
840
+ symbols = self.market_symbols(symbols)
841
+ response = await self.publicGetTickers(params)
842
+ result: dict = {}
843
+ for i in range(0, len(response)):
844
+ ticker = self.parse_ticker({'result': response[i]})
845
+ symbol = ticker['symbol']
846
+ result[symbol] = ticker
847
+ return self.filter_by_array_tickers(result, 'symbol', symbols)
848
+
849
+ async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
850
+ """
851
+ fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
852
+ :see: https://docs.bitfinex.com/v1/reference/rest-public-ticker
853
+ :param str symbol: unified symbol of the market to fetch the ticker for
854
+ :param dict [params]: extra parameters specific to the exchange API endpoint
855
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
856
+ """
857
+ await self.load_markets()
858
+ market = self.market(symbol)
859
+ request: dict = {
860
+ 'symbol': market['id'],
861
+ }
862
+ ticker = await self.publicGetPubtickerSymbol(self.extend(request, params))
863
+ #
864
+ # {
865
+ # mid: '63560.5',
866
+ # bid: '63560.0',
867
+ # ask: '63561.0',
868
+ # last_price: '63547.0',
869
+ # low: '62812.0',
870
+ # high: '64480.0',
871
+ # volume: '517.25634977',
872
+ # timestamp: '1715102384.9849467'
873
+ # }
874
+ #
875
+ return self.parse_ticker(ticker, market)
876
+
877
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
878
+ #
879
+ # {
880
+ # mid: '63560.5',
881
+ # bid: '63560.0',
882
+ # ask: '63561.0',
883
+ # last_price: '63547.0',
884
+ # low: '62812.0',
885
+ # high: '64480.0',
886
+ # volume: '517.25634977',
887
+ # timestamp: '1715102384.9849467'
888
+ # }
889
+ #
890
+ timestamp = self.safe_timestamp(ticker, 'timestamp')
891
+ marketId = self.safe_string(ticker, 'pair')
892
+ market = self.safe_market(marketId, market)
893
+ symbol = market['symbol']
894
+ last = self.safe_string(ticker, 'last_price')
895
+ return self.safe_ticker({
896
+ 'symbol': symbol,
897
+ 'timestamp': timestamp,
898
+ 'datetime': self.iso8601(timestamp),
899
+ 'high': self.safe_string(ticker, 'high'),
900
+ 'low': self.safe_string(ticker, 'low'),
901
+ 'bid': self.safe_string(ticker, 'bid'),
902
+ 'bidVolume': None,
903
+ 'ask': self.safe_string(ticker, 'ask'),
904
+ 'askVolume': None,
905
+ 'vwap': None,
906
+ 'open': None,
907
+ 'close': last,
908
+ 'last': last,
909
+ 'previousClose': None,
910
+ 'change': None,
911
+ 'percentage': None,
912
+ 'average': self.safe_string(ticker, 'mid'),
913
+ 'baseVolume': self.safe_string(ticker, 'volume'),
914
+ 'quoteVolume': None,
915
+ 'info': ticker,
916
+ }, market)
917
+
918
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
919
+ #
920
+ # fetchTrades(public) v1
921
+ #
922
+ # {
923
+ # "timestamp":1637258380,
924
+ # "tid":894452833,
925
+ # "price":"0.99941",
926
+ # "amount":"261.38",
927
+ # "exchange":"bitfinex",
928
+ # "type":"sell"
929
+ # }
930
+ #
931
+ # fetchMyTrades(private) v1
932
+ #
933
+ # {
934
+ # "price":"0.99941",
935
+ # "amount":"261.38",
936
+ # "timestamp":"1637258380.0",
937
+ # "type":"Sell",
938
+ # "fee_currency":"UST",
939
+ # "fee_amount":"-0.52245157",
940
+ # "tid":894452833,
941
+ # "order_id":78819731373
942
+ # }
943
+ #
944
+ # {
945
+ # "price":"0.99958",
946
+ # "amount":"261.90514",
947
+ # "timestamp":"1637258238.0",
948
+ # "type":"Buy",
949
+ # "fee_currency":"UDC",
950
+ # "fee_amount":"-0.52381028",
951
+ # "tid":894452800,
952
+ # "order_id":78819504838
953
+ # }
954
+ #
955
+ id = self.safe_string(trade, 'tid')
956
+ timestamp = self.safe_timestamp(trade, 'timestamp')
957
+ type = None
958
+ side = self.safe_string_lower(trade, 'type')
959
+ orderId = self.safe_string(trade, 'order_id')
960
+ priceString = self.safe_string(trade, 'price')
961
+ amountString = self.safe_string(trade, 'amount')
962
+ fee = None
963
+ if 'fee_amount' in trade:
964
+ feeCostString = Precise.string_neg(self.safe_string(trade, 'fee_amount'))
965
+ feeCurrencyId = self.safe_string(trade, 'fee_currency')
966
+ feeCurrencyCode = self.safe_currency_code(feeCurrencyId)
967
+ fee = {
968
+ 'cost': feeCostString,
969
+ 'currency': feeCurrencyCode,
970
+ }
971
+ return self.safe_trade({
972
+ 'id': id,
973
+ 'info': trade,
974
+ 'timestamp': timestamp,
975
+ 'datetime': self.iso8601(timestamp),
976
+ 'symbol': market['symbol'],
977
+ 'type': type,
978
+ 'order': orderId,
979
+ 'side': side,
980
+ 'takerOrMaker': None,
981
+ 'price': priceString,
982
+ 'amount': amountString,
983
+ 'cost': None,
984
+ 'fee': fee,
985
+ }, market)
986
+
987
+ async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = 50, params={}) -> List[Trade]:
988
+ """
989
+ get the list of most recent trades for a particular symbol
990
+ :see: https://docs.bitfinex.com/v1/reference/rest-public-trades
991
+ :param str symbol: unified symbol of the market to fetch trades for
992
+ :param int [since]: timestamp in ms of the earliest trade to fetch
993
+ :param int [limit]: the maximum amount of trades to fetch
994
+ :param dict [params]: extra parameters specific to the exchange API endpoint
995
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
996
+ """
997
+ await self.load_markets()
998
+ market = self.market(symbol)
999
+ request: dict = {
1000
+ 'symbol': market['id'],
1001
+ 'limit_trades': limit,
1002
+ }
1003
+ if since is not None:
1004
+ request['timestamp'] = self.parse_to_int(since / 1000)
1005
+ response = await self.publicGetTradesSymbol(self.extend(request, params))
1006
+ #
1007
+ # [
1008
+ # {
1009
+ # "timestamp": "1694284565",
1010
+ # "tid": "1415415034",
1011
+ # "price": "25862.0",
1012
+ # "amount": "0.00020685",
1013
+ # "exchange": "bitfinex",
1014
+ # "type": "buy"
1015
+ # },
1016
+ # ]
1017
+ #
1018
+ return self.parse_trades(response, market, since, limit)
1019
+
1020
+ async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1021
+ """
1022
+ fetch all trades made by the user
1023
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-past-trades
1024
+ :param str symbol: unified market symbol
1025
+ :param int [since]: the earliest time in ms to fetch trades for
1026
+ :param int [limit]: the maximum number of trades structures to retrieve
1027
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1028
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1029
+ """
1030
+ if symbol is None:
1031
+ raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol argument')
1032
+ await self.load_markets()
1033
+ market = self.market(symbol)
1034
+ request: dict = {
1035
+ 'symbol': market['id'],
1036
+ }
1037
+ if limit is not None:
1038
+ request['limit_trades'] = limit
1039
+ if since is not None:
1040
+ request['timestamp'] = self.parse_to_int(since / 1000)
1041
+ response = await self.privatePostMytrades(self.extend(request, params))
1042
+ return self.parse_trades(response, market, since, limit)
1043
+
1044
+ async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1045
+ """
1046
+ create a trade order
1047
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-new-order
1048
+ :param str symbol: unified symbol of the market to create an order in
1049
+ :param str type: 'market' or 'limit'
1050
+ :param str side: 'buy' or 'sell'
1051
+ :param float amount: how much of currency you want to trade in units of base currency
1052
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1053
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1054
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1055
+ """
1056
+ await self.load_markets()
1057
+ market = self.market(symbol)
1058
+ postOnly = self.safe_bool(params, 'postOnly', False)
1059
+ type = type.lower()
1060
+ params = self.omit(params, ['postOnly'])
1061
+ if market['spot']:
1062
+ # although they claim that type needs to be 'exchange limit' or 'exchange market'
1063
+ # in fact that's not the case for swap markets
1064
+ type = self.safe_string_lower(self.options['orderTypes'], type, type)
1065
+ request: dict = {
1066
+ 'symbol': market['id'],
1067
+ 'side': side,
1068
+ 'amount': self.amount_to_precision(symbol, amount),
1069
+ 'type': type,
1070
+ 'ocoorder': False,
1071
+ 'buy_price_oco': 0,
1072
+ 'sell_price_oco': 0,
1073
+ }
1074
+ if type.find('market') > -1:
1075
+ request['price'] = str(self.nonce())
1076
+ else:
1077
+ request['price'] = self.price_to_precision(symbol, price)
1078
+ if postOnly:
1079
+ request['is_postonly'] = True
1080
+ response = await self.privatePostOrderNew(self.extend(request, params))
1081
+ return self.parse_order(response, market)
1082
+
1083
+ async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
1084
+ await self.load_markets()
1085
+ order: dict = {
1086
+ 'order_id': int(id),
1087
+ }
1088
+ if price is not None:
1089
+ order['price'] = self.price_to_precision(symbol, price)
1090
+ if amount is not None:
1091
+ order['amount'] = self.number_to_string(amount)
1092
+ if symbol is not None:
1093
+ order['symbol'] = self.market_id(symbol)
1094
+ if side is not None:
1095
+ order['side'] = side
1096
+ if type is not None:
1097
+ order['type'] = self.safe_string(self.options['orderTypes'], type, type)
1098
+ response = await self.privatePostOrderCancelReplace(self.extend(order, params))
1099
+ return self.parse_order(response)
1100
+
1101
+ async def cancel_order(self, id: str, symbol: Str = None, params={}):
1102
+ """
1103
+ cancels an open order
1104
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-cancel-order
1105
+ :param str id: order id
1106
+ :param str symbol: not used by bitfinex cancelOrder()
1107
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1108
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1109
+ """
1110
+ await self.load_markets()
1111
+ request: dict = {
1112
+ 'order_id': int(id),
1113
+ }
1114
+ return await self.privatePostOrderCancel(self.extend(request, params))
1115
+
1116
+ async def cancel_all_orders(self, symbol: Str = None, params={}):
1117
+ """
1118
+ cancel all open orders
1119
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-cancel-all-orders
1120
+ :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
1121
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1122
+ :returns dict: response from exchange
1123
+ """
1124
+ return await self.privatePostOrderCancelAll(params)
1125
+
1126
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1127
+ #
1128
+ # {
1129
+ # "id": 57334010955,
1130
+ # "cid": 1611584840966,
1131
+ # "cid_date": null,
1132
+ # "gid": null,
1133
+ # "symbol": "ltcbtc",
1134
+ # "exchange": null,
1135
+ # "price": "0.0042125",
1136
+ # "avg_execution_price": "0.0042097",
1137
+ # "side": "sell",
1138
+ # "type": "exchange market",
1139
+ # "timestamp": "1611584841.0",
1140
+ # "is_live": False,
1141
+ # "is_cancelled": False,
1142
+ # "is_hidden": 0,
1143
+ # "oco_order": 0,
1144
+ # "was_forced": False,
1145
+ # "original_amount": "0.205176",
1146
+ # "remaining_amount": "0.0",
1147
+ # "executed_amount": "0.205176",
1148
+ # "src": "web"
1149
+ # }
1150
+ #
1151
+ side = self.safe_string(order, 'side')
1152
+ open = self.safe_value(order, 'is_live')
1153
+ canceled = self.safe_value(order, 'is_cancelled')
1154
+ status = None
1155
+ if open:
1156
+ status = 'open'
1157
+ elif canceled:
1158
+ status = 'canceled'
1159
+ else:
1160
+ status = 'closed'
1161
+ marketId = self.safe_string_upper(order, 'symbol')
1162
+ symbol = self.safe_symbol(marketId, market)
1163
+ orderType = self.safe_string(order, 'type', '')
1164
+ exchange = orderType.find('exchange ') >= 0
1165
+ if exchange:
1166
+ parts = order['type'].split(' ')
1167
+ orderType = parts[1]
1168
+ timestamp = self.safe_timestamp(order, 'timestamp')
1169
+ id = self.safe_string(order, 'id')
1170
+ return self.safe_order({
1171
+ 'info': order,
1172
+ 'id': id,
1173
+ 'clientOrderId': None,
1174
+ 'timestamp': timestamp,
1175
+ 'datetime': self.iso8601(timestamp),
1176
+ 'lastTradeTimestamp': None,
1177
+ 'symbol': symbol,
1178
+ 'type': orderType,
1179
+ 'timeInForce': None,
1180
+ 'postOnly': None,
1181
+ 'side': side,
1182
+ 'price': self.safe_string(order, 'price'),
1183
+ 'stopPrice': None,
1184
+ 'triggerPrice': None,
1185
+ 'average': self.safe_string(order, 'avg_execution_price'),
1186
+ 'amount': self.safe_string(order, 'original_amount'),
1187
+ 'remaining': self.safe_string(order, 'remaining_amount'),
1188
+ 'filled': self.safe_string(order, 'executed_amount'),
1189
+ 'status': status,
1190
+ 'fee': None,
1191
+ 'cost': None,
1192
+ 'trades': None,
1193
+ }, market)
1194
+
1195
+ async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1196
+ """
1197
+ fetch all unfilled currently open orders
1198
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-active-orders
1199
+ :param str symbol: unified market symbol
1200
+ :param int [since]: the earliest time in ms to fetch open orders for
1201
+ :param int [limit]: the maximum number of open orders structures to retrieve
1202
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1203
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1204
+ """
1205
+ await self.load_markets()
1206
+ if symbol is not None:
1207
+ if not (symbol in self.markets):
1208
+ raise ExchangeError(self.id + ' has no symbol ' + symbol)
1209
+ response = await self.privatePostOrders(params)
1210
+ orders = self.parse_orders(response, None, since, limit)
1211
+ if symbol is not None:
1212
+ orders = self.filter_by(orders, 'symbol', symbol)
1213
+ return orders
1214
+
1215
+ async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1216
+ """
1217
+ fetches information on multiple closed orders made by the user
1218
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-orders-history
1219
+ :param str symbol: unified market symbol of the market orders were made in
1220
+ :param int [since]: the earliest time in ms to fetch orders for
1221
+ :param int [limit]: the maximum number of order structures to retrieve
1222
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1223
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1224
+ """
1225
+ await self.load_markets()
1226
+ symbol = self.symbol(symbol)
1227
+ request: dict = {}
1228
+ if limit is not None:
1229
+ request['limit'] = limit
1230
+ response = await self.privatePostOrdersHist(self.extend(request, params))
1231
+ orders = self.parse_orders(response, None, since, limit)
1232
+ if symbol is not None:
1233
+ orders = self.filter_by(orders, 'symbol', symbol)
1234
+ orders = self.filter_by_array(orders, 'status', ['closed', 'canceled'], False)
1235
+ return orders
1236
+
1237
+ async def fetch_order(self, id: str, symbol: Str = None, params={}):
1238
+ """
1239
+ fetches information on an order made by the user
1240
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-order-status
1241
+ :param str symbol: not used by bitfinex fetchOrder
1242
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1243
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1244
+ """
1245
+ await self.load_markets()
1246
+ request: dict = {
1247
+ 'order_id': int(id),
1248
+ }
1249
+ response = await self.privatePostOrderStatus(self.extend(request, params))
1250
+ return self.parse_order(response)
1251
+
1252
+ def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
1253
+ #
1254
+ # [
1255
+ # 1457539800000,
1256
+ # 0.02594,
1257
+ # 0.02594,
1258
+ # 0.02594,
1259
+ # 0.02594,
1260
+ # 0.1
1261
+ # ]
1262
+ #
1263
+ return [
1264
+ self.safe_integer(ohlcv, 0),
1265
+ self.safe_number(ohlcv, 1),
1266
+ self.safe_number(ohlcv, 3),
1267
+ self.safe_number(ohlcv, 4),
1268
+ self.safe_number(ohlcv, 2),
1269
+ self.safe_number(ohlcv, 5),
1270
+ ]
1271
+
1272
+ async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
1273
+ """
1274
+ fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1275
+ :see: https://docs.bitfinex.com/reference/rest-public-candles#aggregate-funding-currency-candles
1276
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
1277
+ :param str timeframe: the length of time each candle represents
1278
+ :param int [since]: timestamp in ms of the earliest candle to fetch
1279
+ :param int [limit]: the maximum amount of candles to fetch
1280
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1281
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
1282
+ """
1283
+ await self.load_markets()
1284
+ if limit is None:
1285
+ limit = 100
1286
+ else:
1287
+ limit = min(limit, 10000)
1288
+ market = self.market(symbol)
1289
+ v2id = 't' + market['id']
1290
+ request: dict = {
1291
+ 'symbol': v2id,
1292
+ 'timeframe': self.safe_string(self.timeframes, timeframe, timeframe),
1293
+ 'sort': 1,
1294
+ 'limit': limit,
1295
+ }
1296
+ if since is not None:
1297
+ request['start'] = since
1298
+ response = await self.v2GetCandlesTradeTimeframeSymbolHist(self.extend(request, params))
1299
+ #
1300
+ # [
1301
+ # [1457539800000,0.02594,0.02594,0.02594,0.02594,0.1],
1302
+ # [1457547300000,0.02577,0.02577,0.02577,0.02577,0.01],
1303
+ # [1457550240000,0.0255,0.0253,0.0255,0.0252,3.2640000000000002],
1304
+ # ]
1305
+ #
1306
+ return self.parse_ohlcvs(response, market, timeframe, since, limit)
1307
+
1308
+ def get_currency_name(self, code):
1309
+ # todo rewrite for https://api-pub.bitfinex.com//v2/conf/pub:map:tx:method
1310
+ if code in self.options['currencyNames']:
1311
+ return self.options['currencyNames'][code]
1312
+ raise NotSupported(self.id + ' ' + code + ' not supported for withdrawal')
1313
+
1314
+ async def create_deposit_address(self, code: str, params={}):
1315
+ """
1316
+ create a currency deposit address
1317
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-deposit
1318
+ :param str code: unified currency code of the currency for the deposit address
1319
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1320
+ :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
1321
+ """
1322
+ await self.load_markets()
1323
+ request: dict = {
1324
+ 'renew': 1,
1325
+ }
1326
+ return await self.fetch_deposit_address(code, self.extend(request, params))
1327
+
1328
+ async def fetch_deposit_address(self, code: str, params={}):
1329
+ """
1330
+ fetch the deposit address for a currency associated with self account
1331
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-deposit
1332
+ :param str code: unified currency code
1333
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1334
+ :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
1335
+ """
1336
+ await self.load_markets()
1337
+ # todo rewrite for https://api-pub.bitfinex.com//v2/conf/pub:map:tx:method
1338
+ name = self.get_currency_name(code)
1339
+ request: dict = {
1340
+ 'method': name,
1341
+ 'wallet_name': 'exchange',
1342
+ 'renew': 0, # a value of 1 will generate a new address
1343
+ }
1344
+ response = await self.privatePostDepositNew(self.extend(request, params))
1345
+ address = self.safe_value(response, 'address')
1346
+ tag = None
1347
+ if 'address_pool' in response:
1348
+ tag = address
1349
+ address = response['address_pool']
1350
+ self.check_address(address)
1351
+ return {
1352
+ 'currency': code,
1353
+ 'address': address,
1354
+ 'tag': tag,
1355
+ 'network': None,
1356
+ 'info': response,
1357
+ }
1358
+
1359
+ async def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1360
+ """
1361
+ fetch history of deposits and withdrawals
1362
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-deposit-withdrawal-history
1363
+ :param str code: unified currency code for the currency of the deposit/withdrawals
1364
+ :param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
1365
+ :param int [limit]: max number of deposit/withdrawals to return, default is None
1366
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1367
+ :returns dict: a list of `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1368
+ """
1369
+ await self.load_markets()
1370
+ currencyId = self.safe_string(params, 'currency')
1371
+ query = self.omit(params, 'currency')
1372
+ currency = None
1373
+ if currencyId is None:
1374
+ if code is None:
1375
+ raise ArgumentsRequired(self.id + ' fetchDepositsWithdrawals() requires a currency `code` argument or a `currency` parameter')
1376
+ else:
1377
+ currency = self.currency(code)
1378
+ currencyId = currency['id']
1379
+ query['currency'] = currencyId
1380
+ if since is not None:
1381
+ query['since'] = self.parse_to_int(since / 1000)
1382
+ response = await self.privatePostHistoryMovements(self.extend(query, params))
1383
+ #
1384
+ # [
1385
+ # {
1386
+ # "id": 581183,
1387
+ # "txid": 123456,
1388
+ # "currency": "BTC",
1389
+ # "method": "BITCOIN",
1390
+ # "type": "WITHDRAWAL",
1391
+ # "amount": ".01",
1392
+ # "description": "3QXYWgRGX2BPYBpUDBssGbeWEa5zq6snBZ, offchain transfer ",
1393
+ # "address": "3QXYWgRGX2BPYBpUDBssGbeWEa5zq6snBZ",
1394
+ # "status": "COMPLETED",
1395
+ # "timestamp": "1443833327.0",
1396
+ # "timestamp_created": "1443833327.1",
1397
+ # "fee": 0.1,
1398
+ # }
1399
+ # ]
1400
+ #
1401
+ return self.parse_transactions(response, currency, since, limit)
1402
+
1403
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
1404
+ #
1405
+ # crypto
1406
+ #
1407
+ # {
1408
+ # "id": 12042490,
1409
+ # "fee": "-0.02",
1410
+ # "txid": "EA5B5A66000B66855865EFF2494D7C8D1921FCBE996482157EBD749F2C85E13D",
1411
+ # "type": "DEPOSIT",
1412
+ # "amount": "2099.849999",
1413
+ # "method": "RIPPLE",
1414
+ # "status": "COMPLETED",
1415
+ # "address": "2505189261",
1416
+ # "currency": "XRP",
1417
+ # "timestamp": "1551730524.0",
1418
+ # "description": "EA5B5A66000B66855865EFF2494D7C8D1921FCBE996482157EBD749F2C85E13D",
1419
+ # "timestamp_created": "1551730523.0"
1420
+ # }
1421
+ #
1422
+ # fiat
1423
+ #
1424
+ # {
1425
+ # "id": 12725095,
1426
+ # "fee": "-60.0",
1427
+ # "txid": null,
1428
+ # "type": "WITHDRAWAL",
1429
+ # "amount": "9943.0",
1430
+ # "method": "WIRE",
1431
+ # "status": "SENDING",
1432
+ # "address": null,
1433
+ # "currency": "EUR",
1434
+ # "timestamp": "1561802484.0",
1435
+ # "description": "Name: bob, AccountAddress: some address, Account: someaccountno, Bank: bank address, SWIFT: foo, Country: UK, Details of Payment: withdrawal name, Intermediary Bank Name: , Intermediary Bank Address: , Intermediary Bank City: , Intermediary Bank Country: , Intermediary Bank Account: , Intermediary Bank SWIFT: , Fee: -60.0",
1436
+ # "timestamp_created": "1561716066.0"
1437
+ # }
1438
+ #
1439
+ # withdraw
1440
+ #
1441
+ # {
1442
+ # "status": "success",
1443
+ # "message": "Your withdrawal request has been successfully submitted.",
1444
+ # "withdrawal_id": 586829
1445
+ # }
1446
+ #
1447
+ timestamp = self.safe_timestamp(transaction, 'timestamp_created')
1448
+ currencyId = self.safe_string(transaction, 'currency')
1449
+ code = self.safe_currency_code(currencyId, currency)
1450
+ feeCost = self.safe_string(transaction, 'fee')
1451
+ if feeCost is not None:
1452
+ feeCost = Precise.string_abs(feeCost)
1453
+ return {
1454
+ 'info': transaction,
1455
+ 'id': self.safe_string_2(transaction, 'id', 'withdrawal_id'),
1456
+ 'txid': self.safe_string(transaction, 'txid'),
1457
+ 'type': self.safe_string_lower(transaction, 'type'), # DEPOSIT or WITHDRAWAL,
1458
+ 'currency': code,
1459
+ 'network': None,
1460
+ 'amount': self.safe_number(transaction, 'amount'),
1461
+ 'status': self.parse_transaction_status(self.safe_string(transaction, 'status')),
1462
+ 'timestamp': timestamp,
1463
+ 'datetime': self.iso8601(timestamp),
1464
+ 'address': self.safe_string(transaction, 'address'), # todo: self is actually the tag for XRP transfers(the address is missing)
1465
+ 'addressFrom': None,
1466
+ 'addressTo': None,
1467
+ 'tag': self.safe_string(transaction, 'description'),
1468
+ 'tagFrom': None,
1469
+ 'tagTo': None,
1470
+ 'updated': self.safe_timestamp(transaction, 'timestamp'),
1471
+ 'comment': None,
1472
+ 'internal': None,
1473
+ 'fee': {
1474
+ 'currency': code,
1475
+ 'cost': self.parse_number(feeCost),
1476
+ 'rate': None,
1477
+ },
1478
+ }
1479
+
1480
+ def parse_transaction_status(self, status: Str):
1481
+ statuses: dict = {
1482
+ 'SENDING': 'pending',
1483
+ 'CANCELED': 'canceled',
1484
+ 'ZEROCONFIRMED': 'failed', # ZEROCONFIRMED happens e.g. in a double spend attempt(I had one in my movementsnot )
1485
+ 'COMPLETED': 'ok',
1486
+ }
1487
+ return self.safe_string(statuses, status, status)
1488
+
1489
+ async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
1490
+ """
1491
+ make a withdrawal
1492
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-withdrawal
1493
+ :param str code: unified currency code
1494
+ :param float amount: the amount to withdraw
1495
+ :param str address: the address to withdraw to
1496
+ :param str tag:
1497
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1498
+ :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1499
+ """
1500
+ tag, params = self.handle_withdraw_tag_and_params(tag, params)
1501
+ self.check_address(address)
1502
+ await self.load_markets()
1503
+ # todo rewrite for https://api-pub.bitfinex.com//v2/conf/pub:map:tx:method
1504
+ name = self.get_currency_name(code)
1505
+ currency = self.currency(code)
1506
+ request: dict = {
1507
+ 'withdraw_type': name,
1508
+ 'walletselected': 'exchange',
1509
+ 'amount': self.number_to_string(amount),
1510
+ 'address': address,
1511
+ }
1512
+ if tag is not None:
1513
+ request['payment_id'] = tag
1514
+ responses = await self.privatePostWithdraw(self.extend(request, params))
1515
+ #
1516
+ # [
1517
+ # {
1518
+ # "status":"success",
1519
+ # "message":"Your withdrawal request has been successfully submitted.",
1520
+ # "withdrawal_id":586829
1521
+ # }
1522
+ # ]
1523
+ #
1524
+ response = self.safe_value(responses, 0, {})
1525
+ id = self.safe_number(response, 'withdrawal_id')
1526
+ message = self.safe_string(response, 'message')
1527
+ errorMessage = self.find_broadly_matched_key(self.exceptions['broad'], message)
1528
+ if id == 0:
1529
+ if errorMessage is not None:
1530
+ ExceptionClass = self.exceptions['broad'][errorMessage]
1531
+ raise ExceptionClass(self.id + ' ' + message)
1532
+ raise ExchangeError(self.id + ' withdraw returned an id of zero: ' + self.json(response))
1533
+ return self.parse_transaction(response, currency)
1534
+
1535
+ async def fetch_positions(self, symbols: Strings = None, params={}):
1536
+ """
1537
+ fetch all open positions
1538
+ :see: https://docs.bitfinex.com/v1/reference/rest-auth-active-positions
1539
+ :param str[]|None symbols: list of unified market symbols
1540
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1541
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
1542
+ """
1543
+ await self.load_markets()
1544
+ response = await self.privatePostPositions(params)
1545
+ #
1546
+ # [
1547
+ # {
1548
+ # "id":943715,
1549
+ # "symbol":"btcusd",
1550
+ # "status":"ACTIVE",
1551
+ # "base":"246.94",
1552
+ # "amount":"1.0",
1553
+ # "timestamp":"1444141857.0",
1554
+ # "swap":"0.0",
1555
+ # "pl":"-2.22042"
1556
+ # }
1557
+ # ]
1558
+ #
1559
+ # todo unify parsePosition/parsePositions
1560
+ return response
1561
+
1562
+ def nonce(self):
1563
+ return self.milliseconds()
1564
+
1565
+ def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
1566
+ request = '/' + self.implode_params(path, params)
1567
+ if api == 'v2':
1568
+ request = '/' + api + request
1569
+ else:
1570
+ request = '/' + self.version + request
1571
+ query = self.omit(params, self.extract_params(path))
1572
+ url = self.urls['api'][api] + request
1573
+ if (api == 'public') or (path.find('/hist') >= 0):
1574
+ if query:
1575
+ suffix = '?' + self.urlencode(query)
1576
+ url += suffix
1577
+ request += suffix
1578
+ if api == 'private':
1579
+ self.check_required_credentials()
1580
+ nonce = self.nonce()
1581
+ query = self.extend({
1582
+ 'nonce': str(nonce),
1583
+ 'request': request,
1584
+ }, query)
1585
+ body = self.json(query)
1586
+ payload = self.string_to_base64(body)
1587
+ secret = self.encode(self.secret)
1588
+ signature = self.hmac(self.encode(payload), secret, hashlib.sha384)
1589
+ headers = {
1590
+ 'X-BFX-APIKEY': self.apiKey,
1591
+ 'X-BFX-PAYLOAD': payload,
1592
+ 'X-BFX-SIGNATURE': signature,
1593
+ 'Content-Type': 'application/json',
1594
+ }
1595
+ return {'url': url, 'method': method, 'body': body, 'headers': headers}
1596
+
1597
+ def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
1598
+ if response is None:
1599
+ return None
1600
+ throwError = False
1601
+ if code >= 400:
1602
+ if body[0] == '{':
1603
+ throwError = True
1604
+ else:
1605
+ # json response with error, i.e:
1606
+ # [{"status":"error","message":"Momentary balance check. Please wait few seconds and try the transfer again."}]
1607
+ responseObject = self.safe_value(response, 0, {})
1608
+ status = self.safe_string(responseObject, 'status', '')
1609
+ if status == 'error':
1610
+ throwError = True
1611
+ if throwError:
1612
+ feedback = self.id + ' ' + body
1613
+ message = self.safe_string_2(response, 'message', 'error')
1614
+ self.throw_exactly_matched_exception(self.exceptions['exact'], message, feedback)
1615
+ self.throw_broadly_matched_exception(self.exceptions['broad'], message, feedback)
1616
+ raise ExchangeError(feedback) # unknown message
1617
+ return None