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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (772) hide show
  1. ccxt/__init__.py +358 -0
  2. ccxt/abantether.py +316 -0
  3. ccxt/abstract/__init__.py +0 -0
  4. ccxt/abstract/abantether.py +5 -0
  5. ccxt/abstract/ace.py +15 -0
  6. ccxt/abstract/afratether.py +6 -0
  7. ccxt/abstract/alpaca.py +70 -0
  8. ccxt/abstract/arzinja.py +5 -0
  9. ccxt/abstract/arzplus.py +7 -0
  10. ccxt/abstract/ascendex.py +77 -0
  11. ccxt/abstract/bequant.py +115 -0
  12. ccxt/abstract/bigone.py +45 -0
  13. ccxt/abstract/binance.py +712 -0
  14. ccxt/abstract/binancecoinm.py +712 -0
  15. ccxt/abstract/binanceus.py +764 -0
  16. ccxt/abstract/binanceusdm.py +712 -0
  17. ccxt/abstract/bingx.py +113 -0
  18. ccxt/abstract/bit2c.py +27 -0
  19. ccxt/abstract/bitbank.py +27 -0
  20. ccxt/abstract/bitbay.py +53 -0
  21. ccxt/abstract/bitbns.py +40 -0
  22. ccxt/abstract/bitcoincom.py +115 -0
  23. ccxt/abstract/bitfinex.py +69 -0
  24. ccxt/abstract/bitfinex2.py +139 -0
  25. ccxt/abstract/bitflyer.py +38 -0
  26. ccxt/abstract/bitget.py +508 -0
  27. ccxt/abstract/bithumb.py +32 -0
  28. ccxt/abstract/bitimen.py +7 -0
  29. ccxt/abstract/bitir.py +7 -0
  30. ccxt/abstract/bitmart.py +99 -0
  31. ccxt/abstract/bitmex.py +97 -0
  32. ccxt/abstract/bitopro.py +29 -0
  33. ccxt/abstract/bitpanda.py +35 -0
  34. ccxt/abstract/bitpin.py +7 -0
  35. ccxt/abstract/bitrue.py +72 -0
  36. ccxt/abstract/bitso.py +43 -0
  37. ccxt/abstract/bitstamp.py +258 -0
  38. ccxt/abstract/bitteam.py +29 -0
  39. ccxt/abstract/bitvavo.py +27 -0
  40. ccxt/abstract/bl3p.py +19 -0
  41. ccxt/abstract/blockchaincom.py +28 -0
  42. ccxt/abstract/blofin.py +37 -0
  43. ccxt/abstract/btcalpha.py +18 -0
  44. ccxt/abstract/btcbox.py +13 -0
  45. ccxt/abstract/btcmarkets.py +39 -0
  46. ccxt/abstract/btcturk.py +20 -0
  47. ccxt/abstract/bybit.py +298 -0
  48. ccxt/abstract/cex.py +33 -0
  49. ccxt/abstract/coinbase.py +94 -0
  50. ccxt/abstract/coinbaseadvanced.py +94 -0
  51. ccxt/abstract/coinbaseexchange.py +67 -0
  52. ccxt/abstract/coinbaseinternational.py +39 -0
  53. ccxt/abstract/coincatch.py +94 -0
  54. ccxt/abstract/coincheck.py +33 -0
  55. ccxt/abstract/coinex.py +237 -0
  56. ccxt/abstract/coinlist.py +54 -0
  57. ccxt/abstract/coinmate.py +62 -0
  58. ccxt/abstract/coinmetro.py +34 -0
  59. ccxt/abstract/coinone.py +67 -0
  60. ccxt/abstract/coinsph.py +54 -0
  61. ccxt/abstract/coinspot.py +28 -0
  62. ccxt/abstract/cryptocom.py +107 -0
  63. ccxt/abstract/currencycom.py +68 -0
  64. ccxt/abstract/delta.py +50 -0
  65. ccxt/abstract/deribit.py +125 -0
  66. ccxt/abstract/digifinex.py +91 -0
  67. ccxt/abstract/eterex.py +5 -0
  68. ccxt/abstract/excoino.py +7 -0
  69. ccxt/abstract/exir.py +8 -0
  70. ccxt/abstract/exmo.py +55 -0
  71. ccxt/abstract/exnovin.py +6 -0
  72. ccxt/abstract/farhadexchange.py +5 -0
  73. ccxt/abstract/fmfwio.py +115 -0
  74. ccxt/abstract/gate.py +265 -0
  75. ccxt/abstract/gateio.py +265 -0
  76. ccxt/abstract/gemini.py +58 -0
  77. ccxt/abstract/hashkey.py +67 -0
  78. ccxt/abstract/hitbtc.py +115 -0
  79. ccxt/abstract/hitbtc3.py +115 -0
  80. ccxt/abstract/hitobit.py +8 -0
  81. ccxt/abstract/hollaex.py +33 -0
  82. ccxt/abstract/htx.py +548 -0
  83. ccxt/abstract/huobi.py +548 -0
  84. ccxt/abstract/huobijp.py +114 -0
  85. ccxt/abstract/hyperliquid.py +6 -0
  86. ccxt/abstract/idex.py +26 -0
  87. ccxt/abstract/independentreserve.py +37 -0
  88. ccxt/abstract/indodax.py +26 -0
  89. ccxt/abstract/jibitex.py +7 -0
  90. ccxt/abstract/kraken.py +57 -0
  91. ccxt/abstract/krakenfutures.py +38 -0
  92. ccxt/abstract/kucoin.py +214 -0
  93. ccxt/abstract/kucoinfutures.py +233 -0
  94. ccxt/abstract/kuna.py +182 -0
  95. ccxt/abstract/latoken.py +56 -0
  96. ccxt/abstract/lbank.py +61 -0
  97. ccxt/abstract/luno.py +37 -0
  98. ccxt/abstract/lykke.py +29 -0
  99. ccxt/abstract/mercado.py +25 -0
  100. ccxt/abstract/mexc.py +178 -0
  101. ccxt/abstract/ndax.py +97 -0
  102. ccxt/abstract/nobitex.py +7 -0
  103. ccxt/abstract/novadax.py +29 -0
  104. ccxt/abstract/oceanex.py +22 -0
  105. ccxt/abstract/okcoin.py +74 -0
  106. ccxt/abstract/okexchange.py +8 -0
  107. ccxt/abstract/okx.py +324 -0
  108. ccxt/abstract/ompfinex.py +7 -0
  109. ccxt/abstract/onetrading.py +35 -0
  110. ccxt/abstract/oxfun.py +34 -0
  111. ccxt/abstract/p2b.py +22 -0
  112. ccxt/abstract/paradex.py +40 -0
  113. ccxt/abstract/paymium.py +28 -0
  114. ccxt/abstract/phemex.py +115 -0
  115. ccxt/abstract/poloniex.py +69 -0
  116. ccxt/abstract/poloniexfutures.py +48 -0
  117. ccxt/abstract/probit.py +23 -0
  118. ccxt/abstract/ramzinex.py +7 -0
  119. ccxt/abstract/sarmayex.py +5 -0
  120. ccxt/abstract/sarrafex.py +7 -0
  121. ccxt/abstract/tabdeal.py +7 -0
  122. ccxt/abstract/tetherland.py +5 -0
  123. ccxt/abstract/timex.py +62 -0
  124. ccxt/abstract/tokocrypto.py +37 -0
  125. ccxt/abstract/tradeogre.py +16 -0
  126. ccxt/abstract/twox.py +5 -0
  127. ccxt/abstract/ubitex.py +7 -0
  128. ccxt/abstract/upbit.py +38 -0
  129. ccxt/abstract/vertex.py +19 -0
  130. ccxt/abstract/wallex.py +8 -0
  131. ccxt/abstract/wavesexchange.py +154 -0
  132. ccxt/abstract/wazirx.py +30 -0
  133. ccxt/abstract/whitebit.py +98 -0
  134. ccxt/abstract/woo.py +83 -0
  135. ccxt/abstract/woofipro.py +119 -0
  136. ccxt/abstract/xt.py +152 -0
  137. ccxt/abstract/yobit.py +16 -0
  138. ccxt/abstract/zaif.py +38 -0
  139. ccxt/abstract/zonda.py +53 -0
  140. ccxt/ace.py +1012 -0
  141. ccxt/afratether.py +293 -0
  142. ccxt/alpaca.py +1083 -0
  143. ccxt/arzinja.py +285 -0
  144. ccxt/arzplus.py +412 -0
  145. ccxt/ascendex.py +3330 -0
  146. ccxt/async_support/__init__.py +337 -0
  147. ccxt/async_support/abantether.py +316 -0
  148. ccxt/async_support/ace.py +1012 -0
  149. ccxt/async_support/afratether.py +293 -0
  150. ccxt/async_support/alpaca.py +1083 -0
  151. ccxt/async_support/arzinja.py +285 -0
  152. ccxt/async_support/arzplus.py +412 -0
  153. ccxt/async_support/ascendex.py +3330 -0
  154. ccxt/async_support/base/__init__.py +1 -0
  155. ccxt/async_support/base/exchange.py +1966 -0
  156. ccxt/async_support/base/throttler.py +50 -0
  157. ccxt/async_support/base/ws/__init__.py +38 -0
  158. ccxt/async_support/base/ws/aiohttp_client.py +125 -0
  159. ccxt/async_support/base/ws/cache.py +212 -0
  160. ccxt/async_support/base/ws/client.py +193 -0
  161. ccxt/async_support/base/ws/fast_client.py +96 -0
  162. ccxt/async_support/base/ws/functions.py +59 -0
  163. ccxt/async_support/base/ws/future.py +58 -0
  164. ccxt/async_support/base/ws/order_book.py +78 -0
  165. ccxt/async_support/base/ws/order_book_side.py +174 -0
  166. ccxt/async_support/bequant.py +33 -0
  167. ccxt/async_support/bigone.py +2113 -0
  168. ccxt/async_support/binance.py +12234 -0
  169. ccxt/async_support/binancecoinm.py +45 -0
  170. ccxt/async_support/binanceus.py +211 -0
  171. ccxt/async_support/binanceusdm.py +58 -0
  172. ccxt/async_support/bingx.py +4325 -0
  173. ccxt/async_support/bit2c.py +866 -0
  174. ccxt/async_support/bitbank.py +1001 -0
  175. ccxt/async_support/bitbay.py +17 -0
  176. ccxt/async_support/bitbns.py +1154 -0
  177. ccxt/async_support/bitcoincom.py +17 -0
  178. ccxt/async_support/bitfinex.py +1617 -0
  179. ccxt/async_support/bitfinex2.py +3552 -0
  180. ccxt/async_support/bitflyer.py +995 -0
  181. ccxt/async_support/bitget.py +8273 -0
  182. ccxt/async_support/bithumb.py +1061 -0
  183. ccxt/async_support/bitimen.py +401 -0
  184. ccxt/async_support/bitir.py +490 -0
  185. ccxt/async_support/bitmart.py +4415 -0
  186. ccxt/async_support/bitmex.py +2756 -0
  187. ccxt/async_support/bitopro.py +1630 -0
  188. ccxt/async_support/bitpanda.py +16 -0
  189. ccxt/async_support/bitpin.py +454 -0
  190. ccxt/async_support/bitrue.py +3027 -0
  191. ccxt/async_support/bitso.py +1670 -0
  192. ccxt/async_support/bitstamp.py +2203 -0
  193. ccxt/async_support/bitteam.py +2239 -0
  194. ccxt/async_support/bitvavo.py +1968 -0
  195. ccxt/async_support/bl3p.py +485 -0
  196. ccxt/async_support/blockchaincom.py +1104 -0
  197. ccxt/async_support/blofin.py +2066 -0
  198. ccxt/async_support/btcalpha.py +891 -0
  199. ccxt/async_support/btcbox.py +544 -0
  200. ccxt/async_support/btcmarkets.py +1221 -0
  201. ccxt/async_support/btcturk.py +911 -0
  202. ccxt/async_support/bybit.py +8159 -0
  203. ccxt/async_support/cex.py +1605 -0
  204. ccxt/async_support/coinbase.py +4475 -0
  205. ccxt/async_support/coinbaseadvanced.py +17 -0
  206. ccxt/async_support/coinbaseexchange.py +1734 -0
  207. ccxt/async_support/coinbaseinternational.py +1899 -0
  208. ccxt/async_support/coincatch.py +5069 -0
  209. ccxt/async_support/coincheck.py +815 -0
  210. ccxt/async_support/coinex.py +5526 -0
  211. ccxt/async_support/coinlist.py +2243 -0
  212. ccxt/async_support/coinmate.py +1067 -0
  213. ccxt/async_support/coinmetro.py +1797 -0
  214. ccxt/async_support/coinone.py +1127 -0
  215. ccxt/async_support/coinsph.py +1850 -0
  216. ccxt/async_support/coinspot.py +534 -0
  217. ccxt/async_support/cryptocom.py +2822 -0
  218. ccxt/async_support/currencycom.py +1950 -0
  219. ccxt/async_support/delta.py +3376 -0
  220. ccxt/async_support/deribit.py +3437 -0
  221. ccxt/async_support/digifinex.py +3960 -0
  222. ccxt/async_support/eterex.py +286 -0
  223. ccxt/async_support/excoino.py +399 -0
  224. ccxt/async_support/exir.py +375 -0
  225. ccxt/async_support/exmo.py +2462 -0
  226. ccxt/async_support/exnovin.py +360 -0
  227. ccxt/async_support/farhadexchange.py +266 -0
  228. ccxt/async_support/fmfwio.py +34 -0
  229. ccxt/async_support/gate.py +6976 -0
  230. ccxt/async_support/gateio.py +16 -0
  231. ccxt/async_support/gemini.py +1825 -0
  232. ccxt/async_support/hashkey.py +4150 -0
  233. ccxt/async_support/hitbtc.py +3423 -0
  234. ccxt/async_support/hitbtc3.py +16 -0
  235. ccxt/async_support/hitobit.py +391 -0
  236. ccxt/async_support/hollaex.py +1813 -0
  237. ccxt/async_support/htx.py +8506 -0
  238. ccxt/async_support/huobi.py +16 -0
  239. ccxt/async_support/huobijp.py +1801 -0
  240. ccxt/async_support/hyperliquid.py +2431 -0
  241. ccxt/async_support/idex.py +1766 -0
  242. ccxt/async_support/independentreserve.py +784 -0
  243. ccxt/async_support/indodax.py +1247 -0
  244. ccxt/async_support/jibitex.py +395 -0
  245. ccxt/async_support/kraken.py +2894 -0
  246. ccxt/async_support/krakenfutures.py +2601 -0
  247. ccxt/async_support/kucoin.py +4602 -0
  248. ccxt/async_support/kucoinfutures.py +2698 -0
  249. ccxt/async_support/kuna.py +1841 -0
  250. ccxt/async_support/latoken.py +1664 -0
  251. ccxt/async_support/lbank.py +2683 -0
  252. ccxt/async_support/luno.py +1067 -0
  253. ccxt/async_support/lykke.py +1270 -0
  254. ccxt/async_support/mercado.py +842 -0
  255. ccxt/async_support/mexc.py +5369 -0
  256. ccxt/async_support/ndax.py +2354 -0
  257. ccxt/async_support/nobitex.py +419 -0
  258. ccxt/async_support/novadax.py +1484 -0
  259. ccxt/async_support/oceanex.py +903 -0
  260. ccxt/async_support/okcoin.py +2936 -0
  261. ccxt/async_support/okexchange.py +349 -0
  262. ccxt/async_support/okx.py +7827 -0
  263. ccxt/async_support/ompfinex.py +472 -0
  264. ccxt/async_support/onetrading.py +1911 -0
  265. ccxt/async_support/oxfun.py +2773 -0
  266. ccxt/async_support/p2b.py +1194 -0
  267. ccxt/async_support/paradex.py +2015 -0
  268. ccxt/async_support/paymium.py +564 -0
  269. ccxt/async_support/phemex.py +4473 -0
  270. ccxt/async_support/poloniex.py +2232 -0
  271. ccxt/async_support/poloniexfutures.py +1717 -0
  272. ccxt/async_support/probit.py +1734 -0
  273. ccxt/async_support/ramzinex.py +476 -0
  274. ccxt/async_support/sarmayex.py +357 -0
  275. ccxt/async_support/sarrafex.py +478 -0
  276. ccxt/async_support/tabdeal.py +364 -0
  277. ccxt/async_support/tetherland.py +349 -0
  278. ccxt/async_support/timex.py +1593 -0
  279. ccxt/async_support/tokocrypto.py +2405 -0
  280. ccxt/async_support/tradeogre.py +608 -0
  281. ccxt/async_support/twox.py +326 -0
  282. ccxt/async_support/ubitex.py +409 -0
  283. ccxt/async_support/upbit.py +1833 -0
  284. ccxt/async_support/vertex.py +2922 -0
  285. ccxt/async_support/wallex.py +445 -0
  286. ccxt/async_support/wavesexchange.py +2473 -0
  287. ccxt/async_support/wazirx.py +1224 -0
  288. ccxt/async_support/whitebit.py +2469 -0
  289. ccxt/async_support/woo.py +3114 -0
  290. ccxt/async_support/woofipro.py +2533 -0
  291. ccxt/async_support/xt.py +4454 -0
  292. ccxt/async_support/yobit.py +1283 -0
  293. ccxt/async_support/zaif.py +725 -0
  294. ccxt/async_support/zonda.py +1828 -0
  295. ccxt/base/__init__.py +27 -0
  296. ccxt/base/decimal_to_precision.py +174 -0
  297. ccxt/base/errors.py +242 -0
  298. ccxt/base/exchange.py +5941 -0
  299. ccxt/base/precise.py +287 -0
  300. ccxt/base/types.py +502 -0
  301. ccxt/bequant.py +33 -0
  302. ccxt/bigone.py +2112 -0
  303. ccxt/binance.py +12233 -0
  304. ccxt/binancecoinm.py +45 -0
  305. ccxt/binanceus.py +211 -0
  306. ccxt/binanceusdm.py +58 -0
  307. ccxt/bingx.py +4324 -0
  308. ccxt/bit2c.py +866 -0
  309. ccxt/bitbank.py +1001 -0
  310. ccxt/bitbay.py +17 -0
  311. ccxt/bitbns.py +1154 -0
  312. ccxt/bitcoincom.py +17 -0
  313. ccxt/bitfinex.py +1617 -0
  314. ccxt/bitfinex2.py +3552 -0
  315. ccxt/bitflyer.py +995 -0
  316. ccxt/bitget.py +8272 -0
  317. ccxt/bithumb.py +1061 -0
  318. ccxt/bitimen.py +401 -0
  319. ccxt/bitir.py +490 -0
  320. ccxt/bitmart.py +4415 -0
  321. ccxt/bitmex.py +2756 -0
  322. ccxt/bitopro.py +1630 -0
  323. ccxt/bitpanda.py +16 -0
  324. ccxt/bitpin.py +454 -0
  325. ccxt/bitrue.py +3026 -0
  326. ccxt/bitso.py +1670 -0
  327. ccxt/bitstamp.py +2203 -0
  328. ccxt/bitteam.py +2239 -0
  329. ccxt/bitvavo.py +1968 -0
  330. ccxt/bl3p.py +485 -0
  331. ccxt/blockchaincom.py +1104 -0
  332. ccxt/blofin.py +2066 -0
  333. ccxt/btcalpha.py +891 -0
  334. ccxt/btcbox.py +544 -0
  335. ccxt/btcmarkets.py +1221 -0
  336. ccxt/btcturk.py +911 -0
  337. ccxt/bybit.py +8158 -0
  338. ccxt/cex.py +1605 -0
  339. ccxt/coinbase.py +4474 -0
  340. ccxt/coinbaseadvanced.py +17 -0
  341. ccxt/coinbaseexchange.py +1734 -0
  342. ccxt/coinbaseinternational.py +1899 -0
  343. ccxt/coincatch.py +5069 -0
  344. ccxt/coincheck.py +815 -0
  345. ccxt/coinex.py +5525 -0
  346. ccxt/coinlist.py +2243 -0
  347. ccxt/coinmate.py +1067 -0
  348. ccxt/coinmetro.py +1797 -0
  349. ccxt/coinone.py +1127 -0
  350. ccxt/coinsph.py +1850 -0
  351. ccxt/coinspot.py +534 -0
  352. ccxt/cryptocom.py +2822 -0
  353. ccxt/currencycom.py +1950 -0
  354. ccxt/delta.py +3376 -0
  355. ccxt/deribit.py +3437 -0
  356. ccxt/digifinex.py +3959 -0
  357. ccxt/eterex.py +286 -0
  358. ccxt/excoino.py +399 -0
  359. ccxt/exir.py +375 -0
  360. ccxt/exmo.py +2462 -0
  361. ccxt/exnovin.py +360 -0
  362. ccxt/farhadexchange.py +266 -0
  363. ccxt/fmfwio.py +34 -0
  364. ccxt/gate.py +6975 -0
  365. ccxt/gateio.py +16 -0
  366. ccxt/gemini.py +1824 -0
  367. ccxt/hashkey.py +4150 -0
  368. ccxt/hitbtc.py +3423 -0
  369. ccxt/hitbtc3.py +16 -0
  370. ccxt/hitobit.py +391 -0
  371. ccxt/hollaex.py +1813 -0
  372. ccxt/htx.py +8505 -0
  373. ccxt/huobi.py +16 -0
  374. ccxt/huobijp.py +1801 -0
  375. ccxt/hyperliquid.py +2430 -0
  376. ccxt/idex.py +1766 -0
  377. ccxt/independentreserve.py +784 -0
  378. ccxt/indodax.py +1247 -0
  379. ccxt/jibitex.py +395 -0
  380. ccxt/kraken.py +2894 -0
  381. ccxt/krakenfutures.py +2601 -0
  382. ccxt/kucoin.py +4601 -0
  383. ccxt/kucoinfutures.py +2698 -0
  384. ccxt/kuna.py +1841 -0
  385. ccxt/latoken.py +1664 -0
  386. ccxt/lbank.py +2682 -0
  387. ccxt/luno.py +1067 -0
  388. ccxt/lykke.py +1270 -0
  389. ccxt/mercado.py +842 -0
  390. ccxt/mexc.py +5369 -0
  391. ccxt/ndax.py +2354 -0
  392. ccxt/nobitex.py +419 -0
  393. ccxt/novadax.py +1484 -0
  394. ccxt/oceanex.py +903 -0
  395. ccxt/okcoin.py +2936 -0
  396. ccxt/okexchange.py +349 -0
  397. ccxt/okx.py +7826 -0
  398. ccxt/ompfinex.py +472 -0
  399. ccxt/onetrading.py +1911 -0
  400. ccxt/oxfun.py +2772 -0
  401. ccxt/p2b.py +1194 -0
  402. ccxt/paradex.py +2015 -0
  403. ccxt/paymium.py +564 -0
  404. ccxt/phemex.py +4473 -0
  405. ccxt/poloniex.py +2232 -0
  406. ccxt/poloniexfutures.py +1717 -0
  407. ccxt/pro/__init__.py +149 -0
  408. ccxt/pro/alpaca.py +685 -0
  409. ccxt/pro/ascendex.py +916 -0
  410. ccxt/pro/bequant.py +38 -0
  411. ccxt/pro/binance.py +3488 -0
  412. ccxt/pro/binancecoinm.py +28 -0
  413. ccxt/pro/binanceus.py +48 -0
  414. ccxt/pro/binanceusdm.py +31 -0
  415. ccxt/pro/bingx.py +1264 -0
  416. ccxt/pro/bitcoincom.py +34 -0
  417. ccxt/pro/bitfinex.py +621 -0
  418. ccxt/pro/bitfinex2.py +1083 -0
  419. ccxt/pro/bitget.py +1692 -0
  420. ccxt/pro/bithumb.py +368 -0
  421. ccxt/pro/bitmart.py +1449 -0
  422. ccxt/pro/bitmex.py +1656 -0
  423. ccxt/pro/bitopro.py +445 -0
  424. ccxt/pro/bitpanda.py +15 -0
  425. ccxt/pro/bitrue.py +447 -0
  426. ccxt/pro/bitstamp.py +522 -0
  427. ccxt/pro/bitvavo.py +1270 -0
  428. ccxt/pro/blockchaincom.py +738 -0
  429. ccxt/pro/blofin.py +692 -0
  430. ccxt/pro/bybit.py +2000 -0
  431. ccxt/pro/cex.py +1440 -0
  432. ccxt/pro/coinbase.py +678 -0
  433. ccxt/pro/coinbaseadvanced.py +16 -0
  434. ccxt/pro/coinbaseexchange.py +895 -0
  435. ccxt/pro/coinbaseinternational.py +620 -0
  436. ccxt/pro/coincatch.py +1464 -0
  437. ccxt/pro/coincheck.py +199 -0
  438. ccxt/pro/coinex.py +1061 -0
  439. ccxt/pro/coinone.py +395 -0
  440. ccxt/pro/cryptocom.py +947 -0
  441. ccxt/pro/currencycom.py +536 -0
  442. ccxt/pro/deribit.py +892 -0
  443. ccxt/pro/exmo.py +629 -0
  444. ccxt/pro/gate.py +1416 -0
  445. ccxt/pro/gateio.py +15 -0
  446. ccxt/pro/gemini.py +865 -0
  447. ccxt/pro/hashkey.py +802 -0
  448. ccxt/pro/hitbtc.py +1216 -0
  449. ccxt/pro/hollaex.py +563 -0
  450. ccxt/pro/htx.py +2215 -0
  451. ccxt/pro/huobi.py +15 -0
  452. ccxt/pro/huobijp.py +570 -0
  453. ccxt/pro/hyperliquid.py +525 -0
  454. ccxt/pro/idex.py +672 -0
  455. ccxt/pro/independentreserve.py +270 -0
  456. ccxt/pro/kraken.py +1356 -0
  457. ccxt/pro/krakenfutures.py +1492 -0
  458. ccxt/pro/kucoin.py +1133 -0
  459. ccxt/pro/kucoinfutures.py +1081 -0
  460. ccxt/pro/lbank.py +843 -0
  461. ccxt/pro/luno.py +303 -0
  462. ccxt/pro/mexc.py +1122 -0
  463. ccxt/pro/ndax.py +506 -0
  464. ccxt/pro/okcoin.py +698 -0
  465. ccxt/pro/okx.py +1851 -0
  466. ccxt/pro/onetrading.py +1275 -0
  467. ccxt/pro/oxfun.py +950 -0
  468. ccxt/pro/p2b.py +419 -0
  469. ccxt/pro/paradex.py +352 -0
  470. ccxt/pro/phemex.py +1441 -0
  471. ccxt/pro/poloniex.py +1166 -0
  472. ccxt/pro/poloniexfutures.py +990 -0
  473. ccxt/pro/probit.py +551 -0
  474. ccxt/pro/upbit.py +520 -0
  475. ccxt/pro/vertex.py +943 -0
  476. ccxt/pro/wazirx.py +749 -0
  477. ccxt/pro/whitebit.py +864 -0
  478. ccxt/pro/woo.py +1078 -0
  479. ccxt/pro/woofipro.py +1183 -0
  480. ccxt/pro/xt.py +1067 -0
  481. ccxt/probit.py +1734 -0
  482. ccxt/ramzinex.py +476 -0
  483. ccxt/sarmayex.py +357 -0
  484. ccxt/sarrafex.py +478 -0
  485. ccxt/static_dependencies/__init__.py +1 -0
  486. ccxt/static_dependencies/ecdsa/__init__.py +14 -0
  487. ccxt/static_dependencies/ecdsa/_version.py +520 -0
  488. ccxt/static_dependencies/ecdsa/curves.py +56 -0
  489. ccxt/static_dependencies/ecdsa/der.py +221 -0
  490. ccxt/static_dependencies/ecdsa/ecdsa.py +310 -0
  491. ccxt/static_dependencies/ecdsa/ellipticcurve.py +197 -0
  492. ccxt/static_dependencies/ecdsa/keys.py +332 -0
  493. ccxt/static_dependencies/ecdsa/numbertheory.py +531 -0
  494. ccxt/static_dependencies/ecdsa/rfc6979.py +100 -0
  495. ccxt/static_dependencies/ecdsa/util.py +266 -0
  496. ccxt/static_dependencies/ethereum/__init__.py +7 -0
  497. ccxt/static_dependencies/ethereum/abi/__init__.py +16 -0
  498. ccxt/static_dependencies/ethereum/abi/abi.py +19 -0
  499. ccxt/static_dependencies/ethereum/abi/base.py +152 -0
  500. ccxt/static_dependencies/ethereum/abi/codec.py +217 -0
  501. ccxt/static_dependencies/ethereum/abi/constants.py +3 -0
  502. ccxt/static_dependencies/ethereum/abi/decoding.py +565 -0
  503. ccxt/static_dependencies/ethereum/abi/encoding.py +720 -0
  504. ccxt/static_dependencies/ethereum/abi/exceptions.py +139 -0
  505. ccxt/static_dependencies/ethereum/abi/grammar.py +443 -0
  506. ccxt/static_dependencies/ethereum/abi/packed.py +13 -0
  507. ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
  508. ccxt/static_dependencies/ethereum/abi/registry.py +643 -0
  509. ccxt/static_dependencies/ethereum/abi/tools/__init__.py +3 -0
  510. ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +230 -0
  511. ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
  512. ccxt/static_dependencies/ethereum/abi/utils/numeric.py +83 -0
  513. ccxt/static_dependencies/ethereum/abi/utils/padding.py +27 -0
  514. ccxt/static_dependencies/ethereum/abi/utils/string.py +19 -0
  515. ccxt/static_dependencies/ethereum/account/__init__.py +3 -0
  516. ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +4 -0
  517. ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +239 -0
  518. ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +40 -0
  519. ccxt/static_dependencies/ethereum/account/messages.py +263 -0
  520. ccxt/static_dependencies/ethereum/account/py.typed +0 -0
  521. ccxt/static_dependencies/ethereum/hexbytes/__init__.py +5 -0
  522. ccxt/static_dependencies/ethereum/hexbytes/_utils.py +54 -0
  523. ccxt/static_dependencies/ethereum/hexbytes/main.py +65 -0
  524. ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
  525. ccxt/static_dependencies/ethereum/typing/__init__.py +63 -0
  526. ccxt/static_dependencies/ethereum/typing/abi.py +6 -0
  527. ccxt/static_dependencies/ethereum/typing/bls.py +7 -0
  528. ccxt/static_dependencies/ethereum/typing/discovery.py +5 -0
  529. ccxt/static_dependencies/ethereum/typing/encoding.py +7 -0
  530. ccxt/static_dependencies/ethereum/typing/enums.py +17 -0
  531. ccxt/static_dependencies/ethereum/typing/ethpm.py +9 -0
  532. ccxt/static_dependencies/ethereum/typing/evm.py +20 -0
  533. ccxt/static_dependencies/ethereum/typing/networks.py +1122 -0
  534. ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
  535. ccxt/static_dependencies/ethereum/utils/__init__.py +115 -0
  536. ccxt/static_dependencies/ethereum/utils/abi.py +72 -0
  537. ccxt/static_dependencies/ethereum/utils/address.py +171 -0
  538. ccxt/static_dependencies/ethereum/utils/applicators.py +151 -0
  539. ccxt/static_dependencies/ethereum/utils/conversions.py +190 -0
  540. ccxt/static_dependencies/ethereum/utils/currency.py +107 -0
  541. ccxt/static_dependencies/ethereum/utils/curried/__init__.py +269 -0
  542. ccxt/static_dependencies/ethereum/utils/debug.py +20 -0
  543. ccxt/static_dependencies/ethereum/utils/decorators.py +132 -0
  544. ccxt/static_dependencies/ethereum/utils/encoding.py +6 -0
  545. ccxt/static_dependencies/ethereum/utils/exceptions.py +4 -0
  546. ccxt/static_dependencies/ethereum/utils/functional.py +75 -0
  547. ccxt/static_dependencies/ethereum/utils/hexadecimal.py +74 -0
  548. ccxt/static_dependencies/ethereum/utils/humanize.py +188 -0
  549. ccxt/static_dependencies/ethereum/utils/logging.py +159 -0
  550. ccxt/static_dependencies/ethereum/utils/module_loading.py +31 -0
  551. ccxt/static_dependencies/ethereum/utils/numeric.py +43 -0
  552. ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
  553. ccxt/static_dependencies/ethereum/utils/toolz.py +76 -0
  554. ccxt/static_dependencies/ethereum/utils/types.py +54 -0
  555. ccxt/static_dependencies/ethereum/utils/typing/__init__.py +18 -0
  556. ccxt/static_dependencies/ethereum/utils/typing/misc.py +14 -0
  557. ccxt/static_dependencies/ethereum/utils/units.py +31 -0
  558. ccxt/static_dependencies/keccak/__init__.py +3 -0
  559. ccxt/static_dependencies/keccak/keccak.py +197 -0
  560. ccxt/static_dependencies/lark/__init__.py +38 -0
  561. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  562. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  563. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  564. ccxt/static_dependencies/lark/common.py +86 -0
  565. ccxt/static_dependencies/lark/exceptions.py +292 -0
  566. ccxt/static_dependencies/lark/grammar.py +130 -0
  567. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  568. ccxt/static_dependencies/lark/indenter.py +143 -0
  569. ccxt/static_dependencies/lark/lark.py +658 -0
  570. ccxt/static_dependencies/lark/lexer.py +678 -0
  571. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  572. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  573. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  574. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  575. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  576. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  577. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  578. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  579. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  580. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  581. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  582. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  583. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  584. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  585. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  586. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  587. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  588. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  589. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  590. ccxt/static_dependencies/lark/tree.py +267 -0
  591. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  592. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  593. ccxt/static_dependencies/lark/utils.py +343 -0
  594. ccxt/static_dependencies/lark/visitors.py +596 -0
  595. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  596. ccxt/static_dependencies/marshmallow/base.py +65 -0
  597. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  598. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  599. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  600. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  601. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  602. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  603. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  604. ccxt/static_dependencies/marshmallow/types.py +12 -0
  605. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  606. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  607. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  608. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  609. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  610. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  611. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  612. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  613. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  614. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  615. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  616. ccxt/static_dependencies/msgpack/__init__.py +55 -0
  617. ccxt/static_dependencies/msgpack/exceptions.py +48 -0
  618. ccxt/static_dependencies/msgpack/ext.py +168 -0
  619. ccxt/static_dependencies/msgpack/fallback.py +951 -0
  620. ccxt/static_dependencies/parsimonious/__init__.py +10 -0
  621. ccxt/static_dependencies/parsimonious/exceptions.py +105 -0
  622. ccxt/static_dependencies/parsimonious/expressions.py +479 -0
  623. ccxt/static_dependencies/parsimonious/grammar.py +487 -0
  624. ccxt/static_dependencies/parsimonious/nodes.py +325 -0
  625. ccxt/static_dependencies/parsimonious/utils.py +40 -0
  626. ccxt/static_dependencies/starknet/__init__.py +0 -0
  627. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  628. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  629. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  630. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  631. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  632. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  633. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  634. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  635. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  636. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  637. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  638. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  639. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  640. ccxt/static_dependencies/starknet/common.py +15 -0
  641. ccxt/static_dependencies/starknet/constants.py +39 -0
  642. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  643. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  644. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  645. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  646. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  647. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  648. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  649. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  650. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  651. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  652. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  653. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  654. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  655. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  656. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  657. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  658. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  659. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  660. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  661. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  662. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  663. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  664. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  665. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  666. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  667. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  668. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  669. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  670. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  671. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  672. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  673. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  674. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  675. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  676. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  677. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  678. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  679. ccxt/static_dependencies/starkware/__init__.py +0 -0
  680. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  681. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  682. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  683. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  684. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  685. ccxt/static_dependencies/sympy/__init__.py +0 -0
  686. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  687. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  688. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  689. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  690. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  691. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  692. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  693. ccxt/static_dependencies/toolz/__init__.py +26 -0
  694. ccxt/static_dependencies/toolz/_signatures.py +784 -0
  695. ccxt/static_dependencies/toolz/_version.py +520 -0
  696. ccxt/static_dependencies/toolz/compatibility.py +30 -0
  697. ccxt/static_dependencies/toolz/curried/__init__.py +101 -0
  698. ccxt/static_dependencies/toolz/curried/exceptions.py +22 -0
  699. ccxt/static_dependencies/toolz/curried/operator.py +22 -0
  700. ccxt/static_dependencies/toolz/dicttoolz.py +339 -0
  701. ccxt/static_dependencies/toolz/functoolz.py +1049 -0
  702. ccxt/static_dependencies/toolz/itertoolz.py +1057 -0
  703. ccxt/static_dependencies/toolz/recipes.py +46 -0
  704. ccxt/static_dependencies/toolz/utils.py +9 -0
  705. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  706. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  707. ccxt/tabdeal.py +364 -0
  708. ccxt/test/__init__.py +3 -0
  709. ccxt/test/base/__init__.py +29 -0
  710. ccxt/test/base/test_account.py +26 -0
  711. ccxt/test/base/test_balance.py +56 -0
  712. ccxt/test/base/test_borrow_interest.py +35 -0
  713. ccxt/test/base/test_borrow_rate.py +32 -0
  714. ccxt/test/base/test_calculate_fee.py +51 -0
  715. ccxt/test/base/test_crypto.py +127 -0
  716. ccxt/test/base/test_currency.py +76 -0
  717. ccxt/test/base/test_datetime.py +109 -0
  718. ccxt/test/base/test_decimal_to_precision.py +392 -0
  719. ccxt/test/base/test_deep_extend.py +68 -0
  720. ccxt/test/base/test_deposit_withdrawal.py +50 -0
  721. ccxt/test/base/test_exchange_datetime_functions.py +76 -0
  722. ccxt/test/base/test_funding_rate_history.py +29 -0
  723. ccxt/test/base/test_last_price.py +31 -0
  724. ccxt/test/base/test_ledger_entry.py +45 -0
  725. ccxt/test/base/test_ledger_item.py +48 -0
  726. ccxt/test/base/test_leverage_tier.py +33 -0
  727. ccxt/test/base/test_liquidation.py +50 -0
  728. ccxt/test/base/test_margin_mode.py +24 -0
  729. ccxt/test/base/test_margin_modification.py +35 -0
  730. ccxt/test/base/test_market.py +193 -0
  731. ccxt/test/base/test_number.py +411 -0
  732. ccxt/test/base/test_ohlcv.py +33 -0
  733. ccxt/test/base/test_open_interest.py +32 -0
  734. ccxt/test/base/test_order.py +64 -0
  735. ccxt/test/base/test_order_book.py +69 -0
  736. ccxt/test/base/test_position.py +60 -0
  737. ccxt/test/base/test_shared_methods.py +353 -0
  738. ccxt/test/base/test_status.py +24 -0
  739. ccxt/test/base/test_throttle.py +126 -0
  740. ccxt/test/base/test_ticker.py +92 -0
  741. ccxt/test/base/test_trade.py +47 -0
  742. ccxt/test/base/test_trading_fee.py +26 -0
  743. ccxt/test/base/test_transaction.py +39 -0
  744. ccxt/test/test_async.py +1649 -0
  745. ccxt/test/test_sync.py +1648 -0
  746. ccxt/test/tests_async.py +1558 -0
  747. ccxt/test/tests_helpers.py +287 -0
  748. ccxt/test/tests_init.py +39 -0
  749. ccxt/test/tests_sync.py +1555 -0
  750. ccxt/tetherland.py +349 -0
  751. ccxt/timex.py +1593 -0
  752. ccxt/tokocrypto.py +2405 -0
  753. ccxt/tradeogre.py +608 -0
  754. ccxt/twox.py +326 -0
  755. ccxt/ubitex.py +409 -0
  756. ccxt/upbit.py +1833 -0
  757. ccxt/vertex.py +2922 -0
  758. ccxt/wallex.py +445 -0
  759. ccxt/wavesexchange.py +2472 -0
  760. ccxt/wazirx.py +1224 -0
  761. ccxt/whitebit.py +2469 -0
  762. ccxt/woo.py +3114 -0
  763. ccxt/woofipro.py +2533 -0
  764. ccxt/xt.py +4453 -0
  765. ccxt/yobit.py +1283 -0
  766. ccxt/zaif.py +725 -0
  767. ccxt/zonda.py +1828 -0
  768. ccxt_ir-4.3.46.0.1.dist-info/LICENSE.txt +21 -0
  769. ccxt_ir-4.3.46.0.1.dist-info/METADATA +655 -0
  770. ccxt_ir-4.3.46.0.1.dist-info/RECORD +772 -0
  771. ccxt_ir-4.3.46.0.1.dist-info/WHEEL +6 -0
  772. ccxt_ir-4.3.46.0.1.dist-info/top_level.txt +1 -0
ccxt/deribit.py ADDED
@@ -0,0 +1,3437 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+
6
+ from ccxt.base.exchange import Exchange
7
+ from ccxt.abstract.deribit import ImplicitAPI
8
+ import hashlib
9
+ from ccxt.base.types import Account, Balances, Currencies, Currency, Greeks, Int, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction, TransferEntry, TransferEntries
10
+ from typing import List
11
+ from ccxt.base.errors import ExchangeError
12
+ from ccxt.base.errors import AuthenticationError
13
+ from ccxt.base.errors import PermissionDenied
14
+ from ccxt.base.errors import ArgumentsRequired
15
+ from ccxt.base.errors import BadRequest
16
+ from ccxt.base.errors import InsufficientFunds
17
+ from ccxt.base.errors import InvalidAddress
18
+ from ccxt.base.errors import InvalidOrder
19
+ from ccxt.base.errors import OrderNotFound
20
+ from ccxt.base.errors import NotSupported
21
+ from ccxt.base.errors import DDoSProtection
22
+ from ccxt.base.errors import ExchangeNotAvailable
23
+ from ccxt.base.errors import OnMaintenance
24
+ from ccxt.base.decimal_to_precision import TICK_SIZE
25
+ from ccxt.base.precise import Precise
26
+
27
+
28
+ class deribit(Exchange, ImplicitAPI):
29
+
30
+ def describe(self):
31
+ return self.deep_extend(super(deribit, self).describe(), {
32
+ 'id': 'deribit',
33
+ 'name': 'Deribit',
34
+ 'countries': ['NL'], # Netherlands
35
+ 'version': 'v2',
36
+ 'userAgent': None,
37
+ # 20 requests per second for non-matching-engine endpoints, 1000ms / 20 = 50ms between requests
38
+ # 5 requests per second for matching-engine endpoints, cost = (1000ms / rateLimit) / 5 = 4
39
+ 'rateLimit': 50,
40
+ 'pro': True,
41
+ 'has': {
42
+ 'CORS': True,
43
+ 'spot': False,
44
+ 'margin': False,
45
+ 'swap': True,
46
+ 'future': True,
47
+ 'option': True,
48
+ 'cancelAllOrders': True,
49
+ 'cancelOrder': True,
50
+ 'cancelOrders': False,
51
+ 'createDepositAddress': True,
52
+ 'createOrder': True,
53
+ 'createStopLimitOrder': True,
54
+ 'createStopMarketOrder': True,
55
+ 'createStopOrder': True,
56
+ 'createTrailingAmountOrder': True,
57
+ 'editOrder': True,
58
+ 'fetchAccounts': True,
59
+ 'fetchBalance': True,
60
+ 'fetchBorrowRateHistories': False,
61
+ 'fetchBorrowRateHistory': False,
62
+ 'fetchClosedOrders': True,
63
+ 'fetchCrossBorrowRate': False,
64
+ 'fetchCrossBorrowRates': False,
65
+ 'fetchCurrencies': True,
66
+ 'fetchDeposit': False,
67
+ 'fetchDepositAddress': True,
68
+ 'fetchDeposits': True,
69
+ 'fetchDepositWithdrawFees': True,
70
+ 'fetchFundingRate': True,
71
+ 'fetchFundingRateHistory': True,
72
+ 'fetchGreeks': True,
73
+ 'fetchIndexOHLCV': False,
74
+ 'fetchIsolatedBorrowRate': False,
75
+ 'fetchIsolatedBorrowRates': False,
76
+ 'fetchLeverageTiers': False,
77
+ 'fetchLiquidations': True,
78
+ 'fetchMarginMode': False,
79
+ 'fetchMarkets': True,
80
+ 'fetchMarkOHLCV': False,
81
+ 'fetchMyLiquidations': True,
82
+ 'fetchMySettlementHistory': False,
83
+ 'fetchMyTrades': True,
84
+ 'fetchOHLCV': True,
85
+ 'fetchOpenOrders': True,
86
+ 'fetchOption': True,
87
+ 'fetchOptionChain': True,
88
+ 'fetchOrder': True,
89
+ 'fetchOrderBook': True,
90
+ 'fetchOrders': False,
91
+ 'fetchOrderTrades': True,
92
+ 'fetchPosition': True,
93
+ 'fetchPositionMode': False,
94
+ 'fetchPositions': True,
95
+ 'fetchPremiumIndexOHLCV': False,
96
+ 'fetchStatus': True,
97
+ 'fetchTicker': True,
98
+ 'fetchTickers': True,
99
+ 'fetchTime': True,
100
+ 'fetchTrades': True,
101
+ 'fetchTradingFee': False,
102
+ 'fetchTradingFees': True,
103
+ 'fetchTransactions': False,
104
+ 'fetchTransfer': False,
105
+ 'fetchTransfers': True,
106
+ 'fetchUnderlyingAssets': False,
107
+ 'fetchVolatilityHistory': True,
108
+ 'fetchWithdrawal': False,
109
+ 'fetchWithdrawals': True,
110
+ 'sandbox': True,
111
+ 'transfer': True,
112
+ 'withdraw': True,
113
+ },
114
+ 'timeframes': {
115
+ '1m': '1',
116
+ '3m': '3',
117
+ '5m': '5',
118
+ '10m': '10',
119
+ '15m': '15',
120
+ '30m': '30',
121
+ '1h': '60',
122
+ '2h': '120',
123
+ '3h': '180',
124
+ '6h': '360',
125
+ '12h': '720',
126
+ '1d': '1D',
127
+ },
128
+ 'urls': {
129
+ 'test': {
130
+ 'rest': 'https://test.deribit.com',
131
+ },
132
+ 'logo': 'https://user-images.githubusercontent.com/1294454/41933112-9e2dd65a-798b-11e8-8440-5bab2959fcb8.jpg',
133
+ 'api': {
134
+ 'rest': 'https://www.deribit.com',
135
+ },
136
+ 'www': 'https://www.deribit.com',
137
+ 'doc': [
138
+ 'https://docs.deribit.com/v2',
139
+ 'https://github.com/deribit',
140
+ ],
141
+ 'fees': 'https://www.deribit.com/pages/information/fees',
142
+ 'referral': {
143
+ 'url': 'https://www.deribit.com/reg-1189.4038',
144
+ 'discount': 0.1,
145
+ },
146
+ },
147
+ 'api': {
148
+ 'public': {
149
+ 'get': {
150
+ # Authentication
151
+ 'auth': 1,
152
+ 'exchange_token': 1,
153
+ 'fork_token': 1,
154
+ # Session management
155
+ 'set_heartbeat': 1,
156
+ 'disable_heartbeat': 1,
157
+ # Supporting
158
+ 'get_time': 1,
159
+ 'hello': 1,
160
+ 'status': 1,
161
+ 'test': 1,
162
+ # Subscription management
163
+ 'subscribe': 1,
164
+ 'unsubscribe': 1,
165
+ 'unsubscribe_all': 1,
166
+ # Account management
167
+ 'get_announcements': 1,
168
+ # Market data
169
+ 'get_book_summary_by_currency': 1,
170
+ 'get_book_summary_by_instrument': 1,
171
+ 'get_contract_size': 1,
172
+ 'get_currencies': 1,
173
+ 'get_delivery_prices': 1,
174
+ 'get_funding_chart_data': 1,
175
+ 'get_funding_rate_history': 1,
176
+ 'get_funding_rate_value': 1,
177
+ 'get_historical_volatility': 1,
178
+ 'get_index': 1,
179
+ 'get_index_price': 1,
180
+ 'get_index_price_names': 1,
181
+ 'get_instrument': 1,
182
+ 'get_instruments': 1,
183
+ 'get_last_settlements_by_currency': 1,
184
+ 'get_last_settlements_by_instrument': 1,
185
+ 'get_last_trades_by_currency': 1,
186
+ 'get_last_trades_by_currency_and_time': 1,
187
+ 'get_last_trades_by_instrument': 1,
188
+ 'get_last_trades_by_instrument_and_time': 1,
189
+ 'get_mark_price_history': 1,
190
+ 'get_order_book': 1,
191
+ 'get_trade_volumes': 1,
192
+ 'get_tradingview_chart_data': 1,
193
+ 'get_volatility_index_data': 1,
194
+ 'ticker': 1,
195
+ },
196
+ },
197
+ 'private': {
198
+ 'get': {
199
+ # Authentication
200
+ 'logout': 1,
201
+ # Session management
202
+ 'enable_cancel_on_disconnect': 1,
203
+ 'disable_cancel_on_disconnect': 1,
204
+ 'get_cancel_on_disconnect': 1,
205
+ # Subscription management
206
+ 'subscribe': 1,
207
+ 'unsubscribe': 1,
208
+ 'unsubscribe_all': 1,
209
+ # Account management
210
+ 'change_api_key_name': 1,
211
+ 'change_scope_in_api_key': 1,
212
+ 'change_subaccount_name': 1,
213
+ 'create_api_key': 1,
214
+ 'create_subaccount': 1,
215
+ 'disable_api_key': 1,
216
+ 'disable_tfa_for_subaccount': 1,
217
+ 'enable_affiliate_program': 1,
218
+ 'enable_api_key': 1,
219
+ 'get_access_log': 1,
220
+ 'get_account_summary': 1,
221
+ 'get_affiliate_program_info': 1,
222
+ 'get_email_language': 1,
223
+ 'get_new_announcements': 1,
224
+ 'get_portfolio_margins': 1,
225
+ 'get_position': 1,
226
+ 'get_positions': 1,
227
+ 'get_subaccounts': 1,
228
+ 'get_subaccounts_details': 1,
229
+ 'get_transaction_log': 1,
230
+ 'list_api_keys': 1,
231
+ 'remove_api_key': 1,
232
+ 'remove_subaccount': 1,
233
+ 'reset_api_key': 1,
234
+ 'set_announcement_as_read': 1,
235
+ 'set_api_key_as_default': 1,
236
+ 'set_email_for_subaccount': 1,
237
+ 'set_email_language': 1,
238
+ 'set_password_for_subaccount': 1,
239
+ 'toggle_notifications_from_subaccount': 1,
240
+ 'toggle_subaccount_login': 1,
241
+ # Block Trade
242
+ 'execute_block_trade': 4,
243
+ 'get_block_trade': 1,
244
+ 'get_last_block_trades_by_currency': 1,
245
+ 'invalidate_block_trade_signature': 1,
246
+ 'verify_block_trade': 4,
247
+ # Trading
248
+ 'buy': 4,
249
+ 'sell': 4,
250
+ 'edit': 4,
251
+ 'edit_by_label': 4,
252
+ 'cancel': 4,
253
+ 'cancel_all': 4,
254
+ 'cancel_all_by_currency': 4,
255
+ 'cancel_all_by_instrument': 4,
256
+ 'cancel_by_label': 4,
257
+ 'close_position': 4,
258
+ 'get_margins': 1,
259
+ 'get_mmp_config': 1,
260
+ 'get_open_orders_by_currency': 1,
261
+ 'get_open_orders_by_instrument': 1,
262
+ 'get_order_history_by_currency': 1,
263
+ 'get_order_history_by_instrument': 1,
264
+ 'get_order_margin_by_ids': 1,
265
+ 'get_order_state': 1,
266
+ 'get_stop_order_history': 1, # deprecated
267
+ 'get_trigger_order_history': 1,
268
+ 'get_user_trades_by_currency': 1,
269
+ 'get_user_trades_by_currency_and_time': 1,
270
+ 'get_user_trades_by_instrument': 1,
271
+ 'get_user_trades_by_instrument_and_time': 1,
272
+ 'get_user_trades_by_order': 1,
273
+ 'reset_mmp': 1,
274
+ 'set_mmp_config': 1,
275
+ 'get_settlement_history_by_instrument': 1,
276
+ 'get_settlement_history_by_currency': 1,
277
+ # Wallet
278
+ 'cancel_transfer_by_id': 1,
279
+ 'cancel_withdrawal': 1,
280
+ 'create_deposit_address': 1,
281
+ 'get_current_deposit_address': 1,
282
+ 'get_deposits': 1,
283
+ 'get_transfers': 1,
284
+ 'get_withdrawals': 1,
285
+ 'submit_transfer_to_subaccount': 1,
286
+ 'submit_transfer_to_user': 1,
287
+ 'withdraw': 1,
288
+ },
289
+ },
290
+ },
291
+ 'exceptions': {
292
+ # 0 or absent Success, No error.
293
+ '9999': PermissionDenied, # 'api_not_enabled' User didn't enable API for the Account.
294
+ '10000': AuthenticationError, # 'authorization_required' Authorization issue, invalid or absent signature etc.
295
+ '10001': ExchangeError, # 'error' Some general failure, no public information available.
296
+ '10002': InvalidOrder, # 'qty_too_low' Order quantity is too low.
297
+ '10003': InvalidOrder, # 'order_overlap' Rejection, order overlap is found and self-trading is not enabled.
298
+ '10004': OrderNotFound, # 'order_not_found' Attempt to operate with order that can't be found by specified id.
299
+ '10005': InvalidOrder, # 'price_too_low <Limit>' Price is too low, <Limit> defines current limit for the operation.
300
+ '10006': InvalidOrder, # 'price_too_low4idx <Limit>' Price is too low for current index, <Limit> defines current bottom limit for the operation.
301
+ '10007': InvalidOrder, # 'price_too_high <Limit>' Price is too high, <Limit> defines current up limit for the operation.
302
+ '10008': InvalidOrder, # 'price_too_high4idx <Limit>' Price is too high for current index, <Limit> defines current up limit for the operation.
303
+ '10009': InsufficientFunds, # 'not_enough_funds' Account has not enough funds for the operation.
304
+ '10010': OrderNotFound, # 'already_closed' Attempt of doing something with closed order.
305
+ '10011': InvalidOrder, # 'price_not_allowed' This price is not allowed for some reason.
306
+ '10012': InvalidOrder, # 'book_closed' Operation for instrument which order book had been closed.
307
+ '10013': PermissionDenied, # 'pme_max_total_open_orders <Limit>' Total limit of open orders has been exceeded, it is applicable for PME users.
308
+ '10014': PermissionDenied, # 'pme_max_future_open_orders <Limit>' Limit of count of futures' open orders has been exceeded, it is applicable for PME users.
309
+ '10015': PermissionDenied, # 'pme_max_option_open_orders <Limit>' Limit of count of options' open orders has been exceeded, it is applicable for PME users.
310
+ '10016': PermissionDenied, # 'pme_max_future_open_orders_size <Limit>' Limit of size for futures has been exceeded, it is applicable for PME users.
311
+ '10017': PermissionDenied, # 'pme_max_option_open_orders_size <Limit>' Limit of size for options has been exceeded, it is applicable for PME users.
312
+ '10018': PermissionDenied, # 'non_pme_max_future_position_size <Limit>' Limit of size for futures has been exceeded, it is applicable for non-PME users.
313
+ '10019': PermissionDenied, # 'locked_by_admin' Trading is temporary locked by admin.
314
+ '10020': ExchangeError, # 'invalid_or_unsupported_instrument' Instrument name is not valid.
315
+ '10021': InvalidOrder, # 'invalid_amount' Amount is not valid.
316
+ '10022': InvalidOrder, # 'invalid_quantity' quantity was not recognized valid number(for API v1).
317
+ '10023': InvalidOrder, # 'invalid_price' price was not recognized valid number.
318
+ '10024': InvalidOrder, # 'invalid_max_show' max_show parameter was not recognized valid number.
319
+ '10025': InvalidOrder, # 'invalid_order_id' Order id is missing or its format was not recognized.
320
+ '10026': InvalidOrder, # 'price_precision_exceeded' Extra precision of the price is not supported.
321
+ '10027': InvalidOrder, # 'non_integer_contract_amount' Futures contract amount was not recognized.
322
+ '10028': DDoSProtection, # 'too_many_requests' Allowed request rate has been exceeded.
323
+ '10029': OrderNotFound, # 'not_owner_of_order' Attempt to operate with not own order.
324
+ '10030': ExchangeError, # 'must_be_websocket_request' REST request where Websocket is expected.
325
+ '10031': ExchangeError, # 'invalid_args_for_instrument' Some of arguments are not recognized.
326
+ '10032': InvalidOrder, # 'whole_cost_too_low' Total cost is too low.
327
+ '10033': NotSupported, # 'not_implemented' Method is not implemented yet.
328
+ '10034': InvalidOrder, # 'stop_price_too_high' Stop price is too high.
329
+ '10035': InvalidOrder, # 'stop_price_too_low' Stop price is too low.
330
+ '10036': InvalidOrder, # 'invalid_max_show_amount' Max Show Amount is not valid.
331
+ '10040': ExchangeNotAvailable, # 'retry' Request can't be processed right now and should be retried.
332
+ '10041': OnMaintenance, # 'settlement_in_progress' Settlement is in progress. Every day at settlement time for several seconds, the system calculates user profits and updates balances. That time trading is paused for several seconds till the calculation is completed.
333
+ '10043': InvalidOrder, # 'price_wrong_tick' Price has to be rounded to a certain tick size.
334
+ '10044': InvalidOrder, # 'stop_price_wrong_tick' Stop Price has to be rounded to a certain tick size.
335
+ '10045': InvalidOrder, # 'can_not_cancel_liquidation_order' Liquidation order can't be canceled.
336
+ '10046': InvalidOrder, # 'can_not_edit_liquidation_order' Liquidation order can't be edited.
337
+ '10047': DDoSProtection, # 'matching_engine_queue_full' Reached limit of pending Matching Engine requests for user.
338
+ '10048': ExchangeError, # 'not_on_self_server' The requested operation is not available on self server.
339
+ '11008': InvalidOrder, # 'already_filled' This request is not allowed in regards to the filled order.
340
+ '11029': BadRequest, # 'invalid_arguments' Some invalid input has been detected.
341
+ '11030': ExchangeError, # 'other_reject <Reason>' Some rejects which are not considered often, more info may be specified in <Reason>.
342
+ '11031': ExchangeError, # 'other_error <Error>' Some errors which are not considered often, more info may be specified in <Error>.
343
+ '11035': DDoSProtection, # 'no_more_stops <Limit>' Allowed amount of stop orders has been exceeded.
344
+ '11036': InvalidOrder, # 'invalid_stoppx_for_index_or_last' Invalid StopPx(too high or too low) current index or market.
345
+ '11037': BadRequest, # 'outdated_instrument_for_IV_order' Instrument already not available for trading.
346
+ '11038': InvalidOrder, # 'no_adv_for_futures' Advanced orders are not available for futures.
347
+ '11039': InvalidOrder, # 'no_adv_postonly' Advanced post-only orders are not supported yet.
348
+ '11041': InvalidOrder, # 'not_adv_order' Advanced order properties can't be set if the order is not advanced.
349
+ '11042': PermissionDenied, # 'permission_denied' Permission for the operation has been denied.
350
+ '11043': BadRequest, # 'bad_argument' Bad argument has been passed.
351
+ '11044': InvalidOrder, # 'not_open_order' Attempt to do open order operations with the not open order.
352
+ '11045': BadRequest, # 'invalid_event' Event name has not been recognized.
353
+ '11046': BadRequest, # 'outdated_instrument' At several minutes to instrument expiration, corresponding advanced implied volatility orders are not allowed.
354
+ '11047': BadRequest, # 'unsupported_arg_combination' The specified combination of arguments is not supported.
355
+ '11048': ExchangeError, # 'wrong_max_show_for_option' Wrong Max Show for options.
356
+ '11049': BadRequest, # 'bad_arguments' Several bad arguments have been passed.
357
+ '11050': BadRequest, # 'bad_request' Request has not been parsed properly.
358
+ '11051': OnMaintenance, # 'system_maintenance' System is under maintenance.
359
+ '11052': ExchangeError, # 'subscribe_error_unsubscribed' Subscription error. However, subscription may fail without self error, please check list of subscribed channels returned, channels can be not subscribed due to wrong input or lack of permissions.
360
+ '11053': ExchangeError, # 'transfer_not_found' Specified transfer is not found.
361
+ '11090': InvalidAddress, # 'invalid_addr' Invalid address.
362
+ '11091': InvalidAddress, # 'invalid_transfer_address' Invalid addres for the transfer.
363
+ '11092': InvalidAddress, # 'address_already_exist' The address already exists.
364
+ '11093': DDoSProtection, # 'max_addr_count_exceeded' Limit of allowed addresses has been reached.
365
+ '11094': ExchangeError, # 'internal_server_error' Some unhandled error on server. Please report to admin. The details of the request will help to locate the problem.
366
+ '11095': ExchangeError, # 'disabled_deposit_address_creation' Deposit address creation has been disabled by admin.
367
+ '11096': ExchangeError, # 'address_belongs_to_user' Withdrawal instead of transfer.
368
+ '12000': AuthenticationError, # 'bad_tfa' Wrong TFA code
369
+ '12001': DDoSProtection, # 'too_many_subaccounts' Limit of subbacounts is reached.
370
+ '12002': ExchangeError, # 'wrong_subaccount_name' The input is not allowed of subaccount.
371
+ '12998': AuthenticationError, # 'tfa_over_limit' The number of failed TFA attempts is limited.
372
+ '12003': AuthenticationError, # 'login_over_limit' The number of failed login attempts is limited.
373
+ '12004': AuthenticationError, # 'registration_over_limit' The number of registration requests is limited.
374
+ '12005': AuthenticationError, # 'country_is_banned' The country is banned(possibly via IP check).
375
+ '12100': ExchangeError, # 'transfer_not_allowed' Transfer is not allowed. Possible wrong direction or other mistake.
376
+ '12999': AuthenticationError, # 'tfa_used' TFA code is correct but it is already used. Please, use next code.
377
+ '13000': AuthenticationError, # 'invalid_login' Login name is invalid(not allowed or it contains wrong characters).
378
+ '13001': AuthenticationError, # 'account_not_activated' Account must be activated.
379
+ '13002': PermissionDenied, # 'account_blocked' Account is blocked by admin.
380
+ '13003': AuthenticationError, # 'tfa_required' This action requires TFA authentication.
381
+ '13004': AuthenticationError, # 'invalid_credentials' Invalid credentials has been used.
382
+ '13005': AuthenticationError, # 'pwd_match_error' Password confirmation error.
383
+ '13006': AuthenticationError, # 'security_error' Invalid Security Code.
384
+ '13007': AuthenticationError, # 'user_not_found' User's security code has been changed or wrong.
385
+ '13008': ExchangeError, # 'request_failed' Request failed because of invalid input or internal failure.
386
+ '13009': AuthenticationError, # 'unauthorized' Wrong or expired authorization token or bad signature. For example, please check scope of the token, 'connection' scope can't be reused for other connections.
387
+ '13010': BadRequest, # 'value_required' Invalid input, missing value.
388
+ '13011': BadRequest, # 'value_too_short' Input is too short.
389
+ '13012': PermissionDenied, # 'unavailable_in_subaccount' Subaccount restrictions.
390
+ '13013': BadRequest, # 'invalid_phone_number' Unsupported or invalid phone number.
391
+ '13014': BadRequest, # 'cannot_send_sms' SMS sending failed -- phone number is wrong.
392
+ '13015': BadRequest, # 'invalid_sms_code' Invalid SMS code.
393
+ '13016': BadRequest, # 'invalid_input' Invalid input.
394
+ '13017': ExchangeError, # 'subscription_failed' Subscription hailed, invalid subscription parameters.
395
+ '13018': ExchangeError, # 'invalid_content_type' Invalid content type of the request.
396
+ '13019': ExchangeError, # 'orderbook_closed' Closed, expired order book.
397
+ '13020': ExchangeError, # 'not_found' Instrument is not found, invalid instrument name.
398
+ '13021': PermissionDenied, # 'forbidden' Not enough permissions to execute the request, forbidden.
399
+ '13025': ExchangeError, # 'method_switched_off_by_admin' API method temporarily switched off by administrator.
400
+ '-32602': BadRequest, # 'Invalid params' see JSON-RPC spec.
401
+ '-32601': BadRequest, # 'Method not found' see JSON-RPC spec.
402
+ '-32700': BadRequest, # 'Parse error' see JSON-RPC spec.
403
+ '-32000': BadRequest, # 'Missing params' see JSON-RPC spec.
404
+ '11054': InvalidOrder, # 'post_only_reject' post order would be filled immediately
405
+ },
406
+ 'precisionMode': TICK_SIZE,
407
+ 'options': {
408
+ 'code': 'BTC',
409
+ 'fetchBalance': {
410
+ 'code': 'BTC',
411
+ },
412
+ 'fetchPositions': {
413
+ 'code': 'BTC',
414
+ },
415
+ 'transfer': {
416
+ 'method': 'privateGetSubmitTransferToSubaccount', # or 'privateGetSubmitTransferToUser'
417
+ },
418
+ },
419
+ })
420
+
421
+ def create_expired_option_market(self, symbol: str):
422
+ # support expired option contracts
423
+ quote = 'USD'
424
+ settle = None
425
+ optionParts = symbol.split('-')
426
+ symbolBase = symbol.split('/')
427
+ base = None
428
+ expiry = None
429
+ if symbol.find('/') > -1:
430
+ base = self.safe_string(symbolBase, 0)
431
+ expiry = self.safe_string(optionParts, 1)
432
+ if symbol.find('USDC') > -1:
433
+ base = base + '_USDC'
434
+ else:
435
+ base = self.safe_string(optionParts, 0)
436
+ expiry = self.convert_market_id_expire_date(self.safe_string(optionParts, 1))
437
+ if symbol.find('USDC') > -1:
438
+ quote = 'USDC'
439
+ settle = 'USDC'
440
+ else:
441
+ settle = base
442
+ splitBase = base
443
+ if base.find('_') > -1:
444
+ splitSymbol = base.split('_')
445
+ splitBase = self.safe_string(splitSymbol, 0)
446
+ strike = self.safe_string(optionParts, 2)
447
+ optionType = self.safe_string(optionParts, 3)
448
+ datetime = self.convert_expire_date(expiry)
449
+ timestamp = self.parse8601(datetime)
450
+ return {
451
+ 'id': base + '-' + self.convert_expire_date_to_market_id_date(expiry) + '-' + strike + '-' + optionType,
452
+ 'symbol': splitBase + '/' + quote + ':' + settle + '-' + expiry + '-' + strike + '-' + optionType,
453
+ 'base': base,
454
+ 'quote': quote,
455
+ 'settle': settle,
456
+ 'baseId': base,
457
+ 'quoteId': quote,
458
+ 'settleId': settle,
459
+ 'active': False,
460
+ 'type': 'option',
461
+ 'linear': None,
462
+ 'inverse': None,
463
+ 'spot': False,
464
+ 'swap': False,
465
+ 'future': False,
466
+ 'option': True,
467
+ 'margin': False,
468
+ 'contract': True,
469
+ 'contractSize': None,
470
+ 'expiry': timestamp,
471
+ 'expiryDatetime': datetime,
472
+ 'optionType': 'call' if (optionType == 'C') else 'put',
473
+ 'strike': self.parse_number(strike),
474
+ 'precision': {
475
+ 'amount': None,
476
+ 'price': None,
477
+ },
478
+ 'limits': {
479
+ 'amount': {
480
+ 'min': None,
481
+ 'max': None,
482
+ },
483
+ 'price': {
484
+ 'min': None,
485
+ 'max': None,
486
+ },
487
+ 'cost': {
488
+ 'min': None,
489
+ 'max': None,
490
+ },
491
+ },
492
+ 'info': None,
493
+ }
494
+
495
+ def safe_market(self, marketId: Str = None, market: Market = None, delimiter: Str = None, marketType: Str = None) -> MarketInterface:
496
+ isOption = (marketId is not None) and ((marketId.endswith('-C')) or (marketId.endswith('-P')))
497
+ if isOption and not (marketId in self.markets_by_id):
498
+ # handle expired option contracts
499
+ return self.create_expired_option_market(marketId)
500
+ return super(deribit, self).safe_market(marketId, market, delimiter, marketType)
501
+
502
+ def fetch_time(self, params={}):
503
+ """
504
+ fetches the current integer timestamp in milliseconds from the exchange server
505
+ :see: https://docs.deribit.com/#public-get_time
506
+ :param dict [params]: extra parameters specific to the exchange API endpoint
507
+ :returns int: the current integer timestamp in milliseconds from the exchange server
508
+ """
509
+ response = self.publicGetGetTime(params)
510
+ #
511
+ # {
512
+ # "jsonrpc": "2.0",
513
+ # "result": 1583922446019,
514
+ # "usIn": 1583922446019955,
515
+ # "usOut": 1583922446019956,
516
+ # "usDiff": 1,
517
+ # "testnet": False
518
+ # }
519
+ #
520
+ return self.safe_integer(response, 'result')
521
+
522
+ def fetch_currencies(self, params={}) -> Currencies:
523
+ """
524
+ fetches all available currencies on an exchange
525
+ :see: https://docs.deribit.com/#public-get_currencies
526
+ :param dict [params]: extra parameters specific to the exchange API endpoint
527
+ :returns dict: an associative dictionary of currencies
528
+ """
529
+ response = self.publicGetGetCurrencies(params)
530
+ #
531
+ # {
532
+ # "jsonrpc": "2.0",
533
+ # "result": [
534
+ # {
535
+ # "withdrawal_priorities": [],
536
+ # "withdrawal_fee": 0.01457324,
537
+ # "min_withdrawal_fee": 0.000001,
538
+ # "min_confirmations": 1,
539
+ # "fee_precision": 8,
540
+ # "currency_long": "Solana",
541
+ # "currency": "SOL",
542
+ # "coin_type": "SOL"
543
+ # },
544
+ # ...
545
+ # ],
546
+ # "usIn": 1688652701456124,
547
+ # "usOut": 1688652701456390,
548
+ # "usDiff": 266,
549
+ # "testnet": True
550
+ # }
551
+ #
552
+ data = self.safe_value(response, 'result', {})
553
+ result: dict = {}
554
+ for i in range(0, len(data)):
555
+ currency = data[i]
556
+ currencyId = self.safe_string(currency, 'currency')
557
+ code = self.safe_currency_code(currencyId)
558
+ name = self.safe_string(currency, 'currency_long')
559
+ result[code] = {
560
+ 'info': currency,
561
+ 'code': code,
562
+ 'id': currencyId,
563
+ 'name': name,
564
+ 'active': None,
565
+ 'deposit': None,
566
+ 'withdraw': None,
567
+ 'fee': self.safe_number(currency, 'withdrawal_fee'),
568
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(currency, 'fee_precision'))),
569
+ 'limits': {
570
+ 'amount': {
571
+ 'min': None,
572
+ 'max': None,
573
+ },
574
+ 'withdraw': {
575
+ 'min': None,
576
+ 'max': None,
577
+ },
578
+ 'deposit': {
579
+ 'min': None,
580
+ 'max': None,
581
+ },
582
+ },
583
+ 'networks': None,
584
+ }
585
+ return result
586
+
587
+ def code_from_options(self, methodName, params={}):
588
+ defaultCode = self.safe_value(self.options, 'code', 'BTC')
589
+ options = self.safe_value(self.options, methodName, {})
590
+ code = self.safe_value(options, 'code', defaultCode)
591
+ return self.safe_value(params, 'code', code)
592
+
593
+ def fetch_status(self, params={}):
594
+ """
595
+ the latest known information on the availability of the exchange API
596
+ :see: https://docs.deribit.com/#public-status
597
+ :param dict [params]: extra parameters specific to the exchange API endpoint
598
+ :returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
599
+ """
600
+ response = self.publicGetStatus(params)
601
+ #
602
+ # {
603
+ # "jsonrpc": "2.0",
604
+ # "result": {
605
+ # "locked": "false" # True, partial, False
606
+ # },
607
+ # "usIn": 1650641690226788,
608
+ # "usOut": 1650641690226836,
609
+ # "usDiff": 48,
610
+ # "testnet": False
611
+ # }
612
+ #
613
+ result = self.safe_value(response, 'result')
614
+ locked = self.safe_string(result, 'locked')
615
+ updateTime = self.safe_integer_product(response, 'usIn', 0.001, self.milliseconds())
616
+ return {
617
+ 'status': 'ok' if (locked == 'false') else 'maintenance',
618
+ 'updated': updateTime,
619
+ 'eta': None,
620
+ 'url': None,
621
+ 'info': response,
622
+ }
623
+
624
+ def fetch_accounts(self, params={}) -> List[Account]:
625
+ """
626
+ fetch all the accounts associated with a profile
627
+ :see: https://docs.deribit.com/#private-get_subaccounts
628
+ :param dict [params]: extra parameters specific to the exchange API endpoint
629
+ :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
630
+ """
631
+ self.load_markets()
632
+ response = self.privateGetGetSubaccounts(params)
633
+ #
634
+ # {
635
+ # "jsonrpc": "2.0",
636
+ # "result": [{
637
+ # "username": "someusername",
638
+ # "type": "main",
639
+ # "system_name": "someusername",
640
+ # "security_keys_enabled": False,
641
+ # "security_keys_assignments": [],
642
+ # "receive_notifications": False,
643
+ # "login_enabled": True,
644
+ # "is_password": True,
645
+ # "id": "238216",
646
+ # "email": "pablo@abcdef.com"
647
+ # },
648
+ # {
649
+ # "username": "someusername_1",
650
+ # "type": "subaccount",
651
+ # "system_name": "someusername_1",
652
+ # "security_keys_enabled": False,
653
+ # "security_keys_assignments": [],
654
+ # "receive_notifications": False,
655
+ # "login_enabled": False,
656
+ # "is_password": False,
657
+ # "id": "245499",
658
+ # "email": "pablo@abcdef.com"
659
+ # }
660
+ # ],
661
+ # "usIn": "1652736468292006",
662
+ # "usOut": "1652736468292377",
663
+ # "usDiff": "371",
664
+ # "testnet": False
665
+ # }
666
+ #
667
+ result = self.safe_value(response, 'result', [])
668
+ return self.parse_accounts(result)
669
+
670
+ def parse_account(self, account, currency: Currency = None):
671
+ #
672
+ # {
673
+ # "username": "someusername_1",
674
+ # "type": "subaccount",
675
+ # "system_name": "someusername_1",
676
+ # "security_keys_enabled": False,
677
+ # "security_keys_assignments": [],
678
+ # "receive_notifications": False,
679
+ # "login_enabled": False,
680
+ # "is_password": False,
681
+ # "id": "245499",
682
+ # "email": "pablo@abcdef.com"
683
+ # }
684
+ #
685
+ return {
686
+ 'info': account,
687
+ 'id': self.safe_string(account, 'id'),
688
+ 'type': self.safe_string(account, 'type'),
689
+ 'code': self.safe_currency_code(None, currency),
690
+ }
691
+
692
+ def fetch_markets(self, params={}) -> List[Market]:
693
+ """
694
+ retrieves data on all markets for deribit
695
+ :see: https://docs.deribit.com/#public-get_currencies
696
+ :see: https://docs.deribit.com/#public-get_instruments
697
+ :param dict [params]: extra parameters specific to the exchange API endpoint
698
+ :returns dict[]: an array of objects representing market data
699
+ """
700
+ instrumentsResponses = []
701
+ result = []
702
+ parsedMarkets: dict = {}
703
+ fetchAllMarkets = None
704
+ fetchAllMarkets, params = self.handle_option_and_params(params, 'fetchMarkets', 'fetchAllMarkets', True)
705
+ if fetchAllMarkets:
706
+ instrumentsResponse = self.publicGetGetInstruments(params)
707
+ instrumentsResponses.append(instrumentsResponse)
708
+ else:
709
+ currenciesResponse = self.publicGetGetCurrencies(params)
710
+ #
711
+ # {
712
+ # "jsonrpc": "2.0",
713
+ # "result": [
714
+ # {
715
+ # "withdrawal_priorities": [
716
+ # {value: 0.15, name: "very_low"},
717
+ # {value: 1.5, name: "very_high"},
718
+ # ],
719
+ # "withdrawal_fee": 0.0005,
720
+ # "min_withdrawal_fee": 0.0005,
721
+ # "min_confirmations": 1,
722
+ # "fee_precision": 4,
723
+ # "currency_long": "Bitcoin",
724
+ # "currency": "BTC",
725
+ # "coin_type": "BITCOIN"
726
+ # }
727
+ # ],
728
+ # "usIn": 1583761588590479,
729
+ # "usOut": 1583761588590544,
730
+ # "usDiff": 65,
731
+ # "testnet": False
732
+ # }
733
+ #
734
+ currenciesResult = self.safe_value(currenciesResponse, 'result', [])
735
+ for i in range(0, len(currenciesResult)):
736
+ currencyId = self.safe_string(currenciesResult[i], 'currency')
737
+ request: dict = {
738
+ 'currency': currencyId,
739
+ }
740
+ instrumentsResponse = self.publicGetGetInstruments(self.extend(request, params))
741
+ #
742
+ # {
743
+ # "jsonrpc":"2.0",
744
+ # "result":[
745
+ # {
746
+ # "tick_size":0.0005,
747
+ # "taker_commission":0.0003,
748
+ # "strike":52000.0,
749
+ # "settlement_period":"month",
750
+ # "settlement_currency":"BTC",
751
+ # "quote_currency":"BTC",
752
+ # "option_type":"put", # put, call
753
+ # "min_trade_amount":0.1,
754
+ # "maker_commission":0.0003,
755
+ # "kind":"option",
756
+ # "is_active":true,
757
+ # "instrument_name":"BTC-24JUN22-52000-P",
758
+ # "expiration_timestamp":1656057600000,
759
+ # "creation_timestamp":1648199543000,
760
+ # "counter_currency":"USD",
761
+ # "contract_size":1.0,
762
+ # "block_trade_commission":0.0003,
763
+ # "base_currency":"BTC"
764
+ # },
765
+ # {
766
+ # "tick_size":0.5,
767
+ # "taker_commission":0.0005,
768
+ # "settlement_period":"month", # month, week
769
+ # "settlement_currency":"BTC",
770
+ # "quote_currency":"USD",
771
+ # "min_trade_amount":10.0,
772
+ # "max_liquidation_commission":0.0075,
773
+ # "max_leverage":50,
774
+ # "maker_commission":0.0,
775
+ # "kind":"future",
776
+ # "is_active":true,
777
+ # "instrument_name":"BTC-27MAY22",
778
+ # "future_type":"reversed",
779
+ # "expiration_timestamp":1653638400000,
780
+ # "creation_timestamp":1648195209000,
781
+ # "counter_currency":"USD",
782
+ # "contract_size":10.0,
783
+ # "block_trade_commission":0.0001,
784
+ # "base_currency":"BTC"
785
+ # },
786
+ # {
787
+ # "tick_size":0.5,
788
+ # "taker_commission":0.0005,
789
+ # "settlement_period":"perpetual",
790
+ # "settlement_currency":"BTC",
791
+ # "quote_currency":"USD",
792
+ # "min_trade_amount":10.0,
793
+ # "max_liquidation_commission":0.0075,
794
+ # "max_leverage":50,
795
+ # "maker_commission":0.0,
796
+ # "kind":"future",
797
+ # "is_active":true,
798
+ # "instrument_name":"BTC-PERPETUAL",
799
+ # "future_type":"reversed",
800
+ # "expiration_timestamp":32503708800000,
801
+ # "creation_timestamp":1534242287000,
802
+ # "counter_currency":"USD",
803
+ # "contract_size":10.0,
804
+ # "block_trade_commission":0.0001,
805
+ # "base_currency":"BTC"
806
+ # },
807
+ # ],
808
+ # "usIn":1648691472831791,
809
+ # "usOut":1648691472831896,
810
+ # "usDiff":105,
811
+ # "testnet":false
812
+ # }
813
+ #
814
+ instrumentsResponses.append(instrumentsResponse)
815
+ for i in range(0, len(instrumentsResponses)):
816
+ instrumentsResult = self.safe_value(instrumentsResponses[i], 'result', [])
817
+ for k in range(0, len(instrumentsResult)):
818
+ market = instrumentsResult[k]
819
+ kind = self.safe_string(market, 'kind')
820
+ isSpot = (kind == 'spot')
821
+ id = self.safe_string(market, 'instrument_name')
822
+ baseId = self.safe_string(market, 'base_currency')
823
+ quoteId = self.safe_string(market, 'counter_currency')
824
+ settleId = self.safe_string(market, 'settlement_currency')
825
+ base = self.safe_currency_code(baseId)
826
+ quote = self.safe_currency_code(quoteId)
827
+ settle = self.safe_currency_code(settleId)
828
+ settlementPeriod = self.safe_value(market, 'settlement_period')
829
+ swap = (settlementPeriod == 'perpetual')
830
+ future = not swap and (kind.find('future') >= 0)
831
+ option = (kind.find('option') >= 0)
832
+ isComboMarket = kind.find('combo') >= 0
833
+ expiry = self.safe_integer(market, 'expiration_timestamp')
834
+ strike = None
835
+ optionType = None
836
+ symbol = id
837
+ type = 'swap'
838
+ if future:
839
+ type = 'future'
840
+ elif option:
841
+ type = 'option'
842
+ elif isSpot:
843
+ type = 'spot'
844
+ if isSpot:
845
+ symbol = base + '/' + quote
846
+ elif not isComboMarket:
847
+ symbol = base + '/' + quote + ':' + settle
848
+ if option or future:
849
+ symbol = symbol + '-' + self.yymmdd(expiry, '')
850
+ if option:
851
+ strike = self.safe_number(market, 'strike')
852
+ optionType = self.safe_string(market, 'option_type')
853
+ letter = 'C' if (optionType == 'call') else 'P'
854
+ symbol = symbol + '-' + self.number_to_string(strike) + '-' + letter
855
+ parsedMarketValue = self.safe_value(parsedMarkets, symbol)
856
+ if parsedMarketValue:
857
+ continue
858
+ parsedMarkets[symbol] = True
859
+ minTradeAmount = self.safe_number(market, 'min_trade_amount')
860
+ tickSize = self.safe_number(market, 'tick_size')
861
+ result.append({
862
+ 'id': id,
863
+ 'symbol': symbol,
864
+ 'base': base,
865
+ 'quote': quote,
866
+ 'settle': settle,
867
+ 'baseId': baseId,
868
+ 'quoteId': quoteId,
869
+ 'settleId': settleId,
870
+ 'type': type,
871
+ 'spot': isSpot,
872
+ 'margin': False,
873
+ 'swap': swap,
874
+ 'future': future,
875
+ 'option': option,
876
+ 'active': self.safe_value(market, 'is_active'),
877
+ 'contract': not isSpot,
878
+ 'linear': (settle == quote),
879
+ 'inverse': (settle != quote),
880
+ 'taker': self.safe_number(market, 'taker_commission'),
881
+ 'maker': self.safe_number(market, 'maker_commission'),
882
+ 'contractSize': self.safe_number(market, 'contract_size'),
883
+ 'expiry': expiry,
884
+ 'expiryDatetime': self.iso8601(expiry),
885
+ 'strike': strike,
886
+ 'optionType': optionType,
887
+ 'precision': {
888
+ 'amount': minTradeAmount,
889
+ 'price': tickSize,
890
+ },
891
+ 'limits': {
892
+ 'leverage': {
893
+ 'min': None,
894
+ 'max': None,
895
+ },
896
+ 'amount': {
897
+ 'min': minTradeAmount,
898
+ 'max': None,
899
+ },
900
+ 'price': {
901
+ 'min': tickSize,
902
+ 'max': None,
903
+ },
904
+ 'cost': {
905
+ 'min': None,
906
+ 'max': None,
907
+ },
908
+ },
909
+ 'created': self.safe_integer(market, 'creation_timestamp'),
910
+ 'info': market,
911
+ })
912
+ return result
913
+
914
+ def parse_balance(self, balance) -> Balances:
915
+ result: dict = {
916
+ 'info': balance,
917
+ }
918
+ currencyId = self.safe_string(balance, 'currency')
919
+ currencyCode = self.safe_currency_code(currencyId)
920
+ account = self.account()
921
+ account['free'] = self.safe_string(balance, 'available_funds')
922
+ account['used'] = self.safe_string(balance, 'maintenance_margin')
923
+ account['total'] = self.safe_string(balance, 'equity')
924
+ result[currencyCode] = account
925
+ return self.safe_balance(result)
926
+
927
+ def fetch_balance(self, params={}) -> Balances:
928
+ """
929
+ query for balance and get the amount of funds available for trading or funds locked in orders
930
+ :see: https://docs.deribit.com/#private-get_account_summary
931
+ :param dict [params]: extra parameters specific to the exchange API endpoint
932
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
933
+ """
934
+ self.load_markets()
935
+ code = self.code_from_options('fetchBalance', params)
936
+ currency = self.currency(code)
937
+ request: dict = {
938
+ 'currency': currency['id'],
939
+ }
940
+ response = self.privateGetGetAccountSummary(self.extend(request, params))
941
+ #
942
+ # {
943
+ # "jsonrpc": "2.0",
944
+ # "result": {
945
+ # "total_pl": 0,
946
+ # "session_upl": 0,
947
+ # "session_rpl": 0,
948
+ # "session_funding": 0,
949
+ # "portfolio_margining_enabled": False,
950
+ # "options_vega": 0,
951
+ # "options_theta": 0,
952
+ # "options_session_upl": 0,
953
+ # "options_session_rpl": 0,
954
+ # "options_pl": 0,
955
+ # "options_gamma": 0,
956
+ # "options_delta": 0,
957
+ # "margin_balance": 0.00062359,
958
+ # "maintenance_margin": 0,
959
+ # "limits": {
960
+ # "non_matching_engine_burst": 300,
961
+ # "non_matching_engine": 200,
962
+ # "matching_engine_burst": 20,
963
+ # "matching_engine": 2
964
+ # },
965
+ # "initial_margin": 0,
966
+ # "futures_session_upl": 0,
967
+ # "futures_session_rpl": 0,
968
+ # "futures_pl": 0,
969
+ # "equity": 0.00062359,
970
+ # "deposit_address": "13tUtNsJSZa1F5GeCmwBywVrymHpZispzw",
971
+ # "delta_total": 0,
972
+ # "currency": "BTC",
973
+ # "balance": 0.00062359,
974
+ # "available_withdrawal_funds": 0.00062359,
975
+ # "available_funds": 0.00062359
976
+ # },
977
+ # "usIn": 1583775838115975,
978
+ # "usOut": 1583775838116520,
979
+ # "usDiff": 545,
980
+ # "testnet": False
981
+ # }
982
+ #
983
+ result = self.safe_value(response, 'result', {})
984
+ return self.parse_balance(result)
985
+
986
+ def create_deposit_address(self, code: str, params={}):
987
+ """
988
+ create a currency deposit address
989
+ :see: https://docs.deribit.com/#private-create_deposit_address
990
+ :param str code: unified currency code of the currency for the deposit address
991
+ :param dict [params]: extra parameters specific to the exchange API endpoint
992
+ :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
993
+ """
994
+ self.load_markets()
995
+ currency = self.currency(code)
996
+ request: dict = {
997
+ 'currency': currency['id'],
998
+ }
999
+ response = self.privateGetCreateDepositAddress(self.extend(request, params))
1000
+ #
1001
+ # {
1002
+ # "jsonrpc": "2.0",
1003
+ # "id": 7538,
1004
+ # "result": {
1005
+ # "address": "2N8udZGBc1hLRCFsU9kGwMPpmYUwMFTuCwB",
1006
+ # "creation_timestamp": 1550575165170,
1007
+ # "currency": "BTC",
1008
+ # "type": "deposit"
1009
+ # }
1010
+ # }
1011
+ #
1012
+ result = self.safe_value(response, 'result', {})
1013
+ address = self.safe_string(result, 'address')
1014
+ self.check_address(address)
1015
+ return {
1016
+ 'currency': code,
1017
+ 'address': address,
1018
+ 'tag': None,
1019
+ 'info': response,
1020
+ }
1021
+
1022
+ def fetch_deposit_address(self, code: str, params={}):
1023
+ """
1024
+ fetch the deposit address for a currency associated with self account
1025
+ :see: https://docs.deribit.com/#private-get_current_deposit_address
1026
+ :param str code: unified currency code
1027
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1028
+ :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
1029
+ """
1030
+ self.load_markets()
1031
+ currency = self.currency(code)
1032
+ request: dict = {
1033
+ 'currency': currency['id'],
1034
+ }
1035
+ response = self.privateGetGetCurrentDepositAddress(self.extend(request, params))
1036
+ #
1037
+ # {
1038
+ # "jsonrpc": "2.0",
1039
+ # "result": {
1040
+ # "type": "deposit",
1041
+ # "status": "ready",
1042
+ # "requires_confirmation": True,
1043
+ # "currency": "BTC",
1044
+ # "creation_timestamp": 1514694684651,
1045
+ # "address": "13tUtNsJSZa1F5GeCmwBywVrymHpZispzw"
1046
+ # },
1047
+ # "usIn": 1583785137274288,
1048
+ # "usOut": 1583785137274454,
1049
+ # "usDiff": 166,
1050
+ # "testnet": False
1051
+ # }
1052
+ #
1053
+ result = self.safe_value(response, 'result', {})
1054
+ address = self.safe_string(result, 'address')
1055
+ self.check_address(address)
1056
+ return {
1057
+ 'currency': code,
1058
+ 'address': address,
1059
+ 'tag': None,
1060
+ 'network': None,
1061
+ 'info': response,
1062
+ }
1063
+
1064
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
1065
+ #
1066
+ # fetchTicker /public/ticker
1067
+ #
1068
+ # {
1069
+ # "timestamp": 1583778859480,
1070
+ # "stats": {volume: 60627.57263769, low: 7631.5, high: 8311.5},
1071
+ # "state": "open",
1072
+ # "settlement_price": 7903.21,
1073
+ # "open_interest": 111543850,
1074
+ # "min_price": 7634,
1075
+ # "max_price": 7866.51,
1076
+ # "mark_price": 7750.02,
1077
+ # "last_price": 7750.5,
1078
+ # "instrument_name": "BTC-PERPETUAL",
1079
+ # "index_price": 7748.01,
1080
+ # "funding_8h": 0.0000026,
1081
+ # "current_funding": 0,
1082
+ # "best_bid_price": 7750,
1083
+ # "best_bid_amount": 19470,
1084
+ # "best_ask_price": 7750.5,
1085
+ # "best_ask_amount": 343280
1086
+ # }
1087
+ #
1088
+ # fetchTicker /public/get_book_summary_by_instrument
1089
+ # fetchTickers /public/get_book_summary_by_currency
1090
+ #
1091
+ # {
1092
+ # "volume": 124.1,
1093
+ # "underlying_price": 7856.445926872601,
1094
+ # "underlying_index": "SYN.BTC-10MAR20",
1095
+ # "quote_currency": "USD",
1096
+ # "open_interest": 121.8,
1097
+ # "mid_price": 0.01975,
1098
+ # "mark_price": 0.01984559,
1099
+ # "low": 0.0095,
1100
+ # "last": 0.0205,
1101
+ # "interest_rate": 0,
1102
+ # "instrument_name": "BTC-10MAR20-7750-C",
1103
+ # "high": 0.0295,
1104
+ # "estimated_delivery_price": 7856.29,
1105
+ # "creation_timestamp": 1583783678366,
1106
+ # "bid_price": 0.0185,
1107
+ # "base_currency": "BTC",
1108
+ # "ask_price": 0.021
1109
+ # },
1110
+ #
1111
+ timestamp = self.safe_integer_2(ticker, 'timestamp', 'creation_timestamp')
1112
+ marketId = self.safe_string(ticker, 'instrument_name')
1113
+ symbol = self.safe_symbol(marketId, market)
1114
+ last = self.safe_string_2(ticker, 'last_price', 'last')
1115
+ stats = self.safe_value(ticker, 'stats', ticker)
1116
+ return self.safe_ticker({
1117
+ 'symbol': symbol,
1118
+ 'timestamp': timestamp,
1119
+ 'datetime': self.iso8601(timestamp),
1120
+ 'high': self.safe_string_2(stats, 'high', 'max_price'),
1121
+ 'low': self.safe_string_2(stats, 'low', 'min_price'),
1122
+ 'bid': self.safe_string_2(ticker, 'best_bid_price', 'bid_price'),
1123
+ 'bidVolume': self.safe_string(ticker, 'best_bid_amount'),
1124
+ 'ask': self.safe_string_2(ticker, 'best_ask_price', 'ask_price'),
1125
+ 'askVolume': self.safe_string(ticker, 'best_ask_amount'),
1126
+ 'vwap': None,
1127
+ 'open': None,
1128
+ 'close': last,
1129
+ 'last': last,
1130
+ 'previousClose': None,
1131
+ 'change': None,
1132
+ 'percentage': None,
1133
+ 'average': None,
1134
+ 'baseVolume': None,
1135
+ 'quoteVolume': self.safe_string(stats, 'volume'),
1136
+ 'info': ticker,
1137
+ }, market)
1138
+
1139
+ def fetch_ticker(self, symbol: str, params={}) -> Ticker:
1140
+ """
1141
+ fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1142
+ :see: https://docs.deribit.com/#public-ticker
1143
+ :param str symbol: unified symbol of the market to fetch the ticker for
1144
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1145
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
1146
+ """
1147
+ self.load_markets()
1148
+ market = self.market(symbol)
1149
+ request: dict = {
1150
+ 'instrument_name': market['id'],
1151
+ }
1152
+ response = self.publicGetTicker(self.extend(request, params))
1153
+ #
1154
+ # {
1155
+ # "jsonrpc": "2.0",
1156
+ # "result": {
1157
+ # "timestamp": 1583778859480,
1158
+ # "stats": {volume: 60627.57263769, low: 7631.5, high: 8311.5},
1159
+ # "state": "open",
1160
+ # "settlement_price": 7903.21,
1161
+ # "open_interest": 111543850,
1162
+ # "min_price": 7634,
1163
+ # "max_price": 7866.51,
1164
+ # "mark_price": 7750.02,
1165
+ # "last_price": 7750.5,
1166
+ # "instrument_name": "BTC-PERPETUAL",
1167
+ # "index_price": 7748.01,
1168
+ # "funding_8h": 0.0000026,
1169
+ # "current_funding": 0,
1170
+ # "best_bid_price": 7750,
1171
+ # "best_bid_amount": 19470,
1172
+ # "best_ask_price": 7750.5,
1173
+ # "best_ask_amount": 343280
1174
+ # },
1175
+ # "usIn": 1583778859483941,
1176
+ # "usOut": 1583778859484075,
1177
+ # "usDiff": 134,
1178
+ # "testnet": False
1179
+ # }
1180
+ #
1181
+ result = self.safe_dict(response, 'result')
1182
+ return self.parse_ticker(result, market)
1183
+
1184
+ def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
1185
+ """
1186
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1187
+ :see: https://docs.deribit.com/#public-get_book_summary_by_currency
1188
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1189
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1190
+ :param str [params.code]: *required* the currency code to fetch the tickers for, eg. 'BTC', 'ETH'
1191
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
1192
+ """
1193
+ self.load_markets()
1194
+ symbols = self.market_symbols(symbols)
1195
+ code = self.safe_string_2(params, 'code', 'currency')
1196
+ params = self.omit(params, ['code'])
1197
+ if code is None:
1198
+ raise ArgumentsRequired(self.id + ' fetchTickers requires a currency/code(eg: BTC/ETH/USDT) parameter to fetch tickers for')
1199
+ currency = self.currency(code)
1200
+ request: dict = {
1201
+ 'currency': currency['id'],
1202
+ }
1203
+ response = self.publicGetGetBookSummaryByCurrency(self.extend(request, params))
1204
+ #
1205
+ # {
1206
+ # "jsonrpc": "2.0",
1207
+ # "result": [
1208
+ # {
1209
+ # "volume": 124.1,
1210
+ # "underlying_price": 7856.445926872601,
1211
+ # "underlying_index": "SYN.BTC-10MAR20",
1212
+ # "quote_currency": "USD",
1213
+ # "open_interest": 121.8,
1214
+ # "mid_price": 0.01975,
1215
+ # "mark_price": 0.01984559,
1216
+ # "low": 0.0095,
1217
+ # "last": 0.0205,
1218
+ # "interest_rate": 0,
1219
+ # "instrument_name": "BTC-10MAR20-7750-C",
1220
+ # "high": 0.0295,
1221
+ # "estimated_delivery_price": 7856.29,
1222
+ # "creation_timestamp": 1583783678366,
1223
+ # "bid_price": 0.0185,
1224
+ # "base_currency": "BTC",
1225
+ # "ask_price": 0.021
1226
+ # },
1227
+ # ],
1228
+ # "usIn": 1583783678361966,
1229
+ # "usOut": 1583783678372069,
1230
+ # "usDiff": 10103,
1231
+ # "testnet": False
1232
+ # }
1233
+ #
1234
+ result = self.safe_list(response, 'result', [])
1235
+ tickers: dict = {}
1236
+ for i in range(0, len(result)):
1237
+ ticker = self.parse_ticker(result[i])
1238
+ symbol = ticker['symbol']
1239
+ tickers[symbol] = ticker
1240
+ return self.filter_by_array_tickers(tickers, 'symbol', symbols)
1241
+
1242
+ def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
1243
+ """
1244
+ fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1245
+ :see: https://docs.deribit.com/#public-get_tradingview_chart_data
1246
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
1247
+ :param str timeframe: the length of time each candle represents
1248
+ :param int [since]: timestamp in ms of the earliest candle to fetch
1249
+ :param int [limit]: the maximum amount of candles to fetch
1250
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1251
+ :param boolean [params.paginate]: whether to paginate the results, set to False by default
1252
+ :param int [params.until]: the latest time in ms to fetch ohlcv for
1253
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
1254
+ """
1255
+ self.load_markets()
1256
+ paginate = False
1257
+ paginate, params = self.handle_option_and_params(params, 'fetchOHLCV', 'paginate')
1258
+ if paginate:
1259
+ return self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 5000)
1260
+ market = self.market(symbol)
1261
+ request: dict = {
1262
+ 'instrument_name': market['id'],
1263
+ 'resolution': self.safe_string(self.timeframes, timeframe, timeframe),
1264
+ }
1265
+ duration = self.parse_timeframe(timeframe)
1266
+ now = self.milliseconds()
1267
+ if since is None:
1268
+ if limit is None:
1269
+ limit = 1000 # at max, it provides 5000 bars, but we set generous default here
1270
+ request['start_timestamp'] = now - (limit - 1) * duration * 1000
1271
+ request['end_timestamp'] = now
1272
+ else:
1273
+ since = max(since - 1, 0)
1274
+ request['start_timestamp'] = since
1275
+ if limit is None:
1276
+ request['end_timestamp'] = now
1277
+ else:
1278
+ request['end_timestamp'] = self.sum(since, limit * duration * 1000)
1279
+ until = self.safe_integer(params, 'until')
1280
+ if until is not None:
1281
+ params = self.omit(params, 'until')
1282
+ request['end_timestamp'] = until
1283
+ response = self.publicGetGetTradingviewChartData(self.extend(request, params))
1284
+ #
1285
+ # {
1286
+ # "jsonrpc": "2.0",
1287
+ # "result": {
1288
+ # "volume": [3.6680847969999992, 22.682721123, 3.011587939, 0],
1289
+ # "ticks": [1583916960000, 1583917020000, 1583917080000, 1583917140000],
1290
+ # "status": "ok",
1291
+ # "open": [7834, 7839, 7833.5, 7833],
1292
+ # "low": [7834, 7833.5, 7832.5, 7833],
1293
+ # "high": [7839.5, 7839, 7833.5, 7833],
1294
+ # "cost": [28740, 177740, 23590, 0],
1295
+ # "close": [7839.5, 7833.5, 7833, 7833]
1296
+ # },
1297
+ # "usIn": 1583917166709801,
1298
+ # "usOut": 1583917166710175,
1299
+ # "usDiff": 374,
1300
+ # "testnet": False
1301
+ # }
1302
+ #
1303
+ result = self.safe_value(response, 'result', {})
1304
+ ohlcvs = self.convert_trading_view_to_ohlcv(result, 'ticks', 'open', 'high', 'low', 'close', 'volume', True)
1305
+ return self.parse_ohlcvs(ohlcvs, market, timeframe, since, limit)
1306
+
1307
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
1308
+ #
1309
+ # fetchTrades(public)
1310
+ #
1311
+ # {
1312
+ # "trade_seq":132564271,
1313
+ # "trade_id":"195402220",
1314
+ # "timestamp":1639684927932,
1315
+ # "tick_direction":0,
1316
+ # "price":47946.5,
1317
+ # "mark_price":47944.13,
1318
+ # "instrument_name":"BTC-PERPETUAL",
1319
+ # "index_price":47925.45,
1320
+ # "direction":"buy",
1321
+ # "amount":580.0
1322
+ # }
1323
+ #
1324
+ #
1325
+ # fetchMyTrades, fetchOrderTrades(private)
1326
+ #
1327
+ # {
1328
+ # "trade_seq": 3,
1329
+ # "trade_id": "ETH-34066",
1330
+ # "timestamp": 1550219814585,
1331
+ # "tick_direction": 1,
1332
+ # "state": "open",
1333
+ # "self_trade": False,
1334
+ # "reduce_only": False,
1335
+ # "price": 0.04,
1336
+ # "post_only": False,
1337
+ # "order_type": "limit",
1338
+ # "order_id": "ETH-334607",
1339
+ # "matching_id": null,
1340
+ # "liquidity": "M",
1341
+ # "iv": 56.83,
1342
+ # "instrument_name": "ETH-22FEB19-120-C",
1343
+ # "index_price": 121.37,
1344
+ # "fee_currency": "ETH",
1345
+ # "fee": 0.0011,
1346
+ # "direction": "buy",
1347
+ # "amount": 11
1348
+ # }
1349
+ #
1350
+ id = self.safe_string(trade, 'trade_id')
1351
+ marketId = self.safe_string(trade, 'instrument_name')
1352
+ symbol = self.safe_symbol(marketId, market)
1353
+ timestamp = self.safe_integer(trade, 'timestamp')
1354
+ side = self.safe_string(trade, 'direction')
1355
+ priceString = self.safe_string(trade, 'price')
1356
+ market = self.safe_market(marketId, market)
1357
+ # Amount for inverse perpetual and futures is in USD which in ccxt is the cost
1358
+ # For options amount and linear is in corresponding cryptocurrency contracts, e.g., BTC or ETH
1359
+ amount = self.safe_string(trade, 'amount')
1360
+ cost = Precise.string_mul(amount, priceString)
1361
+ if market['inverse']:
1362
+ cost = Precise.string_div(amount, priceString)
1363
+ liquidity = self.safe_string(trade, 'liquidity')
1364
+ takerOrMaker = None
1365
+ if liquidity is not None:
1366
+ # M = maker, T = taker, MT = both
1367
+ takerOrMaker = 'maker' if (liquidity == 'M') else 'taker'
1368
+ feeCostString = self.safe_string(trade, 'fee')
1369
+ fee = None
1370
+ if feeCostString is not None:
1371
+ feeCurrencyId = self.safe_string(trade, 'fee_currency')
1372
+ feeCurrencyCode = self.safe_currency_code(feeCurrencyId)
1373
+ fee = {
1374
+ 'cost': feeCostString,
1375
+ 'currency': feeCurrencyCode,
1376
+ }
1377
+ return self.safe_trade({
1378
+ 'id': id,
1379
+ 'info': trade,
1380
+ 'timestamp': timestamp,
1381
+ 'datetime': self.iso8601(timestamp),
1382
+ 'symbol': symbol,
1383
+ 'order': self.safe_string(trade, 'order_id'),
1384
+ 'type': self.safe_string(trade, 'order_type'),
1385
+ 'side': side,
1386
+ 'takerOrMaker': takerOrMaker,
1387
+ 'price': priceString,
1388
+ 'amount': amount,
1389
+ 'cost': cost,
1390
+ 'fee': fee,
1391
+ }, market)
1392
+
1393
+ def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
1394
+ """
1395
+ :see: https://docs.deribit.com/#public-get_last_trades_by_instrument
1396
+ :see: https://docs.deribit.com/#public-get_last_trades_by_instrument_and_time
1397
+ get the list of most recent trades for a particular symbol.
1398
+ :param str symbol: unified symbol of the market to fetch trades for
1399
+ :param int [since]: timestamp in ms of the earliest trade to fetch
1400
+ :param int [limit]: the maximum amount of trades to fetch
1401
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1402
+ :param int [params.until]: the latest time in ms to fetch trades for
1403
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
1404
+ """
1405
+ self.load_markets()
1406
+ market = self.market(symbol)
1407
+ request: dict = {
1408
+ 'instrument_name': market['id'],
1409
+ 'include_old': True,
1410
+ }
1411
+ if since is not None:
1412
+ request['start_timestamp'] = since
1413
+ if limit is not None:
1414
+ request['count'] = min(limit, 1000) # default 10
1415
+ until = self.safe_integer_2(params, 'until', 'end_timestamp')
1416
+ if until is not None:
1417
+ params = self.omit(params, ['until'])
1418
+ request['end_timestamp'] = until
1419
+ response = None
1420
+ if (since is None) and not ('end_timestamp' in request):
1421
+ response = self.publicGetGetLastTradesByInstrument(self.extend(request, params))
1422
+ else:
1423
+ response = self.publicGetGetLastTradesByInstrumentAndTime(self.extend(request, params))
1424
+ #
1425
+ # {
1426
+ # "jsonrpc":"2.0",
1427
+ # "result": {
1428
+ # "trades": [
1429
+ # {
1430
+ # "trade_seq":132564271,
1431
+ # "trade_id":"195402220",
1432
+ # "timestamp":1639684927932,
1433
+ # "tick_direction":0,
1434
+ # "price":47946.5,
1435
+ # "mark_price":47944.13,
1436
+ # "instrument_name":"BTC-PERPETUAL",
1437
+ # "index_price":47925.45,
1438
+ # "direction":"buy","amount":580.0
1439
+ # }
1440
+ # ],
1441
+ # "has_more":true
1442
+ # },
1443
+ # "usIn":1639684931934671,
1444
+ # "usOut":1639684931935337,
1445
+ # "usDiff":666,
1446
+ # "testnet":false
1447
+ # }
1448
+ #
1449
+ result = self.safe_value(response, 'result', {})
1450
+ trades = self.safe_list(result, 'trades', [])
1451
+ return self.parse_trades(trades, market, since, limit)
1452
+
1453
+ def fetch_trading_fees(self, params={}) -> TradingFees:
1454
+ """
1455
+ fetch the trading fees for multiple markets
1456
+ :see: https://docs.deribit.com/#private-get_account_summary
1457
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1458
+ :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
1459
+ """
1460
+ self.load_markets()
1461
+ code = self.code_from_options('fetchTradingFees', params)
1462
+ currency = self.currency(code)
1463
+ request: dict = {
1464
+ 'currency': currency['id'],
1465
+ 'extended': True,
1466
+ }
1467
+ response = self.privateGetGetAccountSummary(self.extend(request, params))
1468
+ #
1469
+ # {
1470
+ # "jsonrpc": "2.0",
1471
+ # "result": {
1472
+ # "total_pl": 0,
1473
+ # "session_upl": 0,
1474
+ # "session_rpl": 0,
1475
+ # "session_funding": 0,
1476
+ # "portfolio_margining_enabled": False,
1477
+ # "options_vega": 0,
1478
+ # "options_theta": 0,
1479
+ # "options_session_upl": 0,
1480
+ # "options_session_rpl": 0,
1481
+ # "options_pl": 0,
1482
+ # "options_gamma": 0,
1483
+ # "options_delta": 0,
1484
+ # "margin_balance": 0.00062359,
1485
+ # "maintenance_margin": 0,
1486
+ # "limits": {
1487
+ # "non_matching_engine_burst": 300,
1488
+ # "non_matching_engine": 200,
1489
+ # "matching_engine_burst": 20,
1490
+ # "matching_engine": 2
1491
+ # },
1492
+ # "initial_margin": 0,
1493
+ # "futures_session_upl": 0,
1494
+ # "futures_session_rpl": 0,
1495
+ # "futures_pl": 0,
1496
+ # "equity": 0.00062359,
1497
+ # "deposit_address": "13tUtNsJSZa1F5GeCmwBywVrymHpZispzw",
1498
+ # "delta_total": 0,
1499
+ # "currency": "BTC",
1500
+ # "balance": 0.00062359,
1501
+ # "available_withdrawal_funds": 0.00062359,
1502
+ # "available_funds": 0.00062359,
1503
+ # "fees": [
1504
+ # "currency": '',
1505
+ # "instrument_type": "perpetual",
1506
+ # "fee_type": "relative",
1507
+ # "maker_fee": 0,
1508
+ # "taker_fee": 0,
1509
+ # ],
1510
+ # },
1511
+ # "usIn": 1583775838115975,
1512
+ # "usOut": 1583775838116520,
1513
+ # "usDiff": 545,
1514
+ # "testnet": False
1515
+ # }
1516
+ #
1517
+ result = self.safe_value(response, 'result', {})
1518
+ fees = self.safe_value(result, 'fees', [])
1519
+ perpetualFee: dict = {}
1520
+ futureFee: dict = {}
1521
+ optionFee: dict = {}
1522
+ for i in range(0, len(fees)):
1523
+ fee = fees[i]
1524
+ instrumentType = self.safe_string(fee, 'instrument_type')
1525
+ if instrumentType == 'future':
1526
+ futureFee = {
1527
+ 'info': fee,
1528
+ 'maker': self.safe_number(fee, 'maker_fee'),
1529
+ 'taker': self.safe_number(fee, 'taker_fee'),
1530
+ }
1531
+ elif instrumentType == 'perpetual':
1532
+ perpetualFee = {
1533
+ 'info': fee,
1534
+ 'maker': self.safe_number(fee, 'maker_fee'),
1535
+ 'taker': self.safe_number(fee, 'taker_fee'),
1536
+ }
1537
+ elif instrumentType == 'option':
1538
+ optionFee = {
1539
+ 'info': fee,
1540
+ 'maker': self.safe_number(fee, 'maker_fee'),
1541
+ 'taker': self.safe_number(fee, 'taker_fee'),
1542
+ }
1543
+ parsedFees: dict = {}
1544
+ for i in range(0, len(self.symbols)):
1545
+ symbol = self.symbols[i]
1546
+ market = self.market(symbol)
1547
+ fee: dict = {
1548
+ 'info': market,
1549
+ 'symbol': symbol,
1550
+ 'percentage': True,
1551
+ 'tierBased': True,
1552
+ 'maker': market['maker'],
1553
+ 'taker': market['taker'],
1554
+ }
1555
+ if market['swap']:
1556
+ fee = self.extend(fee, perpetualFee)
1557
+ elif market['future']:
1558
+ fee = self.extend(fee, futureFee)
1559
+ elif market['option']:
1560
+ fee = self.extend(fee, optionFee)
1561
+ parsedFees[symbol] = fee
1562
+ return parsedFees
1563
+
1564
+ def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
1565
+ """
1566
+ fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
1567
+ :see: https://docs.deribit.com/#public-get_order_book
1568
+ :param str symbol: unified symbol of the market to fetch the order book for
1569
+ :param int [limit]: the maximum amount of order book entries to return
1570
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1571
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
1572
+ """
1573
+ self.load_markets()
1574
+ market = self.market(symbol)
1575
+ request: dict = {
1576
+ 'instrument_name': market['id'],
1577
+ }
1578
+ if limit is not None:
1579
+ request['depth'] = limit
1580
+ response = self.publicGetGetOrderBook(self.extend(request, params))
1581
+ #
1582
+ # {
1583
+ # "jsonrpc": "2.0",
1584
+ # "result": {
1585
+ # "timestamp": 1583781354740,
1586
+ # "stats": {volume: 61249.66735634, low: 7631.5, high: 8311.5},
1587
+ # "state": "open",
1588
+ # "settlement_price": 7903.21,
1589
+ # "open_interest": 111536690,
1590
+ # "min_price": 7695.13,
1591
+ # "max_price": 7929.49,
1592
+ # "mark_price": 7813.06,
1593
+ # "last_price": 7814.5,
1594
+ # "instrument_name": "BTC-PERPETUAL",
1595
+ # "index_price": 7810.12,
1596
+ # "funding_8h": 0.0000031,
1597
+ # "current_funding": 0,
1598
+ # "change_id": 17538025952,
1599
+ # "bids": [
1600
+ # [7814, 351820],
1601
+ # [7813.5, 207490],
1602
+ # [7813, 32160],
1603
+ # ],
1604
+ # "best_bid_price": 7814,
1605
+ # "best_bid_amount": 351820,
1606
+ # "best_ask_price": 7814.5,
1607
+ # "best_ask_amount": 11880,
1608
+ # "asks": [
1609
+ # [7814.5, 11880],
1610
+ # [7815, 18100],
1611
+ # [7815.5, 2640],
1612
+ # ],
1613
+ # },
1614
+ # "usIn": 1583781354745804,
1615
+ # "usOut": 1583781354745932,
1616
+ # "usDiff": 128,
1617
+ # "testnet": False
1618
+ # }
1619
+ #
1620
+ result = self.safe_value(response, 'result', {})
1621
+ timestamp = self.safe_integer(result, 'timestamp')
1622
+ nonce = self.safe_integer(result, 'change_id')
1623
+ orderbook = self.parse_order_book(result, market['symbol'], timestamp)
1624
+ orderbook['nonce'] = nonce
1625
+ return orderbook
1626
+
1627
+ def parse_order_status(self, status: Str):
1628
+ statuses: dict = {
1629
+ 'open': 'open',
1630
+ 'cancelled': 'canceled',
1631
+ 'filled': 'closed',
1632
+ 'rejected': 'rejected',
1633
+ 'untriggered': 'open',
1634
+ }
1635
+ return self.safe_string(statuses, status, status)
1636
+
1637
+ def parse_time_in_force(self, timeInForce: Str):
1638
+ timeInForces: dict = {
1639
+ 'good_til_cancelled': 'GTC',
1640
+ 'fill_or_kill': 'FOK',
1641
+ 'immediate_or_cancel': 'IOC',
1642
+ }
1643
+ return self.safe_string(timeInForces, timeInForce, timeInForce)
1644
+
1645
+ def parse_order_type(self, orderType):
1646
+ orderTypes: dict = {
1647
+ 'stop_limit': 'limit',
1648
+ 'take_limit': 'limit',
1649
+ 'stop_market': 'market',
1650
+ 'take_market': 'market',
1651
+ }
1652
+ return self.safe_string(orderTypes, orderType, orderType)
1653
+
1654
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1655
+ #
1656
+ # createOrder
1657
+ #
1658
+ # {
1659
+ # "time_in_force": "good_til_cancelled",
1660
+ # "reduce_only": False,
1661
+ # "profit_loss": 0,
1662
+ # "price": "market_price",
1663
+ # "post_only": False,
1664
+ # "order_type": "market",
1665
+ # "order_state": "filled",
1666
+ # "order_id": "ETH-349249",
1667
+ # "max_show": 40,
1668
+ # "last_update_timestamp": 1550657341322,
1669
+ # "label": "market0000234",
1670
+ # "is_liquidation": False,
1671
+ # "instrument_name": "ETH-PERPETUAL",
1672
+ # "filled_amount": 40,
1673
+ # "direction": "buy",
1674
+ # "creation_timestamp": 1550657341322,
1675
+ # "commission": 0.000139,
1676
+ # "average_price": 143.81,
1677
+ # "api": True,
1678
+ # "amount": 40,
1679
+ # "trades": [], # injected by createOrder
1680
+ # }
1681
+ #
1682
+ marketId = self.safe_string(order, 'instrument_name')
1683
+ market = self.safe_market(marketId, market)
1684
+ timestamp = self.safe_integer(order, 'creation_timestamp')
1685
+ lastUpdate = self.safe_integer(order, 'last_update_timestamp')
1686
+ id = self.safe_string(order, 'order_id')
1687
+ priceString = self.safe_string(order, 'price')
1688
+ if priceString == 'market_price':
1689
+ priceString = None
1690
+ averageString = self.safe_string(order, 'average_price')
1691
+ # Inverse contracts amount is in USD which in ccxt is the cost
1692
+ # For options and Linear contracts amount is in corresponding cryptocurrency, e.g., BTC or ETH
1693
+ filledString = self.safe_string(order, 'filled_amount')
1694
+ amount = self.safe_string(order, 'amount')
1695
+ cost = Precise.string_mul(filledString, averageString)
1696
+ if market['inverse']:
1697
+ if averageString != '0':
1698
+ cost = Precise.string_div(amount, averageString)
1699
+ lastTradeTimestamp = None
1700
+ if filledString is not None:
1701
+ isFilledPositive = Precise.string_gt(filledString, '0')
1702
+ if isFilledPositive:
1703
+ lastTradeTimestamp = lastUpdate
1704
+ status = self.parse_order_status(self.safe_string(order, 'order_state'))
1705
+ side = self.safe_string_lower(order, 'direction')
1706
+ feeCostString = self.safe_string(order, 'commission')
1707
+ fee = None
1708
+ if feeCostString is not None:
1709
+ feeCostString = Precise.string_abs(feeCostString)
1710
+ fee = {
1711
+ 'cost': feeCostString,
1712
+ 'currency': market['base'],
1713
+ }
1714
+ rawType = self.safe_string(order, 'order_type')
1715
+ type = self.parse_order_type(rawType)
1716
+ # injected in createOrder
1717
+ trades = self.safe_value(order, 'trades')
1718
+ timeInForce = self.parse_time_in_force(self.safe_string(order, 'time_in_force'))
1719
+ stopPrice = self.safe_value(order, 'stop_price')
1720
+ postOnly = self.safe_value(order, 'post_only')
1721
+ return self.safe_order({
1722
+ 'info': order,
1723
+ 'id': id,
1724
+ 'clientOrderId': None,
1725
+ 'timestamp': timestamp,
1726
+ 'datetime': self.iso8601(timestamp),
1727
+ 'lastTradeTimestamp': lastTradeTimestamp,
1728
+ 'symbol': market['symbol'],
1729
+ 'type': type,
1730
+ 'timeInForce': timeInForce,
1731
+ 'postOnly': postOnly,
1732
+ 'side': side,
1733
+ 'price': priceString,
1734
+ 'stopPrice': stopPrice,
1735
+ 'triggerPrice': stopPrice,
1736
+ 'amount': amount,
1737
+ 'cost': cost,
1738
+ 'average': averageString,
1739
+ 'filled': filledString,
1740
+ 'remaining': None,
1741
+ 'status': status,
1742
+ 'fee': fee,
1743
+ 'trades': trades,
1744
+ }, market)
1745
+
1746
+ def fetch_order(self, id: str, symbol: Str = None, params={}):
1747
+ """
1748
+ fetches information on an order made by the user
1749
+ :see: https://docs.deribit.com/#private-get_order_state
1750
+ :param str symbol: unified symbol of the market the order was made in
1751
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1752
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1753
+ """
1754
+ self.load_markets()
1755
+ request: dict = {
1756
+ 'order_id': id,
1757
+ }
1758
+ market = None
1759
+ if symbol is not None:
1760
+ market = self.market(symbol)
1761
+ response = self.privateGetGetOrderState(self.extend(request, params))
1762
+ #
1763
+ # {
1764
+ # "jsonrpc": "2.0",
1765
+ # "id": 4316,
1766
+ # "result": {
1767
+ # "time_in_force": "good_til_cancelled",
1768
+ # "reduce_only": False,
1769
+ # "profit_loss": 0.051134,
1770
+ # "price": 118.94,
1771
+ # "post_only": False,
1772
+ # "order_type": "limit",
1773
+ # "order_state": "filled",
1774
+ # "order_id": "ETH-331562",
1775
+ # "max_show": 37,
1776
+ # "last_update_timestamp": 1550219810944,
1777
+ # "label": "",
1778
+ # "is_liquidation": False,
1779
+ # "instrument_name": "ETH-PERPETUAL",
1780
+ # "filled_amount": 37,
1781
+ # "direction": "sell",
1782
+ # "creation_timestamp": 1550219749176,
1783
+ # "commission": 0.000031,
1784
+ # "average_price": 118.94,
1785
+ # "api": False,
1786
+ # "amount": 37
1787
+ # }
1788
+ # }
1789
+ #
1790
+ result = self.safe_dict(response, 'result')
1791
+ return self.parse_order(result, market)
1792
+
1793
+ def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1794
+ """
1795
+ create a trade order
1796
+ :see: https://docs.deribit.com/#private-buy
1797
+ :see: https://docs.deribit.com/#private-sell
1798
+ :param str symbol: unified symbol of the market to create an order in
1799
+ :param str type: 'market' or 'limit'
1800
+ :param str side: 'buy' or 'sell'
1801
+ :param float amount: how much you want to trade in units of the base currency. For inverse perpetual and futures the amount is in the quote currency USD. For options it is in the underlying assets base currency.
1802
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1803
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1804
+ :param str [params.trigger]: the trigger type 'index_price', 'mark_price', or 'last_price', default is 'last_price'
1805
+ :param float [params.trailingAmount]: the quote amount to trail away from the current market price
1806
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1807
+ """
1808
+ self.load_markets()
1809
+ market = self.market(symbol)
1810
+ request: dict = {
1811
+ 'instrument_name': market['id'],
1812
+ 'amount': self.amount_to_precision(symbol, amount),
1813
+ 'type': type, # limit, stop_limit, market, stop_market, default is limit
1814
+ # 'label': 'string', # user-defined label for the order(maximum 64 characters)
1815
+ # 'price': self.price_to_precision(symbol, 123.45), # only for limit and stop_limit orders
1816
+ # 'time_in_force' : 'good_til_cancelled', # fill_or_kill, immediate_or_cancel
1817
+ # 'max_show': 123.45, # max amount within an order to be shown to other customers, 0 for invisible order
1818
+ # 'post_only': False, # if the new price would cause the order to be filled immediately(as taker), the price will be changed to be just below the spread.
1819
+ # 'reject_post_only': False, # if True the order is put to order book unmodified or request is rejected
1820
+ # 'reduce_only': False, # if True, the order is intended to only reduce a current position
1821
+ # 'stop_price': False, # stop price, required for stop_limit orders
1822
+ # 'trigger': 'index_price', # mark_price, last_price, required for stop_limit orders
1823
+ # 'advanced': 'usd', # 'implv', advanced option order type, options only
1824
+ }
1825
+ trigger = self.safe_string(params, 'trigger', 'last_price')
1826
+ timeInForce = self.safe_string_upper(params, 'timeInForce')
1827
+ reduceOnly = self.safe_value_2(params, 'reduceOnly', 'reduce_only')
1828
+ # only stop loss sell orders are allowed when price crossed from above
1829
+ stopLossPrice = self.safe_value(params, 'stopLossPrice')
1830
+ # only take profit buy orders are allowed when price crossed from below
1831
+ takeProfitPrice = self.safe_value(params, 'takeProfitPrice')
1832
+ trailingAmount = self.safe_string_2(params, 'trailingAmount', 'trigger_offset')
1833
+ isTrailingAmountOrder = trailingAmount is not None
1834
+ isStopLimit = type == 'stop_limit'
1835
+ isStopMarket = type == 'stop_market'
1836
+ isTakeLimit = type == 'take_limit'
1837
+ isTakeMarket = type == 'take_market'
1838
+ isStopLossOrder = isStopLimit or isStopMarket or (stopLossPrice is not None)
1839
+ isTakeProfitOrder = isTakeLimit or isTakeMarket or (takeProfitPrice is not None)
1840
+ if isStopLossOrder and isTakeProfitOrder:
1841
+ raise InvalidOrder(self.id + ' createOrder() only allows one of stopLossPrice or takeProfitPrice to be specified')
1842
+ isStopOrder = isStopLossOrder or isTakeProfitOrder
1843
+ isLimitOrder = (type == 'limit') or isStopLimit or isTakeLimit
1844
+ isMarketOrder = (type == 'market') or isStopMarket or isTakeMarket
1845
+ exchangeSpecificPostOnly = self.safe_value(params, 'post_only')
1846
+ postOnly = self.is_post_only(isMarketOrder, exchangeSpecificPostOnly, params)
1847
+ if isLimitOrder:
1848
+ request['type'] = 'limit'
1849
+ request['price'] = self.price_to_precision(symbol, price)
1850
+ else:
1851
+ request['type'] = 'market'
1852
+ if isTrailingAmountOrder:
1853
+ request['trigger'] = trigger
1854
+ request['type'] = 'trailing_stop'
1855
+ request['trigger_offset'] = self.parse_to_numeric(trailingAmount)
1856
+ elif isStopOrder:
1857
+ triggerPrice = stopLossPrice if (stopLossPrice is not None) else takeProfitPrice
1858
+ request['trigger_price'] = self.price_to_precision(symbol, triggerPrice)
1859
+ request['trigger'] = trigger
1860
+ if isStopLossOrder:
1861
+ if isMarketOrder:
1862
+ # stop_market(sell only)
1863
+ request['type'] = 'stop_market'
1864
+ else:
1865
+ # stop_limit(sell only)
1866
+ request['type'] = 'stop_limit'
1867
+ else:
1868
+ if isMarketOrder:
1869
+ # take_market(buy only)
1870
+ request['type'] = 'take_market'
1871
+ else:
1872
+ # take_limit(buy only)
1873
+ request['type'] = 'take_limit'
1874
+ if reduceOnly:
1875
+ request['reduce_only'] = True
1876
+ if postOnly:
1877
+ request['post_only'] = True
1878
+ request['reject_post_only'] = True
1879
+ if timeInForce is not None:
1880
+ if timeInForce == 'GTC':
1881
+ request['time_in_force'] = 'good_til_cancelled'
1882
+ if timeInForce == 'IOC':
1883
+ request['time_in_force'] = 'immediate_or_cancel'
1884
+ if timeInForce == 'FOK':
1885
+ request['time_in_force'] = 'fill_or_kill'
1886
+ params = self.omit(params, ['timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'reduceOnly', 'trailingAmount'])
1887
+ response = None
1888
+ if self.capitalize(side) == 'Buy':
1889
+ response = self.privateGetBuy(self.extend(request, params))
1890
+ else:
1891
+ response = self.privateGetSell(self.extend(request, params))
1892
+ #
1893
+ # {
1894
+ # "jsonrpc": "2.0",
1895
+ # "id": 5275,
1896
+ # "result": {
1897
+ # "trades": [
1898
+ # {
1899
+ # "trade_seq": 14151,
1900
+ # "trade_id": "ETH-37435",
1901
+ # "timestamp": 1550657341322,
1902
+ # "tick_direction": 2,
1903
+ # "state": "closed",
1904
+ # "self_trade": False,
1905
+ # "price": 143.81,
1906
+ # "order_type": "market",
1907
+ # "order_id": "ETH-349249",
1908
+ # "matching_id": null,
1909
+ # "liquidity": "T",
1910
+ # "label": "market0000234",
1911
+ # "instrument_name": "ETH-PERPETUAL",
1912
+ # "index_price": 143.73,
1913
+ # "fee_currency": "ETH",
1914
+ # "fee": 0.000139,
1915
+ # "direction": "buy",
1916
+ # "amount": 40
1917
+ # }
1918
+ # ],
1919
+ # "order": {
1920
+ # "time_in_force": "good_til_cancelled",
1921
+ # "reduce_only": False,
1922
+ # "profit_loss": 0,
1923
+ # "price": "market_price",
1924
+ # "post_only": False,
1925
+ # "order_type": "market",
1926
+ # "order_state": "filled",
1927
+ # "order_id": "ETH-349249",
1928
+ # "max_show": 40,
1929
+ # "last_update_timestamp": 1550657341322,
1930
+ # "label": "market0000234",
1931
+ # "is_liquidation": False,
1932
+ # "instrument_name": "ETH-PERPETUAL",
1933
+ # "filled_amount": 40,
1934
+ # "direction": "buy",
1935
+ # "creation_timestamp": 1550657341322,
1936
+ # "commission": 0.000139,
1937
+ # "average_price": 143.81,
1938
+ # "api": True,
1939
+ # "amount": 40
1940
+ # }
1941
+ # }
1942
+ # }
1943
+ #
1944
+ result = self.safe_value(response, 'result', {})
1945
+ order = self.safe_value(result, 'order')
1946
+ trades = self.safe_value(result, 'trades', [])
1947
+ order['trades'] = trades
1948
+ return self.parse_order(order, market)
1949
+
1950
+ def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
1951
+ """
1952
+ edit a trade order
1953
+ :see: https://docs.deribit.com/#private-edit
1954
+ :param str id: edit order id
1955
+ :param str [symbol]: unified symbol of the market to edit an order in
1956
+ :param str [type]: 'market' or 'limit'
1957
+ :param str [side]: 'buy' or 'sell'
1958
+ :param float amount: how much you want to trade in units of the base currency, inverse swap and future use the quote currency
1959
+ :param float [price]: the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
1960
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1961
+ :param float [params.trailingAmount]: the quote amount to trail away from the current market price
1962
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1963
+ """
1964
+ if amount is None:
1965
+ raise ArgumentsRequired(self.id + ' editOrder() requires an amount argument')
1966
+ self.load_markets()
1967
+ request: dict = {
1968
+ 'order_id': id,
1969
+ 'amount': self.amount_to_precision(symbol, amount),
1970
+ # 'post_only': False, # if the new price would cause the order to be filled immediately(as taker), the price will be changed to be just below the spread.
1971
+ # 'reject_post_only': False, # if True the order is put to order book unmodified or request is rejected
1972
+ # 'reduce_only': False, # if True, the order is intended to only reduce a current position
1973
+ # 'stop_price': False, # stop price, required for stop_limit orders
1974
+ # 'advanced': 'usd', # 'implv', advanced option order type, options only
1975
+ }
1976
+ if price is not None:
1977
+ request['price'] = self.price_to_precision(symbol, price)
1978
+ trailingAmount = self.safe_string_2(params, 'trailingAmount', 'trigger_offset')
1979
+ isTrailingAmountOrder = trailingAmount is not None
1980
+ if isTrailingAmountOrder:
1981
+ request['trigger_offset'] = self.parse_to_numeric(trailingAmount)
1982
+ params = self.omit(params, 'trigger_offset')
1983
+ response = self.privateGetEdit(self.extend(request, params))
1984
+ result = self.safe_value(response, 'result', {})
1985
+ order = self.safe_value(result, 'order')
1986
+ trades = self.safe_value(result, 'trades', [])
1987
+ order['trades'] = trades
1988
+ return self.parse_order(order)
1989
+
1990
+ def cancel_order(self, id: str, symbol: Str = None, params={}):
1991
+ """
1992
+ cancels an open order
1993
+ :see: https://docs.deribit.com/#private-cancel
1994
+ :param str id: order id
1995
+ :param str symbol: not used by deribit cancelOrder()
1996
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1997
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1998
+ """
1999
+ self.load_markets()
2000
+ request: dict = {
2001
+ 'order_id': id,
2002
+ }
2003
+ response = self.privateGetCancel(self.extend(request, params))
2004
+ result = self.safe_dict(response, 'result', {})
2005
+ return self.parse_order(result)
2006
+
2007
+ def cancel_all_orders(self, symbol: Str = None, params={}):
2008
+ """
2009
+ cancel all open orders
2010
+ :see: https://docs.deribit.com/#private-cancel_all
2011
+ :see: https://docs.deribit.com/#private-cancel_all_by_instrument
2012
+ :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
2013
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2014
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
2015
+ """
2016
+ self.load_markets()
2017
+ request: dict = {}
2018
+ response = None
2019
+ if symbol is None:
2020
+ response = self.privateGetCancelAll(self.extend(request, params))
2021
+ else:
2022
+ market = self.market(symbol)
2023
+ request['instrument_name'] = market['id']
2024
+ response = self.privateGetCancelAllByInstrument(self.extend(request, params))
2025
+ return response
2026
+
2027
+ def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
2028
+ """
2029
+ fetch all unfilled currently open orders
2030
+ :see: https://docs.deribit.com/#private-get_open_orders_by_currency
2031
+ :see: https://docs.deribit.com/#private-get_open_orders_by_instrument
2032
+ :param str symbol: unified market symbol
2033
+ :param int [since]: the earliest time in ms to fetch open orders for
2034
+ :param int [limit]: the maximum number of open orders structures to retrieve
2035
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2036
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
2037
+ """
2038
+ self.load_markets()
2039
+ request: dict = {}
2040
+ market = None
2041
+ response = None
2042
+ if symbol is None:
2043
+ code = self.code_from_options('fetchOpenOrders', params)
2044
+ currency = self.currency(code)
2045
+ request['currency'] = currency['id']
2046
+ response = self.privateGetGetOpenOrdersByCurrency(self.extend(request, params))
2047
+ else:
2048
+ market = self.market(symbol)
2049
+ request['instrument_name'] = market['id']
2050
+ response = self.privateGetGetOpenOrdersByInstrument(self.extend(request, params))
2051
+ result = self.safe_list(response, 'result', [])
2052
+ return self.parse_orders(result, market, since, limit)
2053
+
2054
+ def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
2055
+ """
2056
+ fetches information on multiple closed orders made by the user
2057
+ :see: https://docs.deribit.com/#private-get_order_history_by_currency
2058
+ :see: https://docs.deribit.com/#private-get_order_history_by_instrument
2059
+ :param str symbol: unified market symbol of the market orders were made in
2060
+ :param int [since]: the earliest time in ms to fetch orders for
2061
+ :param int [limit]: the maximum number of order structures to retrieve
2062
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2063
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
2064
+ """
2065
+ self.load_markets()
2066
+ request: dict = {}
2067
+ market = None
2068
+ response = None
2069
+ if symbol is None:
2070
+ code = self.code_from_options('fetchClosedOrders', params)
2071
+ currency = self.currency(code)
2072
+ request['currency'] = currency['id']
2073
+ response = self.privateGetGetOrderHistoryByCurrency(self.extend(request, params))
2074
+ else:
2075
+ market = self.market(symbol)
2076
+ request['instrument_name'] = market['id']
2077
+ response = self.privateGetGetOrderHistoryByInstrument(self.extend(request, params))
2078
+ result = self.safe_list(response, 'result', [])
2079
+ return self.parse_orders(result, market, since, limit)
2080
+
2081
+ def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2082
+ """
2083
+ fetch all the trades made from a single order
2084
+ :see: https://docs.deribit.com/#private-get_user_trades_by_order
2085
+ :param str id: order id
2086
+ :param str symbol: unified market symbol
2087
+ :param int [since]: the earliest time in ms to fetch trades for
2088
+ :param int [limit]: the maximum number of trades to retrieve
2089
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2090
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
2091
+ """
2092
+ self.load_markets()
2093
+ request: dict = {
2094
+ 'order_id': id,
2095
+ }
2096
+ response = self.privateGetGetUserTradesByOrder(self.extend(request, params))
2097
+ #
2098
+ # {
2099
+ # "jsonrpc": "2.0",
2100
+ # "id": 9367,
2101
+ # "result": {
2102
+ # "trades": [
2103
+ # {
2104
+ # "trade_seq": 3,
2105
+ # "trade_id": "ETH-34066",
2106
+ # "timestamp": 1550219814585,
2107
+ # "tick_direction": 1,
2108
+ # "state": "open",
2109
+ # "self_trade": False,
2110
+ # "reduce_only": False,
2111
+ # "price": 0.04,
2112
+ # "post_only": False,
2113
+ # "order_type": "limit",
2114
+ # "order_id": "ETH-334607",
2115
+ # "matching_id": null,
2116
+ # "liquidity": "M",
2117
+ # "iv": 56.83,
2118
+ # "instrument_name": "ETH-22FEB19-120-C",
2119
+ # "index_price": 121.37,
2120
+ # "fee_currency": "ETH",
2121
+ # "fee": 0.0011,
2122
+ # "direction": "buy",
2123
+ # "amount": 11
2124
+ # },
2125
+ # ],
2126
+ # "has_more": True
2127
+ # }
2128
+ # }
2129
+ #
2130
+ result = self.safe_list(response, 'result', [])
2131
+ return self.parse_trades(result, None, since, limit)
2132
+
2133
+ def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2134
+ """
2135
+ fetch all trades made by the user
2136
+ :see: https://docs.deribit.com/#private-get_user_trades_by_currency
2137
+ :see: https://docs.deribit.com/#private-get_user_trades_by_currency_and_time
2138
+ :see: https://docs.deribit.com/#private-get_user_trades_by_instrument
2139
+ :see: https://docs.deribit.com/#private-get_user_trades_by_instrument_and_time
2140
+ :param str symbol: unified market symbol
2141
+ :param int [since]: the earliest time in ms to fetch trades for
2142
+ :param int [limit]: the maximum number of trades structures to retrieve
2143
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2144
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
2145
+ """
2146
+ self.load_markets()
2147
+ request: dict = {
2148
+ 'include_old': True,
2149
+ }
2150
+ market = None
2151
+ if limit is not None:
2152
+ request['count'] = limit # default 10
2153
+ response = None
2154
+ if symbol is None:
2155
+ code = self.code_from_options('fetchMyTrades', params)
2156
+ currency = self.currency(code)
2157
+ request['currency'] = currency['id']
2158
+ if since is None:
2159
+ response = self.privateGetGetUserTradesByCurrency(self.extend(request, params))
2160
+ else:
2161
+ request['start_timestamp'] = since
2162
+ response = self.privateGetGetUserTradesByCurrencyAndTime(self.extend(request, params))
2163
+ else:
2164
+ market = self.market(symbol)
2165
+ request['instrument_name'] = market['id']
2166
+ if since is None:
2167
+ response = self.privateGetGetUserTradesByInstrument(self.extend(request, params))
2168
+ else:
2169
+ request['start_timestamp'] = since
2170
+ response = self.privateGetGetUserTradesByInstrumentAndTime(self.extend(request, params))
2171
+ #
2172
+ # {
2173
+ # "jsonrpc": "2.0",
2174
+ # "id": 9367,
2175
+ # "result": {
2176
+ # "trades": [
2177
+ # {
2178
+ # "trade_seq": 3,
2179
+ # "trade_id": "ETH-34066",
2180
+ # "timestamp": 1550219814585,
2181
+ # "tick_direction": 1,
2182
+ # "state": "open",
2183
+ # "self_trade": False,
2184
+ # "reduce_only": False,
2185
+ # "price": 0.04,
2186
+ # "post_only": False,
2187
+ # "order_type": "limit",
2188
+ # "order_id": "ETH-334607",
2189
+ # "matching_id": null,
2190
+ # "liquidity": "M",
2191
+ # "iv": 56.83,
2192
+ # "instrument_name": "ETH-22FEB19-120-C",
2193
+ # "index_price": 121.37,
2194
+ # "fee_currency": "ETH",
2195
+ # "fee": 0.0011,
2196
+ # "direction": "buy",
2197
+ # "amount": 11
2198
+ # },
2199
+ # ],
2200
+ # "has_more": True
2201
+ # }
2202
+ # }
2203
+ #
2204
+ result = self.safe_value(response, 'result', {})
2205
+ trades = self.safe_list(result, 'trades', [])
2206
+ return self.parse_trades(trades, market, since, limit)
2207
+
2208
+ def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2209
+ """
2210
+ fetch all deposits made to an account
2211
+ :see: https://docs.deribit.com/#private-get_deposits
2212
+ :param str code: unified currency code
2213
+ :param int [since]: the earliest time in ms to fetch deposits for
2214
+ :param int [limit]: the maximum number of deposits structures to retrieve
2215
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2216
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2217
+ """
2218
+ if code is None:
2219
+ raise ArgumentsRequired(self.id + ' fetchDeposits() requires a currency code argument')
2220
+ self.load_markets()
2221
+ currency = self.currency(code)
2222
+ request: dict = {
2223
+ 'currency': currency['id'],
2224
+ }
2225
+ if limit is not None:
2226
+ request['count'] = limit
2227
+ response = self.privateGetGetDeposits(self.extend(request, params))
2228
+ #
2229
+ # {
2230
+ # "jsonrpc": "2.0",
2231
+ # "id": 5611,
2232
+ # "result": {
2233
+ # "count": 1,
2234
+ # "data": [
2235
+ # {
2236
+ # "address": "2N35qDKDY22zmJq9eSyiAerMD4enJ1xx6ax",
2237
+ # "amount": 5,
2238
+ # "currency": "BTC",
2239
+ # "received_timestamp": 1549295017670,
2240
+ # "state": "completed",
2241
+ # "transaction_id": "230669110fdaf0a0dbcdc079b6b8b43d5af29cc73683835b9bc6b3406c065fda",
2242
+ # "updated_timestamp": 1549295130159
2243
+ # }
2244
+ # ]
2245
+ # }
2246
+ # }
2247
+ #
2248
+ result = self.safe_value(response, 'result', {})
2249
+ data = self.safe_list(result, 'data', [])
2250
+ return self.parse_transactions(data, currency, since, limit, params)
2251
+
2252
+ def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2253
+ """
2254
+ fetch all withdrawals made from an account
2255
+ :see: https://docs.deribit.com/#private-get_withdrawals
2256
+ :param str code: unified currency code
2257
+ :param int [since]: the earliest time in ms to fetch withdrawals for
2258
+ :param int [limit]: the maximum number of withdrawals structures to retrieve
2259
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2260
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2261
+ """
2262
+ if code is None:
2263
+ raise ArgumentsRequired(self.id + ' fetchWithdrawals() requires a currency code argument')
2264
+ self.load_markets()
2265
+ currency = self.currency(code)
2266
+ request: dict = {
2267
+ 'currency': currency['id'],
2268
+ }
2269
+ if limit is not None:
2270
+ request['count'] = limit
2271
+ response = self.privateGetGetWithdrawals(self.extend(request, params))
2272
+ #
2273
+ # {
2274
+ # "jsonrpc": "2.0",
2275
+ # "id": 2745,
2276
+ # "result": {
2277
+ # "count": 1,
2278
+ # "data": [
2279
+ # {
2280
+ # "address": "2NBqqD5GRJ8wHy1PYyCXTe9ke5226FhavBz",
2281
+ # "amount": 0.5,
2282
+ # "confirmed_timestamp": null,
2283
+ # "created_timestamp": 1550571443070,
2284
+ # "currency": "BTC",
2285
+ # "fee": 0.0001,
2286
+ # "id": 1,
2287
+ # "priority": 0.15,
2288
+ # "state": "unconfirmed",
2289
+ # "transaction_id": null,
2290
+ # "updated_timestamp": 1550571443070
2291
+ # }
2292
+ # ]
2293
+ # }
2294
+ # }
2295
+ #
2296
+ result = self.safe_value(response, 'result', {})
2297
+ data = self.safe_list(result, 'data', [])
2298
+ return self.parse_transactions(data, currency, since, limit, params)
2299
+
2300
+ def parse_transaction_status(self, status: Str):
2301
+ statuses: dict = {
2302
+ 'completed': 'ok',
2303
+ 'unconfirmed': 'pending',
2304
+ }
2305
+ return self.safe_string(statuses, status, status)
2306
+
2307
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
2308
+ #
2309
+ # fetchWithdrawals
2310
+ #
2311
+ # {
2312
+ # "address": "2NBqqD5GRJ8wHy1PYyCXTe9ke5226FhavBz",
2313
+ # "amount": 0.5,
2314
+ # "confirmed_timestamp": null,
2315
+ # "created_timestamp": 1550571443070,
2316
+ # "currency": "BTC",
2317
+ # "fee": 0.0001,
2318
+ # "id": 1,
2319
+ # "priority": 0.15,
2320
+ # "state": "unconfirmed",
2321
+ # "transaction_id": null,
2322
+ # "updated_timestamp": 1550571443070
2323
+ # }
2324
+ #
2325
+ # fetchDeposits
2326
+ #
2327
+ # {
2328
+ # "address": "2N35qDKDY22zmJq9eSyiAerMD4enJ1xx6ax",
2329
+ # "amount": 5,
2330
+ # "currency": "BTC",
2331
+ # "received_timestamp": 1549295017670,
2332
+ # "state": "completed",
2333
+ # "transaction_id": "230669110fdaf0a0dbcdc079b6b8b43d5af29cc73683835b9bc6b3406c065fda",
2334
+ # "updated_timestamp": 1549295130159
2335
+ # }
2336
+ #
2337
+ currencyId = self.safe_string(transaction, 'currency')
2338
+ code = self.safe_currency_code(currencyId, currency)
2339
+ timestamp = self.safe_integer_2(transaction, 'created_timestamp', 'received_timestamp')
2340
+ updated = self.safe_integer(transaction, 'updated_timestamp')
2341
+ status = self.parse_transaction_status(self.safe_string(transaction, 'state'))
2342
+ address = self.safe_string(transaction, 'address')
2343
+ feeCost = self.safe_number(transaction, 'fee')
2344
+ type = 'deposit'
2345
+ fee = None
2346
+ if feeCost is not None:
2347
+ type = 'withdrawal'
2348
+ fee = {
2349
+ 'cost': feeCost,
2350
+ 'currency': code,
2351
+ }
2352
+ return {
2353
+ 'info': transaction,
2354
+ 'id': self.safe_string(transaction, 'id'),
2355
+ 'txid': self.safe_string(transaction, 'transaction_id'),
2356
+ 'timestamp': timestamp,
2357
+ 'datetime': self.iso8601(timestamp),
2358
+ 'address': address,
2359
+ 'addressTo': address,
2360
+ 'addressFrom': None,
2361
+ 'tag': None,
2362
+ 'tagTo': None,
2363
+ 'tagFrom': None,
2364
+ 'type': type,
2365
+ 'amount': self.safe_number(transaction, 'amount'),
2366
+ 'currency': code,
2367
+ 'status': status,
2368
+ 'updated': updated,
2369
+ 'network': None,
2370
+ 'internal': None,
2371
+ 'comment': None,
2372
+ 'fee': fee,
2373
+ }
2374
+
2375
+ def parse_position(self, position: dict, market: Market = None):
2376
+ #
2377
+ # {
2378
+ # "jsonrpc": "2.0",
2379
+ # "id": 404,
2380
+ # "result": {
2381
+ # "average_price": 0,
2382
+ # "delta": 0,
2383
+ # "direction": "buy",
2384
+ # "estimated_liquidation_price": 0,
2385
+ # "floating_profit_loss": 0,
2386
+ # "index_price": 3555.86,
2387
+ # "initial_margin": 0,
2388
+ # "instrument_name": "BTC-PERPETUAL",
2389
+ # "leverage": 100,
2390
+ # "kind": "future",
2391
+ # "maintenance_margin": 0,
2392
+ # "mark_price": 3556.62,
2393
+ # "open_orders_margin": 0.000165889,
2394
+ # "realized_profit_loss": 0,
2395
+ # "settlement_price": 3555.44,
2396
+ # "size": 0,
2397
+ # "size_currency": 0,
2398
+ # "total_profit_loss": 0
2399
+ # }
2400
+ # }
2401
+ #
2402
+ contract = self.safe_string(position, 'instrument_name')
2403
+ market = self.safe_market(contract, market)
2404
+ side = self.safe_string(position, 'direction')
2405
+ side = 'long' if (side == 'buy') else 'short'
2406
+ unrealizedPnl = self.safe_string(position, 'floating_profit_loss')
2407
+ initialMarginString = self.safe_string(position, 'initial_margin')
2408
+ notionalString = self.safe_string(position, 'size_currency')
2409
+ maintenanceMarginString = self.safe_string(position, 'maintenance_margin')
2410
+ currentTime = self.milliseconds()
2411
+ return self.safe_position({
2412
+ 'info': position,
2413
+ 'id': None,
2414
+ 'symbol': self.safe_string(market, 'symbol'),
2415
+ 'timestamp': currentTime,
2416
+ 'datetime': self.iso8601(currentTime),
2417
+ 'lastUpdateTimestamp': None,
2418
+ 'initialMargin': self.parse_number(initialMarginString),
2419
+ 'initialMarginPercentage': self.parse_number(Precise.string_mul(Precise.string_div(initialMarginString, notionalString), '100')),
2420
+ 'maintenanceMargin': self.parse_number(maintenanceMarginString),
2421
+ 'maintenanceMarginPercentage': self.parse_number(Precise.string_mul(Precise.string_div(maintenanceMarginString, notionalString), '100')),
2422
+ 'entryPrice': self.safe_number(position, 'average_price'),
2423
+ 'notional': self.parse_number(notionalString),
2424
+ 'leverage': self.safe_integer(position, 'leverage'),
2425
+ 'unrealizedPnl': self.parse_number(unrealizedPnl),
2426
+ 'contracts': None,
2427
+ 'contractSize': self.safe_number(market, 'contractSize'),
2428
+ 'marginRatio': None,
2429
+ 'liquidationPrice': self.safe_number(position, 'estimated_liquidation_price'),
2430
+ 'markPrice': self.safe_number(position, 'mark_price'),
2431
+ 'lastPrice': None,
2432
+ 'collateral': None,
2433
+ 'marginMode': None,
2434
+ 'side': side,
2435
+ 'percentage': None,
2436
+ 'hedged': None,
2437
+ 'stopLossPrice': None,
2438
+ 'takeProfitPrice': None,
2439
+ })
2440
+
2441
+ def fetch_position(self, symbol: str, params={}):
2442
+ """
2443
+ fetch data on a single open contract trade position
2444
+ :see: https://docs.deribit.com/#private-get_position
2445
+ :param str symbol: unified market symbol of the market the position is held in, default is None
2446
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2447
+ :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
2448
+ """
2449
+ self.load_markets()
2450
+ market = self.market(symbol)
2451
+ request: dict = {
2452
+ 'instrument_name': market['id'],
2453
+ }
2454
+ response = self.privateGetGetPosition(self.extend(request, params))
2455
+ #
2456
+ # {
2457
+ # "jsonrpc": "2.0",
2458
+ # "id": 404,
2459
+ # "result": {
2460
+ # "average_price": 0,
2461
+ # "delta": 0,
2462
+ # "direction": "buy",
2463
+ # "estimated_liquidation_price": 0,
2464
+ # "floating_profit_loss": 0,
2465
+ # "index_price": 3555.86,
2466
+ # "initial_margin": 0,
2467
+ # "instrument_name": "BTC-PERPETUAL",
2468
+ # "leverage": 100,
2469
+ # "kind": "future",
2470
+ # "maintenance_margin": 0,
2471
+ # "mark_price": 3556.62,
2472
+ # "open_orders_margin": 0.000165889,
2473
+ # "realized_profit_loss": 0,
2474
+ # "settlement_price": 3555.44,
2475
+ # "size": 0,
2476
+ # "size_currency": 0,
2477
+ # "total_profit_loss": 0
2478
+ # }
2479
+ # }
2480
+ #
2481
+ result = self.safe_dict(response, 'result')
2482
+ return self.parse_position(result)
2483
+
2484
+ def fetch_positions(self, symbols: Strings = None, params={}):
2485
+ """
2486
+ fetch all open positions
2487
+ :see: https://docs.deribit.com/#private-get_positions
2488
+ :param str[]|None symbols: list of unified market symbols
2489
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2490
+ :param str [params.kind]: market type filter for positions 'future', 'option', 'spot', 'future_combo' or 'option_combo'
2491
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
2492
+ """
2493
+ self.load_markets()
2494
+ kind = self.safe_string(params, 'kind')
2495
+ code = None
2496
+ if symbols is None:
2497
+ code = self.code_from_options('fetchPositions', params)
2498
+ elif isinstance(symbols, str):
2499
+ code = symbols
2500
+ symbols = None # fix https://github.com/ccxt/ccxt/issues/13961
2501
+ else:
2502
+ if isinstance(symbols, list):
2503
+ length = len(symbols)
2504
+ if length != 1:
2505
+ raise BadRequest(self.id + ' fetchPositions() symbols argument cannot contain more than 1 symbol')
2506
+ market = self.market(symbols[0])
2507
+ settle = market['settle']
2508
+ code = settle if (settle is not None) else market['base']
2509
+ kind = market['info']['kind']
2510
+ currency = self.currency(code)
2511
+ request: dict = {
2512
+ 'currency': currency['id'],
2513
+ }
2514
+ if kind is not None:
2515
+ request['kind'] = kind
2516
+ response = self.privateGetGetPositions(self.extend(request, params))
2517
+ #
2518
+ # {
2519
+ # "jsonrpc": "2.0",
2520
+ # "id": 2236,
2521
+ # "result": [
2522
+ # {
2523
+ # "average_price": 7440.18,
2524
+ # "delta": 0.006687487,
2525
+ # "direction": "buy",
2526
+ # "estimated_liquidation_price": 1.74,
2527
+ # "floating_profit_loss": 0,
2528
+ # "index_price": 7466.79,
2529
+ # "initial_margin": 0.000197283,
2530
+ # "instrument_name": "BTC-PERPETUAL",
2531
+ # "kind": "future",
2532
+ # "leverage": 34,
2533
+ # "maintenance_margin": 0.000143783,
2534
+ # "mark_price": 7476.65,
2535
+ # "open_orders_margin": 0.000197288,
2536
+ # "realized_funding": -1e-8,
2537
+ # "realized_profit_loss": -9e-9,
2538
+ # "settlement_price": 7476.65,
2539
+ # "size": 50,
2540
+ # "size_currency": 0.006687487,
2541
+ # "total_profit_loss": 0.000032781
2542
+ # },
2543
+ # ]
2544
+ # }
2545
+ #
2546
+ result = self.safe_list(response, 'result')
2547
+ return self.parse_positions(result, symbols)
2548
+
2549
+ def fetch_volatility_history(self, code: str, params={}):
2550
+ """
2551
+ fetch the historical volatility of an option market based on an underlying asset
2552
+ :see: https://docs.deribit.com/#public-get_historical_volatility
2553
+ :param str code: unified currency code
2554
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2555
+ :returns dict[]: a list of `volatility history objects <https://docs.ccxt.com/#/?id=volatility-structure>`
2556
+ """
2557
+ self.load_markets()
2558
+ currency = self.currency(code)
2559
+ request: dict = {
2560
+ 'currency': currency['id'],
2561
+ }
2562
+ response = self.publicGetGetHistoricalVolatility(self.extend(request, params))
2563
+ #
2564
+ # {
2565
+ # "jsonrpc": "2.0",
2566
+ # "result": [
2567
+ # [1640142000000,63.828320460740585],
2568
+ # [1640142000000,63.828320460740585],
2569
+ # [1640145600000,64.03821964123213]
2570
+ # ],
2571
+ # "usIn": 1641515379467734,
2572
+ # "usOut": 1641515379468095,
2573
+ # "usDiff": 361,
2574
+ # "testnet": False
2575
+ # }
2576
+ #
2577
+ return self.parse_volatility_history(response)
2578
+
2579
+ def parse_volatility_history(self, volatility):
2580
+ #
2581
+ # {
2582
+ # "jsonrpc": "2.0",
2583
+ # "result": [
2584
+ # [1640142000000,63.828320460740585],
2585
+ # [1640142000000,63.828320460740585],
2586
+ # [1640145600000,64.03821964123213]
2587
+ # ],
2588
+ # "usIn": 1641515379467734,
2589
+ # "usOut": 1641515379468095,
2590
+ # "usDiff": 361,
2591
+ # "testnet": False
2592
+ # }
2593
+ #
2594
+ volatilityResult = self.safe_value(volatility, 'result', [])
2595
+ result = []
2596
+ for i in range(0, len(volatilityResult)):
2597
+ timestamp = self.safe_integer(volatilityResult[i], 0)
2598
+ volatilityObj = self.safe_number(volatilityResult[i], 1)
2599
+ result.append({
2600
+ 'info': volatilityObj,
2601
+ 'timestamp': timestamp,
2602
+ 'datetime': self.iso8601(timestamp),
2603
+ 'volatility': volatilityObj,
2604
+ })
2605
+ return result
2606
+
2607
+ def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> TransferEntries:
2608
+ """
2609
+ fetch a history of internal transfers made on an account
2610
+ :see: https://docs.deribit.com/#private-get_transfers
2611
+ :param str code: unified currency code of the currency transferred
2612
+ :param int [since]: the earliest time in ms to fetch transfers for
2613
+ :param int [limit]: the maximum number of transfers structures to retrieve
2614
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2615
+ :returns dict[]: a list of `transfer structures <https://docs.ccxt.com/#/?id=transfer-structure>`
2616
+ """
2617
+ if code is None:
2618
+ raise ArgumentsRequired(self.id + ' fetchTransfers() requires a currency code argument')
2619
+ self.load_markets()
2620
+ currency = self.currency(code)
2621
+ request: dict = {
2622
+ 'currency': currency['id'],
2623
+ }
2624
+ if limit is not None:
2625
+ request['count'] = limit
2626
+ response = self.privateGetGetTransfers(self.extend(request, params))
2627
+ #
2628
+ # {
2629
+ # "jsonrpc": "2.0",
2630
+ # "id": 7606,
2631
+ # "result": {
2632
+ # "count": 2,
2633
+ # "data": [
2634
+ # {
2635
+ # "amount": 0.2,
2636
+ # "created_timestamp": 1550579457727,
2637
+ # "currency": "BTC",
2638
+ # "direction": "payment",
2639
+ # "id": 2,
2640
+ # "other_side": "2MzyQc5Tkik61kJbEpJV5D5H9VfWHZK9Sgy",
2641
+ # "state": "prepared",
2642
+ # "type": "user",
2643
+ # "updated_timestamp": 1550579457727
2644
+ # },
2645
+ # {
2646
+ # "amount": 0.3,
2647
+ # "created_timestamp": 1550579255800,
2648
+ # "currency": "BTC",
2649
+ # "direction": "payment",
2650
+ # "id": 1,
2651
+ # "other_side": "new_user_1_1",
2652
+ # "state": "confirmed",
2653
+ # "type": "subaccount",
2654
+ # "updated_timestamp": 1550579255800
2655
+ # }
2656
+ # ]
2657
+ # }
2658
+ # }
2659
+ #
2660
+ result = self.safe_value(response, 'result', {})
2661
+ transfers = self.safe_list(result, 'data', [])
2662
+ return self.parse_transfers(transfers, currency, since, limit, params)
2663
+
2664
+ def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
2665
+ """
2666
+ transfer currency internally between wallets on the same account
2667
+ :see: https://docs.deribit.com/#private-submit_transfer_to_user
2668
+ :see: https://docs.deribit.com/#private-submit_transfer_to_subaccount
2669
+ :param str code: unified currency code
2670
+ :param float amount: amount to transfer
2671
+ :param str fromAccount: account to transfer from
2672
+ :param str toAccount: account to transfer to
2673
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2674
+ :returns dict: a `transfer structure <https://docs.ccxt.com/#/?id=transfer-structure>`
2675
+ """
2676
+ self.load_markets()
2677
+ currency = self.currency(code)
2678
+ request: dict = {
2679
+ 'amount': amount,
2680
+ 'currency': currency['id'],
2681
+ 'destination': toAccount,
2682
+ }
2683
+ method = self.safe_string(params, 'method')
2684
+ params = self.omit(params, 'method')
2685
+ if method is None:
2686
+ transferOptions = self.safe_value(self.options, 'transfer', {})
2687
+ method = self.safe_string(transferOptions, 'method', 'privateGetSubmitTransferToSubaccount')
2688
+ response = None
2689
+ if method == 'privateGetSubmitTransferToUser':
2690
+ response = self.privateGetSubmitTransferToUser(self.extend(request, params))
2691
+ else:
2692
+ response = self.privateGetSubmitTransferToSubaccount(self.extend(request, params))
2693
+ #
2694
+ # {
2695
+ # "jsonrpc": "2.0",
2696
+ # "id": 9421,
2697
+ # "result": {
2698
+ # "updated_timestamp": 1550232862350,
2699
+ # "type": "user",
2700
+ # "state": "prepared",
2701
+ # "other_side": "0x4aa0753d798d668056920094d65321a8e8913e26",
2702
+ # "id": 3,
2703
+ # "direction": "payment",
2704
+ # "currency": "ETH",
2705
+ # "created_timestamp": 1550232862350,
2706
+ # "amount": 13.456
2707
+ # }
2708
+ # }
2709
+ #
2710
+ result = self.safe_dict(response, 'result', {})
2711
+ return self.parse_transfer(result, currency)
2712
+
2713
+ def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
2714
+ #
2715
+ # {
2716
+ # "updated_timestamp": 1550232862350,
2717
+ # "type": "user",
2718
+ # "state": "prepared",
2719
+ # "other_side": "0x4aa0753d798d668056920094d65321a8e8913e26",
2720
+ # "id": 3,
2721
+ # "direction": "payment",
2722
+ # "currency": "ETH",
2723
+ # "created_timestamp": 1550232862350,
2724
+ # "amount": 13.456
2725
+ # }
2726
+ #
2727
+ timestamp = self.safe_timestamp(transfer, 'created_timestamp')
2728
+ status = self.safe_string(transfer, 'state')
2729
+ account = self.safe_string(transfer, 'other_side')
2730
+ direction = self.safe_string(transfer, 'direction')
2731
+ currencyId = self.safe_string(transfer, 'currency')
2732
+ return {
2733
+ 'info': transfer,
2734
+ 'id': self.safe_string(transfer, 'id'),
2735
+ 'status': self.parse_transfer_status(status),
2736
+ 'amount': self.safe_number(transfer, 'amount'),
2737
+ 'currency': self.safe_currency_code(currencyId, currency),
2738
+ 'fromAccount': direction != account if 'payment' else None,
2739
+ 'toAccount': direction == account if 'payment' else None,
2740
+ 'timestamp': timestamp,
2741
+ 'datetime': self.iso8601(timestamp),
2742
+ }
2743
+
2744
+ def parse_transfer_status(self, status: Str) -> Str:
2745
+ statuses: dict = {
2746
+ 'prepared': 'pending',
2747
+ 'confirmed': 'ok',
2748
+ 'cancelled': 'cancelled',
2749
+ 'waiting_for_admin': 'pending',
2750
+ }
2751
+ return self.safe_string(statuses, status, status)
2752
+
2753
+ def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
2754
+ """
2755
+ make a withdrawal
2756
+ :see: https://docs.deribit.com/#private-withdraw
2757
+ :param str code: unified currency code
2758
+ :param float amount: the amount to withdraw
2759
+ :param str address: the address to withdraw to
2760
+ :param str tag:
2761
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2762
+ :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
2763
+ """
2764
+ tag, params = self.handle_withdraw_tag_and_params(tag, params)
2765
+ self.check_address(address)
2766
+ self.load_markets()
2767
+ currency = self.currency(code)
2768
+ request: dict = {
2769
+ 'currency': currency['id'],
2770
+ 'address': address, # must be in the address book
2771
+ 'amount': amount,
2772
+ # 'priority': 'high', # low, mid, high, very_high, extreme_high, insane
2773
+ # 'tfa': '123456', # if enabled
2774
+ }
2775
+ if self.twofa is not None:
2776
+ request['tfa'] = self.totp(self.twofa)
2777
+ response = self.privateGetWithdraw(self.extend(request, params))
2778
+ return self.parse_transaction(response, currency)
2779
+
2780
+ def parse_deposit_withdraw_fee(self, fee, currency: Currency = None):
2781
+ #
2782
+ # {
2783
+ # "withdrawal_priorities": [],
2784
+ # "withdrawal_fee": 0.01457324,
2785
+ # "min_withdrawal_fee": 0.000001,
2786
+ # "min_confirmations": 1,
2787
+ # "fee_precision": 8,
2788
+ # "currency_long": "Solana",
2789
+ # "currency": "SOL",
2790
+ # "coin_type": "SOL"
2791
+ # }
2792
+ #
2793
+ return {
2794
+ 'info': fee,
2795
+ 'withdraw': {
2796
+ 'fee': self.safe_number(fee, 'withdrawal_fee'),
2797
+ 'percentage': False,
2798
+ },
2799
+ 'deposit': {
2800
+ 'fee': None,
2801
+ 'percentage': None,
2802
+ },
2803
+ 'networks': {},
2804
+ }
2805
+
2806
+ def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
2807
+ """
2808
+ fetch deposit and withdraw fees
2809
+ :see: https://docs.deribit.com/#public-get_currencies
2810
+ :param str[]|None codes: list of unified currency codes
2811
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2812
+ :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
2813
+ """
2814
+ self.load_markets()
2815
+ response = self.publicGetGetCurrencies(params)
2816
+ #
2817
+ # {
2818
+ # "jsonrpc": "2.0",
2819
+ # "result": [
2820
+ # {
2821
+ # "withdrawal_priorities": [],
2822
+ # "withdrawal_fee": 0.01457324,
2823
+ # "min_withdrawal_fee": 0.000001,
2824
+ # "min_confirmations": 1,
2825
+ # "fee_precision": 8,
2826
+ # "currency_long": "Solana",
2827
+ # "currency": "SOL",
2828
+ # "coin_type": "SOL"
2829
+ # },
2830
+ # ...
2831
+ # ],
2832
+ # "usIn": 1688652701456124,
2833
+ # "usOut": 1688652701456390,
2834
+ # "usDiff": 266,
2835
+ # "testnet": True
2836
+ # }
2837
+ #
2838
+ data = self.safe_list(response, 'result', [])
2839
+ return self.parse_deposit_withdraw_fees(data, codes, 'currency')
2840
+
2841
+ def fetch_funding_rate(self, symbol: str, params={}):
2842
+ """
2843
+ fetch the current funding rate
2844
+ :see: https://docs.deribit.com/#public-get_funding_rate_value
2845
+ :param str symbol: unified market symbol
2846
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2847
+ :param int [params.start_timestamp]: fetch funding rate starting from self timestamp
2848
+ :param int [params.end_timestamp]: fetch funding rate ending at self timestamp
2849
+ :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
2850
+ """
2851
+ self.load_markets()
2852
+ market = self.market(symbol)
2853
+ time = self.milliseconds()
2854
+ request: dict = {
2855
+ 'instrument_name': market['id'],
2856
+ 'start_timestamp': time - (8 * 60 * 60 * 1000), # 8h ago,
2857
+ 'end_timestamp': time,
2858
+ }
2859
+ response = self.publicGetGetFundingRateValue(self.extend(request, params))
2860
+ #
2861
+ # {
2862
+ # "jsonrpc":"2.0",
2863
+ # "result":"0",
2864
+ # "usIn":"1691161645596519",
2865
+ # "usOut":"1691161645597149",
2866
+ # "usDiff":"630",
2867
+ # "testnet":false
2868
+ # }
2869
+ #
2870
+ return self.parse_funding_rate(response, market)
2871
+
2872
+ def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2873
+ """
2874
+ fetch the current funding rate
2875
+ :see: https://docs.deribit.com/#public-get_funding_rate_history
2876
+ :param str symbol: unified market symbol
2877
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2878
+ :param int [params.end_timestamp]: fetch funding rate ending at self timestamp
2879
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
2880
+ :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
2881
+ """
2882
+ self.load_markets()
2883
+ market = self.market(symbol)
2884
+ paginate = False
2885
+ paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
2886
+ if paginate:
2887
+ return self.fetch_paginated_call_deterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params, 720)
2888
+ time = self.milliseconds()
2889
+ month = 30 * 24 * 60 * 60 * 1000
2890
+ if since is None:
2891
+ since = time - month
2892
+ request: dict = {
2893
+ 'instrument_name': market['id'],
2894
+ 'start_timestamp': since - 1,
2895
+ 'end_timestamp': time,
2896
+ }
2897
+ response = self.publicGetGetFundingRateHistory(self.extend(request, params))
2898
+ #
2899
+ # {
2900
+ # "jsonrpc": "2.0",
2901
+ # "id": 7617,
2902
+ # "result": [
2903
+ # {
2904
+ # "timestamp": 1569891600000,
2905
+ # "index_price": 8222.87,
2906
+ # "prev_index_price": 8305.72,
2907
+ # "interest_8h": -0.00009234260068476106,
2908
+ # "interest_1h": -4.739622041017375e-7
2909
+ # }
2910
+ # ]
2911
+ # }
2912
+ #
2913
+ rates = []
2914
+ result = self.safe_value(response, 'result', [])
2915
+ for i in range(0, len(result)):
2916
+ fr = result[i]
2917
+ rate = self.parse_funding_rate(fr, market)
2918
+ rates.append(rate)
2919
+ return self.filter_by_symbol_since_limit(rates, symbol, since, limit)
2920
+
2921
+ def parse_funding_rate(self, contract, market: Market = None):
2922
+ #
2923
+ # {
2924
+ # "jsonrpc":"2.0",
2925
+ # "result":"0",
2926
+ # "usIn":"1691161645596519",
2927
+ # "usOut":"1691161645597149",
2928
+ # "usDiff":"630",
2929
+ # "testnet":false
2930
+ # }
2931
+ # history
2932
+ # {
2933
+ # "timestamp": 1569891600000,
2934
+ # "index_price": 8222.87,
2935
+ # "prev_index_price": 8305.72,
2936
+ # "interest_8h": -0.00009234260068476106,
2937
+ # "interest_1h": -4.739622041017375e-7
2938
+ # }
2939
+ #
2940
+ timestamp = self.safe_integer(contract, 'timestamp')
2941
+ datetime = self.iso8601(timestamp)
2942
+ result = self.safe_number_2(contract, 'result', 'interest_8h')
2943
+ return {
2944
+ 'info': contract,
2945
+ 'symbol': self.safe_symbol(None, market),
2946
+ 'markPrice': None,
2947
+ 'indexPrice': self.safe_number(contract, 'index_price'),
2948
+ 'interestRate': None,
2949
+ 'estimatedSettlePrice': None,
2950
+ 'timestamp': timestamp,
2951
+ 'datetime': datetime,
2952
+ 'fundingRate': result,
2953
+ 'fundingTimestamp': None,
2954
+ 'fundingDatetime': None,
2955
+ 'nextFundingRate': None,
2956
+ 'nextFundingTimestamp': None,
2957
+ 'nextFundingDatetime': None,
2958
+ 'previousFundingRate': None,
2959
+ 'previousFundingTimestamp': None,
2960
+ 'previousFundingDatetime': None,
2961
+ }
2962
+
2963
+ def fetch_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}):
2964
+ """
2965
+ retrieves the public liquidations of a trading pair
2966
+ :see: https://docs.deribit.com/#public-get_last_settlements_by_currency
2967
+ :param str symbol: unified CCXT market symbol
2968
+ :param int [since]: the earliest time in ms to fetch liquidations for
2969
+ :param int [limit]: the maximum number of liquidation structures to retrieve
2970
+ :param dict [params]: exchange specific parameters for the deribit api endpoint
2971
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
2972
+ :returns dict: an array of `liquidation structures <https://docs.ccxt.com/#/?id=liquidation-structure>`
2973
+ """
2974
+ self.load_markets()
2975
+ paginate = False
2976
+ paginate, params = self.handle_option_and_params(params, 'fetchLiquidations', 'paginate')
2977
+ if paginate:
2978
+ return self.fetch_paginated_call_cursor('fetchLiquidations', symbol, since, limit, params, 'continuation', 'continuation', None)
2979
+ market = self.market(symbol)
2980
+ if market['spot']:
2981
+ raise NotSupported(self.id + ' fetchLiquidations() does not support ' + market['type'] + ' markets')
2982
+ request: dict = {
2983
+ 'instrument_name': market['id'],
2984
+ 'type': 'bankruptcy',
2985
+ }
2986
+ if since is not None:
2987
+ request['search_start_timestamp'] = since
2988
+ if limit is not None:
2989
+ request['count'] = limit
2990
+ response = self.publicGetGetLastSettlementsByInstrument(self.extend(request, params))
2991
+ #
2992
+ # {
2993
+ # "jsonrpc": "2.0",
2994
+ # "result": {
2995
+ # "settlements": [
2996
+ # {
2997
+ # "type": "bankruptcy",
2998
+ # "timestamp": 1696579200041,
2999
+ # "funded": 10000.0,
3000
+ # "session_bankrupcy": 10000.0
3001
+ # "session_profit_loss": 112951.68715857354,
3002
+ # "session_tax": 0.15,
3003
+ # "session_tax_rate": 0.0015,
3004
+ # "socialized": 0.001,
3005
+ # },
3006
+ # ],
3007
+ # "continuation": "5dHzoGyD8Hs8KURoUhfgXgHpJTA5oyapoudSmNeAfEftqRbjNE6jNNUpo2oCu1khnZL9ao"
3008
+ # },
3009
+ # "usIn": 1696652052254890,
3010
+ # "usOut": 1696652052255733,
3011
+ # "usDiff": 843,
3012
+ # "testnet": False
3013
+ # }
3014
+ #
3015
+ result = self.safe_value(response, 'result', {})
3016
+ cursor = self.safe_string(result, 'continuation')
3017
+ settlements = self.safe_value(result, 'settlements', [])
3018
+ settlementsWithCursor = self.add_pagination_cursor_to_result(cursor, settlements)
3019
+ return self.parse_liquidations(settlementsWithCursor, market, since, limit)
3020
+
3021
+ def add_pagination_cursor_to_result(self, cursor, data):
3022
+ if cursor is not None:
3023
+ dataLength = len(data)
3024
+ if dataLength > 0:
3025
+ first = data[0]
3026
+ last = data[dataLength - 1]
3027
+ first['continuation'] = cursor
3028
+ last['continuation'] = cursor
3029
+ data[0] = first
3030
+ data[dataLength - 1] = last
3031
+ return data
3032
+
3033
+ def fetch_my_liquidations(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3034
+ """
3035
+ retrieves the users liquidated positions
3036
+ :see: https://docs.deribit.com/#private-get_settlement_history_by_instrument
3037
+ :param str symbol: unified CCXT market symbol
3038
+ :param int [since]: the earliest time in ms to fetch liquidations for
3039
+ :param int [limit]: the maximum number of liquidation structures to retrieve
3040
+ :param dict [params]: exchange specific parameters for the deribit api endpoint
3041
+ :returns dict: an array of `liquidation structures <https://docs.ccxt.com/#/?id=liquidation-structure>`
3042
+ """
3043
+ if symbol is None:
3044
+ raise ArgumentsRequired(self.id + ' fetchMyLiquidations() requires a symbol argument')
3045
+ self.load_markets()
3046
+ market = self.market(symbol)
3047
+ if market['spot']:
3048
+ raise NotSupported(self.id + ' fetchMyLiquidations() does not support ' + market['type'] + ' markets')
3049
+ request: dict = {
3050
+ 'instrument_name': market['id'],
3051
+ 'type': 'bankruptcy',
3052
+ }
3053
+ if since is not None:
3054
+ request['search_start_timestamp'] = since
3055
+ if limit is not None:
3056
+ request['count'] = limit
3057
+ response = self.privateGetGetSettlementHistoryByInstrument(self.extend(request, params))
3058
+ #
3059
+ # {
3060
+ # "jsonrpc": "2.0",
3061
+ # "result": {
3062
+ # "settlements": [
3063
+ # {
3064
+ # "type": "bankruptcy",
3065
+ # "timestamp": 1696579200041,
3066
+ # "funded": 10000.0,
3067
+ # "session_bankrupcy": 10000.0
3068
+ # "session_profit_loss": 112951.68715857354,
3069
+ # "session_tax": 0.15,
3070
+ # "session_tax_rate": 0.0015,
3071
+ # "socialized": 0.001,
3072
+ # },
3073
+ # ],
3074
+ # "continuation": "5dHzoGyD8Hs8KURoUhfgXgHpJTA5oyapoudSmNeAfEftqRbjNE6jNNUpo2oCu1khnZL9ao"
3075
+ # },
3076
+ # "usIn": 1696652052254890,
3077
+ # "usOut": 1696652052255733,
3078
+ # "usDiff": 843,
3079
+ # "testnet": False
3080
+ # }
3081
+ #
3082
+ result = self.safe_value(response, 'result', {})
3083
+ settlements = self.safe_list(result, 'settlements', [])
3084
+ return self.parse_liquidations(settlements, market, since, limit)
3085
+
3086
+ def parse_liquidation(self, liquidation, market: Market = None):
3087
+ #
3088
+ # {
3089
+ # "type": "bankruptcy",
3090
+ # "timestamp": 1696579200041,
3091
+ # "funded": 1,
3092
+ # "session_bankrupcy": 0.001,
3093
+ # "session_profit_loss": 0.001,
3094
+ # "session_tax": 0.0015,
3095
+ # "session_tax_rate": 0.0015,
3096
+ # "socialized": 0.001,
3097
+ # }
3098
+ #
3099
+ timestamp = self.safe_integer(liquidation, 'timestamp')
3100
+ return self.safe_liquidation({
3101
+ 'info': liquidation,
3102
+ 'symbol': self.safe_symbol(None, market),
3103
+ 'contracts': None,
3104
+ 'contractSize': self.safe_number(market, 'contractSize'),
3105
+ 'price': None,
3106
+ 'baseValue': self.safe_number(liquidation, 'session_bankrupcy'),
3107
+ 'quoteValue': None,
3108
+ 'timestamp': timestamp,
3109
+ 'datetime': self.iso8601(timestamp),
3110
+ })
3111
+
3112
+ def fetch_greeks(self, symbol: str, params={}) -> Greeks:
3113
+ """
3114
+ fetches an option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract
3115
+ :see: https://docs.deribit.com/#public-ticker
3116
+ :param str symbol: unified symbol of the market to fetch greeks for
3117
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3118
+ :returns dict: a `greeks structure <https://docs.ccxt.com/#/?id=greeks-structure>`
3119
+ """
3120
+ self.load_markets()
3121
+ market = self.market(symbol)
3122
+ request: dict = {
3123
+ 'instrument_name': market['id'],
3124
+ }
3125
+ response = self.publicGetTicker(self.extend(request, params))
3126
+ #
3127
+ # {
3128
+ # "jsonrpc": "2.0",
3129
+ # "result": {
3130
+ # "estimated_delivery_price": 36552.72,
3131
+ # "best_bid_amount": 0.2,
3132
+ # "best_ask_amount": 9.1,
3133
+ # "interest_rate": 0.0,
3134
+ # "best_bid_price": 0.214,
3135
+ # "best_ask_price": 0.219,
3136
+ # "open_interest": 368.8,
3137
+ # "settlement_price": 0.22103022,
3138
+ # "last_price": 0.215,
3139
+ # "bid_iv": 60.51,
3140
+ # "ask_iv": 61.88,
3141
+ # "mark_iv": 61.27,
3142
+ # "underlying_index": "BTC-27SEP24",
3143
+ # "underlying_price": 38992.71,
3144
+ # "min_price": 0.1515,
3145
+ # "max_price": 0.326,
3146
+ # "mark_price": 0.2168,
3147
+ # "instrument_name": "BTC-27SEP24-40000-C",
3148
+ # "index_price": 36552.72,
3149
+ # "greeks": {
3150
+ # "rho": 130.63998,
3151
+ # "theta": -13.48784,
3152
+ # "vega": 141.90146,
3153
+ # "gamma": 0.00002,
3154
+ # "delta": 0.59621
3155
+ # },
3156
+ # "stats": {
3157
+ # "volume_usd": 100453.9,
3158
+ # "volume": 12.0,
3159
+ # "price_change": -2.2727,
3160
+ # "low": 0.2065,
3161
+ # "high": 0.238
3162
+ # },
3163
+ # "state": "open",
3164
+ # "timestamp": 1699578548021
3165
+ # },
3166
+ # "usIn": 1699578548308414,
3167
+ # "usOut": 1699578548308606,
3168
+ # "usDiff": 192,
3169
+ # "testnet": False
3170
+ # }
3171
+ #
3172
+ result = self.safe_value(response, 'result', {})
3173
+ return self.parse_greeks(result, market)
3174
+
3175
+ def parse_greeks(self, greeks: dict, market: Market = None) -> Greeks:
3176
+ #
3177
+ # {
3178
+ # "estimated_delivery_price": 36552.72,
3179
+ # "best_bid_amount": 0.2,
3180
+ # "best_ask_amount": 9.1,
3181
+ # "interest_rate": 0.0,
3182
+ # "best_bid_price": 0.214,
3183
+ # "best_ask_price": 0.219,
3184
+ # "open_interest": 368.8,
3185
+ # "settlement_price": 0.22103022,
3186
+ # "last_price": 0.215,
3187
+ # "bid_iv": 60.51,
3188
+ # "ask_iv": 61.88,
3189
+ # "mark_iv": 61.27,
3190
+ # "underlying_index": "BTC-27SEP24",
3191
+ # "underlying_price": 38992.71,
3192
+ # "min_price": 0.1515,
3193
+ # "max_price": 0.326,
3194
+ # "mark_price": 0.2168,
3195
+ # "instrument_name": "BTC-27SEP24-40000-C",
3196
+ # "index_price": 36552.72,
3197
+ # "greeks": {
3198
+ # "rho": 130.63998,
3199
+ # "theta": -13.48784,
3200
+ # "vega": 141.90146,
3201
+ # "gamma": 0.00002,
3202
+ # "delta": 0.59621
3203
+ # },
3204
+ # "stats": {
3205
+ # "volume_usd": 100453.9,
3206
+ # "volume": 12.0,
3207
+ # "price_change": -2.2727,
3208
+ # "low": 0.2065,
3209
+ # "high": 0.238
3210
+ # },
3211
+ # "state": "open",
3212
+ # "timestamp": 1699578548021
3213
+ # }
3214
+ #
3215
+ timestamp = self.safe_integer(greeks, 'timestamp')
3216
+ marketId = self.safe_string(greeks, 'instrument_name')
3217
+ symbol = self.safe_symbol(marketId, market)
3218
+ stats = self.safe_value(greeks, 'greeks', {})
3219
+ return {
3220
+ 'symbol': symbol,
3221
+ 'timestamp': timestamp,
3222
+ 'datetime': self.iso8601(timestamp),
3223
+ 'delta': self.safe_number(stats, 'delta'),
3224
+ 'gamma': self.safe_number(stats, 'gamma'),
3225
+ 'theta': self.safe_number(stats, 'theta'),
3226
+ 'vega': self.safe_number(stats, 'vega'),
3227
+ 'rho': self.safe_number(stats, 'rho'),
3228
+ 'bidSize': self.safe_number(greeks, 'best_bid_amount'),
3229
+ 'askSize': self.safe_number(greeks, 'best_ask_amount'),
3230
+ 'bidImpliedVolatility': self.safe_number(greeks, 'bid_iv'),
3231
+ 'askImpliedVolatility': self.safe_number(greeks, 'ask_iv'),
3232
+ 'markImpliedVolatility': self.safe_number(greeks, 'mark_iv'),
3233
+ 'bidPrice': self.safe_number(greeks, 'best_bid_price'),
3234
+ 'askPrice': self.safe_number(greeks, 'best_ask_price'),
3235
+ 'markPrice': self.safe_number(greeks, 'mark_price'),
3236
+ 'lastPrice': self.safe_number(greeks, 'last_price'),
3237
+ 'underlyingPrice': self.safe_number(greeks, 'underlying_price'),
3238
+ 'info': greeks,
3239
+ }
3240
+
3241
+ def fetch_option(self, symbol: str, params={}) -> Option:
3242
+ """
3243
+ fetches option data that is commonly found in an option chain
3244
+ :see: https://docs.deribit.com/#public-get_book_summary_by_instrument
3245
+ :param str symbol: unified market symbol
3246
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3247
+ :returns dict: an `option chain structure <https://docs.ccxt.com/#/?id=option-chain-structure>`
3248
+ """
3249
+ self.load_markets()
3250
+ market = self.market(symbol)
3251
+ request: dict = {
3252
+ 'instrument_name': market['id'],
3253
+ }
3254
+ response = self.publicGetGetBookSummaryByInstrument(self.extend(request, params))
3255
+ #
3256
+ # {
3257
+ # "jsonrpc": "2.0",
3258
+ # "result": [
3259
+ # {
3260
+ # "mid_price": 0.04025,
3261
+ # "volume_usd": 11045.12,
3262
+ # "quote_currency": "BTC",
3263
+ # "estimated_delivery_price": 65444.72,
3264
+ # "creation_timestamp": 1711100949273,
3265
+ # "base_currency": "BTC",
3266
+ # "underlying_index": "BTC-27DEC24",
3267
+ # "underlying_price": 73742.14,
3268
+ # "volume": 4.0,
3269
+ # "interest_rate": 0.0,
3270
+ # "price_change": -6.9767,
3271
+ # "open_interest": 274.2,
3272
+ # "ask_price": 0.042,
3273
+ # "bid_price": 0.0385,
3274
+ # "instrument_name": "BTC-27DEC24-240000-C",
3275
+ # "mark_price": 0.04007735,
3276
+ # "last": 0.04,
3277
+ # "low": 0.04,
3278
+ # "high": 0.043
3279
+ # }
3280
+ # ],
3281
+ # "usIn": 1711100949273223,
3282
+ # "usOut": 1711100949273580,
3283
+ # "usDiff": 357,
3284
+ # "testnet": False
3285
+ # }
3286
+ #
3287
+ result = self.safe_list(response, 'result', [])
3288
+ chain = self.safe_dict(result, 0, {})
3289
+ return self.parse_option(chain, None, market)
3290
+
3291
+ def fetch_option_chain(self, code: str, params={}) -> OptionChain:
3292
+ """
3293
+ fetches data for an underlying asset that is commonly found in an option chain
3294
+ :see: https://docs.deribit.com/#public-get_book_summary_by_currency
3295
+ :param str currency: base currency to fetch an option chain for
3296
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3297
+ :returns dict: a list of `option chain structures <https://docs.ccxt.com/#/?id=option-chain-structure>`
3298
+ """
3299
+ self.load_markets()
3300
+ currency = self.currency(code)
3301
+ request: dict = {
3302
+ 'currency': currency['id'],
3303
+ 'kind': 'option',
3304
+ }
3305
+ response = self.publicGetGetBookSummaryByCurrency(self.extend(request, params))
3306
+ #
3307
+ # {
3308
+ # "jsonrpc": "2.0",
3309
+ # "result": [
3310
+ # {
3311
+ # "mid_price": 0.4075,
3312
+ # "volume_usd": 2836.83,
3313
+ # "quote_currency": "BTC",
3314
+ # "estimated_delivery_price": 65479.26,
3315
+ # "creation_timestamp": 1711101594477,
3316
+ # "base_currency": "BTC",
3317
+ # "underlying_index": "BTC-28JUN24",
3318
+ # "underlying_price": 68827.27,
3319
+ # "volume": 0.1,
3320
+ # "interest_rate": 0.0,
3321
+ # "price_change": 0.0,
3322
+ # "open_interest": 364.1,
3323
+ # "ask_price": 0.411,
3324
+ # "bid_price": 0.404,
3325
+ # "instrument_name": "BTC-28JUN24-42000-C",
3326
+ # "mark_price": 0.40752052,
3327
+ # "last": 0.423,
3328
+ # "low": 0.423,
3329
+ # "high": 0.423
3330
+ # }
3331
+ # ],
3332
+ # "usIn": 1711101594456388,
3333
+ # "usOut": 1711101594484065,
3334
+ # "usDiff": 27677,
3335
+ # "testnet": False
3336
+ # }
3337
+ #
3338
+ result = self.safe_list(response, 'result', [])
3339
+ return self.parse_option_chain(result, 'base_currency', 'instrument_name')
3340
+
3341
+ def parse_option(self, chain: dict, currency: Currency = None, market: Market = None) -> Option:
3342
+ #
3343
+ # {
3344
+ # "mid_price": 0.04025,
3345
+ # "volume_usd": 11045.12,
3346
+ # "quote_currency": "BTC",
3347
+ # "estimated_delivery_price": 65444.72,
3348
+ # "creation_timestamp": 1711100949273,
3349
+ # "base_currency": "BTC",
3350
+ # "underlying_index": "BTC-27DEC24",
3351
+ # "underlying_price": 73742.14,
3352
+ # "volume": 4.0,
3353
+ # "interest_rate": 0.0,
3354
+ # "price_change": -6.9767,
3355
+ # "open_interest": 274.2,
3356
+ # "ask_price": 0.042,
3357
+ # "bid_price": 0.0385,
3358
+ # "instrument_name": "BTC-27DEC24-240000-C",
3359
+ # "mark_price": 0.04007735,
3360
+ # "last": 0.04,
3361
+ # "low": 0.04,
3362
+ # "high": 0.043
3363
+ # }
3364
+ #
3365
+ marketId = self.safe_string(chain, 'instrument_name')
3366
+ market = self.safe_market(marketId, market)
3367
+ currencyId = self.safe_string(chain, 'base_currency')
3368
+ code = self.safe_currency_code(currencyId, currency)
3369
+ timestamp = self.safe_integer(chain, 'timestamp')
3370
+ return {
3371
+ 'info': chain,
3372
+ 'currency': code,
3373
+ 'symbol': market['symbol'],
3374
+ 'timestamp': timestamp,
3375
+ 'datetime': self.iso8601(timestamp),
3376
+ 'impliedVolatility': None,
3377
+ 'openInterest': self.safe_number(chain, 'open_interest'),
3378
+ 'bidPrice': self.safe_number(chain, 'bid_price'),
3379
+ 'askPrice': self.safe_number(chain, 'ask_price'),
3380
+ 'midPrice': self.safe_number(chain, 'mid_price'),
3381
+ 'markPrice': self.safe_number(chain, 'mark_price'),
3382
+ 'lastPrice': self.safe_number(chain, 'last'),
3383
+ 'underlyingPrice': self.safe_number(chain, 'underlying_price'),
3384
+ 'change': None,
3385
+ 'percentage': self.safe_number(chain, 'price_change'),
3386
+ 'baseVolume': self.safe_number(chain, 'volume'),
3387
+ 'quoteVolume': self.safe_number(chain, 'volume_usd'),
3388
+ }
3389
+
3390
+ def nonce(self):
3391
+ return self.milliseconds()
3392
+
3393
+ def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
3394
+ request = '/' + 'api/' + self.version + '/' + api + '/' + path
3395
+ if api == 'public':
3396
+ if params:
3397
+ request += '?' + self.urlencode(params)
3398
+ if api == 'private':
3399
+ self.check_required_credentials()
3400
+ nonce = str(self.nonce())
3401
+ timestamp = str(self.milliseconds())
3402
+ requestBody = ''
3403
+ if params:
3404
+ request += '?' + self.urlencode(params)
3405
+ requestData = method + "\n" + request + "\n" + requestBody + "\n" # eslint-disable-line quotes
3406
+ auth = timestamp + "\n" + nonce + "\n" + requestData # eslint-disable-line quotes
3407
+ signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
3408
+ headers = {
3409
+ 'Authorization': 'deri-hmac-sha256 id=' + self.apiKey + ',ts=' + timestamp + ',sig=' + signature + ',' + 'nonce=' + nonce,
3410
+ }
3411
+ url = self.urls['api']['rest'] + request
3412
+ return {'url': url, 'method': method, 'body': body, 'headers': headers}
3413
+
3414
+ def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
3415
+ if not response:
3416
+ return None # fallback to default error handler
3417
+ #
3418
+ # {
3419
+ # "jsonrpc": "2.0",
3420
+ # "error": {
3421
+ # "message": "Invalid params",
3422
+ # "data": {reason: "invalid currency", param: "currency"},
3423
+ # "code": -32602
3424
+ # },
3425
+ # "testnet": False,
3426
+ # "usIn": 1583763842150374,
3427
+ # "usOut": 1583763842150410,
3428
+ # "usDiff": 36
3429
+ # }
3430
+ #
3431
+ error = self.safe_value(response, 'error')
3432
+ if error is not None:
3433
+ errorCode = self.safe_string(error, 'code')
3434
+ feedback = self.id + ' ' + body
3435
+ self.throw_exactly_matched_exception(self.exceptions, errorCode, feedback)
3436
+ raise ExchangeError(feedback) # unknown message
3437
+ return None