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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (772) hide show
  1. ccxt/__init__.py +358 -0
  2. ccxt/abantether.py +316 -0
  3. ccxt/abstract/__init__.py +0 -0
  4. ccxt/abstract/abantether.py +5 -0
  5. ccxt/abstract/ace.py +15 -0
  6. ccxt/abstract/afratether.py +6 -0
  7. ccxt/abstract/alpaca.py +70 -0
  8. ccxt/abstract/arzinja.py +5 -0
  9. ccxt/abstract/arzplus.py +7 -0
  10. ccxt/abstract/ascendex.py +77 -0
  11. ccxt/abstract/bequant.py +115 -0
  12. ccxt/abstract/bigone.py +45 -0
  13. ccxt/abstract/binance.py +712 -0
  14. ccxt/abstract/binancecoinm.py +712 -0
  15. ccxt/abstract/binanceus.py +764 -0
  16. ccxt/abstract/binanceusdm.py +712 -0
  17. ccxt/abstract/bingx.py +113 -0
  18. ccxt/abstract/bit2c.py +27 -0
  19. ccxt/abstract/bitbank.py +27 -0
  20. ccxt/abstract/bitbay.py +53 -0
  21. ccxt/abstract/bitbns.py +40 -0
  22. ccxt/abstract/bitcoincom.py +115 -0
  23. ccxt/abstract/bitfinex.py +69 -0
  24. ccxt/abstract/bitfinex2.py +139 -0
  25. ccxt/abstract/bitflyer.py +38 -0
  26. ccxt/abstract/bitget.py +508 -0
  27. ccxt/abstract/bithumb.py +32 -0
  28. ccxt/abstract/bitimen.py +7 -0
  29. ccxt/abstract/bitir.py +7 -0
  30. ccxt/abstract/bitmart.py +99 -0
  31. ccxt/abstract/bitmex.py +97 -0
  32. ccxt/abstract/bitopro.py +29 -0
  33. ccxt/abstract/bitpanda.py +35 -0
  34. ccxt/abstract/bitpin.py +7 -0
  35. ccxt/abstract/bitrue.py +72 -0
  36. ccxt/abstract/bitso.py +43 -0
  37. ccxt/abstract/bitstamp.py +258 -0
  38. ccxt/abstract/bitteam.py +29 -0
  39. ccxt/abstract/bitvavo.py +27 -0
  40. ccxt/abstract/bl3p.py +19 -0
  41. ccxt/abstract/blockchaincom.py +28 -0
  42. ccxt/abstract/blofin.py +37 -0
  43. ccxt/abstract/btcalpha.py +18 -0
  44. ccxt/abstract/btcbox.py +13 -0
  45. ccxt/abstract/btcmarkets.py +39 -0
  46. ccxt/abstract/btcturk.py +20 -0
  47. ccxt/abstract/bybit.py +298 -0
  48. ccxt/abstract/cex.py +33 -0
  49. ccxt/abstract/coinbase.py +94 -0
  50. ccxt/abstract/coinbaseadvanced.py +94 -0
  51. ccxt/abstract/coinbaseexchange.py +67 -0
  52. ccxt/abstract/coinbaseinternational.py +39 -0
  53. ccxt/abstract/coincatch.py +94 -0
  54. ccxt/abstract/coincheck.py +33 -0
  55. ccxt/abstract/coinex.py +237 -0
  56. ccxt/abstract/coinlist.py +54 -0
  57. ccxt/abstract/coinmate.py +62 -0
  58. ccxt/abstract/coinmetro.py +34 -0
  59. ccxt/abstract/coinone.py +67 -0
  60. ccxt/abstract/coinsph.py +54 -0
  61. ccxt/abstract/coinspot.py +28 -0
  62. ccxt/abstract/cryptocom.py +107 -0
  63. ccxt/abstract/currencycom.py +68 -0
  64. ccxt/abstract/delta.py +50 -0
  65. ccxt/abstract/deribit.py +125 -0
  66. ccxt/abstract/digifinex.py +91 -0
  67. ccxt/abstract/eterex.py +5 -0
  68. ccxt/abstract/excoino.py +7 -0
  69. ccxt/abstract/exir.py +8 -0
  70. ccxt/abstract/exmo.py +55 -0
  71. ccxt/abstract/exnovin.py +6 -0
  72. ccxt/abstract/farhadexchange.py +5 -0
  73. ccxt/abstract/fmfwio.py +115 -0
  74. ccxt/abstract/gate.py +265 -0
  75. ccxt/abstract/gateio.py +265 -0
  76. ccxt/abstract/gemini.py +58 -0
  77. ccxt/abstract/hashkey.py +67 -0
  78. ccxt/abstract/hitbtc.py +115 -0
  79. ccxt/abstract/hitbtc3.py +115 -0
  80. ccxt/abstract/hitobit.py +8 -0
  81. ccxt/abstract/hollaex.py +33 -0
  82. ccxt/abstract/htx.py +548 -0
  83. ccxt/abstract/huobi.py +548 -0
  84. ccxt/abstract/huobijp.py +114 -0
  85. ccxt/abstract/hyperliquid.py +6 -0
  86. ccxt/abstract/idex.py +26 -0
  87. ccxt/abstract/independentreserve.py +37 -0
  88. ccxt/abstract/indodax.py +26 -0
  89. ccxt/abstract/jibitex.py +7 -0
  90. ccxt/abstract/kraken.py +57 -0
  91. ccxt/abstract/krakenfutures.py +38 -0
  92. ccxt/abstract/kucoin.py +214 -0
  93. ccxt/abstract/kucoinfutures.py +233 -0
  94. ccxt/abstract/kuna.py +182 -0
  95. ccxt/abstract/latoken.py +56 -0
  96. ccxt/abstract/lbank.py +61 -0
  97. ccxt/abstract/luno.py +37 -0
  98. ccxt/abstract/lykke.py +29 -0
  99. ccxt/abstract/mercado.py +25 -0
  100. ccxt/abstract/mexc.py +178 -0
  101. ccxt/abstract/ndax.py +97 -0
  102. ccxt/abstract/nobitex.py +7 -0
  103. ccxt/abstract/novadax.py +29 -0
  104. ccxt/abstract/oceanex.py +22 -0
  105. ccxt/abstract/okcoin.py +74 -0
  106. ccxt/abstract/okexchange.py +8 -0
  107. ccxt/abstract/okx.py +324 -0
  108. ccxt/abstract/ompfinex.py +7 -0
  109. ccxt/abstract/onetrading.py +35 -0
  110. ccxt/abstract/oxfun.py +34 -0
  111. ccxt/abstract/p2b.py +22 -0
  112. ccxt/abstract/paradex.py +40 -0
  113. ccxt/abstract/paymium.py +28 -0
  114. ccxt/abstract/phemex.py +115 -0
  115. ccxt/abstract/poloniex.py +69 -0
  116. ccxt/abstract/poloniexfutures.py +48 -0
  117. ccxt/abstract/probit.py +23 -0
  118. ccxt/abstract/ramzinex.py +7 -0
  119. ccxt/abstract/sarmayex.py +5 -0
  120. ccxt/abstract/sarrafex.py +7 -0
  121. ccxt/abstract/tabdeal.py +7 -0
  122. ccxt/abstract/tetherland.py +5 -0
  123. ccxt/abstract/timex.py +62 -0
  124. ccxt/abstract/tokocrypto.py +37 -0
  125. ccxt/abstract/tradeogre.py +16 -0
  126. ccxt/abstract/twox.py +5 -0
  127. ccxt/abstract/ubitex.py +7 -0
  128. ccxt/abstract/upbit.py +38 -0
  129. ccxt/abstract/vertex.py +19 -0
  130. ccxt/abstract/wallex.py +8 -0
  131. ccxt/abstract/wavesexchange.py +154 -0
  132. ccxt/abstract/wazirx.py +30 -0
  133. ccxt/abstract/whitebit.py +98 -0
  134. ccxt/abstract/woo.py +83 -0
  135. ccxt/abstract/woofipro.py +119 -0
  136. ccxt/abstract/xt.py +152 -0
  137. ccxt/abstract/yobit.py +16 -0
  138. ccxt/abstract/zaif.py +38 -0
  139. ccxt/abstract/zonda.py +53 -0
  140. ccxt/ace.py +1012 -0
  141. ccxt/afratether.py +293 -0
  142. ccxt/alpaca.py +1083 -0
  143. ccxt/arzinja.py +285 -0
  144. ccxt/arzplus.py +412 -0
  145. ccxt/ascendex.py +3330 -0
  146. ccxt/async_support/__init__.py +337 -0
  147. ccxt/async_support/abantether.py +316 -0
  148. ccxt/async_support/ace.py +1012 -0
  149. ccxt/async_support/afratether.py +293 -0
  150. ccxt/async_support/alpaca.py +1083 -0
  151. ccxt/async_support/arzinja.py +285 -0
  152. ccxt/async_support/arzplus.py +412 -0
  153. ccxt/async_support/ascendex.py +3330 -0
  154. ccxt/async_support/base/__init__.py +1 -0
  155. ccxt/async_support/base/exchange.py +1966 -0
  156. ccxt/async_support/base/throttler.py +50 -0
  157. ccxt/async_support/base/ws/__init__.py +38 -0
  158. ccxt/async_support/base/ws/aiohttp_client.py +125 -0
  159. ccxt/async_support/base/ws/cache.py +212 -0
  160. ccxt/async_support/base/ws/client.py +193 -0
  161. ccxt/async_support/base/ws/fast_client.py +96 -0
  162. ccxt/async_support/base/ws/functions.py +59 -0
  163. ccxt/async_support/base/ws/future.py +58 -0
  164. ccxt/async_support/base/ws/order_book.py +78 -0
  165. ccxt/async_support/base/ws/order_book_side.py +174 -0
  166. ccxt/async_support/bequant.py +33 -0
  167. ccxt/async_support/bigone.py +2113 -0
  168. ccxt/async_support/binance.py +12234 -0
  169. ccxt/async_support/binancecoinm.py +45 -0
  170. ccxt/async_support/binanceus.py +211 -0
  171. ccxt/async_support/binanceusdm.py +58 -0
  172. ccxt/async_support/bingx.py +4325 -0
  173. ccxt/async_support/bit2c.py +866 -0
  174. ccxt/async_support/bitbank.py +1001 -0
  175. ccxt/async_support/bitbay.py +17 -0
  176. ccxt/async_support/bitbns.py +1154 -0
  177. ccxt/async_support/bitcoincom.py +17 -0
  178. ccxt/async_support/bitfinex.py +1617 -0
  179. ccxt/async_support/bitfinex2.py +3552 -0
  180. ccxt/async_support/bitflyer.py +995 -0
  181. ccxt/async_support/bitget.py +8273 -0
  182. ccxt/async_support/bithumb.py +1061 -0
  183. ccxt/async_support/bitimen.py +401 -0
  184. ccxt/async_support/bitir.py +490 -0
  185. ccxt/async_support/bitmart.py +4415 -0
  186. ccxt/async_support/bitmex.py +2756 -0
  187. ccxt/async_support/bitopro.py +1630 -0
  188. ccxt/async_support/bitpanda.py +16 -0
  189. ccxt/async_support/bitpin.py +454 -0
  190. ccxt/async_support/bitrue.py +3027 -0
  191. ccxt/async_support/bitso.py +1670 -0
  192. ccxt/async_support/bitstamp.py +2203 -0
  193. ccxt/async_support/bitteam.py +2239 -0
  194. ccxt/async_support/bitvavo.py +1968 -0
  195. ccxt/async_support/bl3p.py +485 -0
  196. ccxt/async_support/blockchaincom.py +1104 -0
  197. ccxt/async_support/blofin.py +2066 -0
  198. ccxt/async_support/btcalpha.py +891 -0
  199. ccxt/async_support/btcbox.py +544 -0
  200. ccxt/async_support/btcmarkets.py +1221 -0
  201. ccxt/async_support/btcturk.py +911 -0
  202. ccxt/async_support/bybit.py +8159 -0
  203. ccxt/async_support/cex.py +1605 -0
  204. ccxt/async_support/coinbase.py +4475 -0
  205. ccxt/async_support/coinbaseadvanced.py +17 -0
  206. ccxt/async_support/coinbaseexchange.py +1734 -0
  207. ccxt/async_support/coinbaseinternational.py +1899 -0
  208. ccxt/async_support/coincatch.py +5069 -0
  209. ccxt/async_support/coincheck.py +815 -0
  210. ccxt/async_support/coinex.py +5526 -0
  211. ccxt/async_support/coinlist.py +2243 -0
  212. ccxt/async_support/coinmate.py +1067 -0
  213. ccxt/async_support/coinmetro.py +1797 -0
  214. ccxt/async_support/coinone.py +1127 -0
  215. ccxt/async_support/coinsph.py +1850 -0
  216. ccxt/async_support/coinspot.py +534 -0
  217. ccxt/async_support/cryptocom.py +2822 -0
  218. ccxt/async_support/currencycom.py +1950 -0
  219. ccxt/async_support/delta.py +3376 -0
  220. ccxt/async_support/deribit.py +3437 -0
  221. ccxt/async_support/digifinex.py +3960 -0
  222. ccxt/async_support/eterex.py +286 -0
  223. ccxt/async_support/excoino.py +399 -0
  224. ccxt/async_support/exir.py +375 -0
  225. ccxt/async_support/exmo.py +2462 -0
  226. ccxt/async_support/exnovin.py +360 -0
  227. ccxt/async_support/farhadexchange.py +266 -0
  228. ccxt/async_support/fmfwio.py +34 -0
  229. ccxt/async_support/gate.py +6976 -0
  230. ccxt/async_support/gateio.py +16 -0
  231. ccxt/async_support/gemini.py +1825 -0
  232. ccxt/async_support/hashkey.py +4150 -0
  233. ccxt/async_support/hitbtc.py +3423 -0
  234. ccxt/async_support/hitbtc3.py +16 -0
  235. ccxt/async_support/hitobit.py +391 -0
  236. ccxt/async_support/hollaex.py +1813 -0
  237. ccxt/async_support/htx.py +8506 -0
  238. ccxt/async_support/huobi.py +16 -0
  239. ccxt/async_support/huobijp.py +1801 -0
  240. ccxt/async_support/hyperliquid.py +2431 -0
  241. ccxt/async_support/idex.py +1766 -0
  242. ccxt/async_support/independentreserve.py +784 -0
  243. ccxt/async_support/indodax.py +1247 -0
  244. ccxt/async_support/jibitex.py +395 -0
  245. ccxt/async_support/kraken.py +2894 -0
  246. ccxt/async_support/krakenfutures.py +2601 -0
  247. ccxt/async_support/kucoin.py +4602 -0
  248. ccxt/async_support/kucoinfutures.py +2698 -0
  249. ccxt/async_support/kuna.py +1841 -0
  250. ccxt/async_support/latoken.py +1664 -0
  251. ccxt/async_support/lbank.py +2683 -0
  252. ccxt/async_support/luno.py +1067 -0
  253. ccxt/async_support/lykke.py +1270 -0
  254. ccxt/async_support/mercado.py +842 -0
  255. ccxt/async_support/mexc.py +5369 -0
  256. ccxt/async_support/ndax.py +2354 -0
  257. ccxt/async_support/nobitex.py +419 -0
  258. ccxt/async_support/novadax.py +1484 -0
  259. ccxt/async_support/oceanex.py +903 -0
  260. ccxt/async_support/okcoin.py +2936 -0
  261. ccxt/async_support/okexchange.py +349 -0
  262. ccxt/async_support/okx.py +7827 -0
  263. ccxt/async_support/ompfinex.py +472 -0
  264. ccxt/async_support/onetrading.py +1911 -0
  265. ccxt/async_support/oxfun.py +2773 -0
  266. ccxt/async_support/p2b.py +1194 -0
  267. ccxt/async_support/paradex.py +2015 -0
  268. ccxt/async_support/paymium.py +564 -0
  269. ccxt/async_support/phemex.py +4473 -0
  270. ccxt/async_support/poloniex.py +2232 -0
  271. ccxt/async_support/poloniexfutures.py +1717 -0
  272. ccxt/async_support/probit.py +1734 -0
  273. ccxt/async_support/ramzinex.py +476 -0
  274. ccxt/async_support/sarmayex.py +357 -0
  275. ccxt/async_support/sarrafex.py +478 -0
  276. ccxt/async_support/tabdeal.py +364 -0
  277. ccxt/async_support/tetherland.py +349 -0
  278. ccxt/async_support/timex.py +1593 -0
  279. ccxt/async_support/tokocrypto.py +2405 -0
  280. ccxt/async_support/tradeogre.py +608 -0
  281. ccxt/async_support/twox.py +326 -0
  282. ccxt/async_support/ubitex.py +409 -0
  283. ccxt/async_support/upbit.py +1833 -0
  284. ccxt/async_support/vertex.py +2922 -0
  285. ccxt/async_support/wallex.py +445 -0
  286. ccxt/async_support/wavesexchange.py +2473 -0
  287. ccxt/async_support/wazirx.py +1224 -0
  288. ccxt/async_support/whitebit.py +2469 -0
  289. ccxt/async_support/woo.py +3114 -0
  290. ccxt/async_support/woofipro.py +2533 -0
  291. ccxt/async_support/xt.py +4454 -0
  292. ccxt/async_support/yobit.py +1283 -0
  293. ccxt/async_support/zaif.py +725 -0
  294. ccxt/async_support/zonda.py +1828 -0
  295. ccxt/base/__init__.py +27 -0
  296. ccxt/base/decimal_to_precision.py +174 -0
  297. ccxt/base/errors.py +242 -0
  298. ccxt/base/exchange.py +5941 -0
  299. ccxt/base/precise.py +287 -0
  300. ccxt/base/types.py +502 -0
  301. ccxt/bequant.py +33 -0
  302. ccxt/bigone.py +2112 -0
  303. ccxt/binance.py +12233 -0
  304. ccxt/binancecoinm.py +45 -0
  305. ccxt/binanceus.py +211 -0
  306. ccxt/binanceusdm.py +58 -0
  307. ccxt/bingx.py +4324 -0
  308. ccxt/bit2c.py +866 -0
  309. ccxt/bitbank.py +1001 -0
  310. ccxt/bitbay.py +17 -0
  311. ccxt/bitbns.py +1154 -0
  312. ccxt/bitcoincom.py +17 -0
  313. ccxt/bitfinex.py +1617 -0
  314. ccxt/bitfinex2.py +3552 -0
  315. ccxt/bitflyer.py +995 -0
  316. ccxt/bitget.py +8272 -0
  317. ccxt/bithumb.py +1061 -0
  318. ccxt/bitimen.py +401 -0
  319. ccxt/bitir.py +490 -0
  320. ccxt/bitmart.py +4415 -0
  321. ccxt/bitmex.py +2756 -0
  322. ccxt/bitopro.py +1630 -0
  323. ccxt/bitpanda.py +16 -0
  324. ccxt/bitpin.py +454 -0
  325. ccxt/bitrue.py +3026 -0
  326. ccxt/bitso.py +1670 -0
  327. ccxt/bitstamp.py +2203 -0
  328. ccxt/bitteam.py +2239 -0
  329. ccxt/bitvavo.py +1968 -0
  330. ccxt/bl3p.py +485 -0
  331. ccxt/blockchaincom.py +1104 -0
  332. ccxt/blofin.py +2066 -0
  333. ccxt/btcalpha.py +891 -0
  334. ccxt/btcbox.py +544 -0
  335. ccxt/btcmarkets.py +1221 -0
  336. ccxt/btcturk.py +911 -0
  337. ccxt/bybit.py +8158 -0
  338. ccxt/cex.py +1605 -0
  339. ccxt/coinbase.py +4474 -0
  340. ccxt/coinbaseadvanced.py +17 -0
  341. ccxt/coinbaseexchange.py +1734 -0
  342. ccxt/coinbaseinternational.py +1899 -0
  343. ccxt/coincatch.py +5069 -0
  344. ccxt/coincheck.py +815 -0
  345. ccxt/coinex.py +5525 -0
  346. ccxt/coinlist.py +2243 -0
  347. ccxt/coinmate.py +1067 -0
  348. ccxt/coinmetro.py +1797 -0
  349. ccxt/coinone.py +1127 -0
  350. ccxt/coinsph.py +1850 -0
  351. ccxt/coinspot.py +534 -0
  352. ccxt/cryptocom.py +2822 -0
  353. ccxt/currencycom.py +1950 -0
  354. ccxt/delta.py +3376 -0
  355. ccxt/deribit.py +3437 -0
  356. ccxt/digifinex.py +3959 -0
  357. ccxt/eterex.py +286 -0
  358. ccxt/excoino.py +399 -0
  359. ccxt/exir.py +375 -0
  360. ccxt/exmo.py +2462 -0
  361. ccxt/exnovin.py +360 -0
  362. ccxt/farhadexchange.py +266 -0
  363. ccxt/fmfwio.py +34 -0
  364. ccxt/gate.py +6975 -0
  365. ccxt/gateio.py +16 -0
  366. ccxt/gemini.py +1824 -0
  367. ccxt/hashkey.py +4150 -0
  368. ccxt/hitbtc.py +3423 -0
  369. ccxt/hitbtc3.py +16 -0
  370. ccxt/hitobit.py +391 -0
  371. ccxt/hollaex.py +1813 -0
  372. ccxt/htx.py +8505 -0
  373. ccxt/huobi.py +16 -0
  374. ccxt/huobijp.py +1801 -0
  375. ccxt/hyperliquid.py +2430 -0
  376. ccxt/idex.py +1766 -0
  377. ccxt/independentreserve.py +784 -0
  378. ccxt/indodax.py +1247 -0
  379. ccxt/jibitex.py +395 -0
  380. ccxt/kraken.py +2894 -0
  381. ccxt/krakenfutures.py +2601 -0
  382. ccxt/kucoin.py +4601 -0
  383. ccxt/kucoinfutures.py +2698 -0
  384. ccxt/kuna.py +1841 -0
  385. ccxt/latoken.py +1664 -0
  386. ccxt/lbank.py +2682 -0
  387. ccxt/luno.py +1067 -0
  388. ccxt/lykke.py +1270 -0
  389. ccxt/mercado.py +842 -0
  390. ccxt/mexc.py +5369 -0
  391. ccxt/ndax.py +2354 -0
  392. ccxt/nobitex.py +419 -0
  393. ccxt/novadax.py +1484 -0
  394. ccxt/oceanex.py +903 -0
  395. ccxt/okcoin.py +2936 -0
  396. ccxt/okexchange.py +349 -0
  397. ccxt/okx.py +7826 -0
  398. ccxt/ompfinex.py +472 -0
  399. ccxt/onetrading.py +1911 -0
  400. ccxt/oxfun.py +2772 -0
  401. ccxt/p2b.py +1194 -0
  402. ccxt/paradex.py +2015 -0
  403. ccxt/paymium.py +564 -0
  404. ccxt/phemex.py +4473 -0
  405. ccxt/poloniex.py +2232 -0
  406. ccxt/poloniexfutures.py +1717 -0
  407. ccxt/pro/__init__.py +149 -0
  408. ccxt/pro/alpaca.py +685 -0
  409. ccxt/pro/ascendex.py +916 -0
  410. ccxt/pro/bequant.py +38 -0
  411. ccxt/pro/binance.py +3488 -0
  412. ccxt/pro/binancecoinm.py +28 -0
  413. ccxt/pro/binanceus.py +48 -0
  414. ccxt/pro/binanceusdm.py +31 -0
  415. ccxt/pro/bingx.py +1264 -0
  416. ccxt/pro/bitcoincom.py +34 -0
  417. ccxt/pro/bitfinex.py +621 -0
  418. ccxt/pro/bitfinex2.py +1083 -0
  419. ccxt/pro/bitget.py +1692 -0
  420. ccxt/pro/bithumb.py +368 -0
  421. ccxt/pro/bitmart.py +1449 -0
  422. ccxt/pro/bitmex.py +1656 -0
  423. ccxt/pro/bitopro.py +445 -0
  424. ccxt/pro/bitpanda.py +15 -0
  425. ccxt/pro/bitrue.py +447 -0
  426. ccxt/pro/bitstamp.py +522 -0
  427. ccxt/pro/bitvavo.py +1270 -0
  428. ccxt/pro/blockchaincom.py +738 -0
  429. ccxt/pro/blofin.py +692 -0
  430. ccxt/pro/bybit.py +2000 -0
  431. ccxt/pro/cex.py +1440 -0
  432. ccxt/pro/coinbase.py +678 -0
  433. ccxt/pro/coinbaseadvanced.py +16 -0
  434. ccxt/pro/coinbaseexchange.py +895 -0
  435. ccxt/pro/coinbaseinternational.py +620 -0
  436. ccxt/pro/coincatch.py +1464 -0
  437. ccxt/pro/coincheck.py +199 -0
  438. ccxt/pro/coinex.py +1061 -0
  439. ccxt/pro/coinone.py +395 -0
  440. ccxt/pro/cryptocom.py +947 -0
  441. ccxt/pro/currencycom.py +536 -0
  442. ccxt/pro/deribit.py +892 -0
  443. ccxt/pro/exmo.py +629 -0
  444. ccxt/pro/gate.py +1416 -0
  445. ccxt/pro/gateio.py +15 -0
  446. ccxt/pro/gemini.py +865 -0
  447. ccxt/pro/hashkey.py +802 -0
  448. ccxt/pro/hitbtc.py +1216 -0
  449. ccxt/pro/hollaex.py +563 -0
  450. ccxt/pro/htx.py +2215 -0
  451. ccxt/pro/huobi.py +15 -0
  452. ccxt/pro/huobijp.py +570 -0
  453. ccxt/pro/hyperliquid.py +525 -0
  454. ccxt/pro/idex.py +672 -0
  455. ccxt/pro/independentreserve.py +270 -0
  456. ccxt/pro/kraken.py +1356 -0
  457. ccxt/pro/krakenfutures.py +1492 -0
  458. ccxt/pro/kucoin.py +1133 -0
  459. ccxt/pro/kucoinfutures.py +1081 -0
  460. ccxt/pro/lbank.py +843 -0
  461. ccxt/pro/luno.py +303 -0
  462. ccxt/pro/mexc.py +1122 -0
  463. ccxt/pro/ndax.py +506 -0
  464. ccxt/pro/okcoin.py +698 -0
  465. ccxt/pro/okx.py +1851 -0
  466. ccxt/pro/onetrading.py +1275 -0
  467. ccxt/pro/oxfun.py +950 -0
  468. ccxt/pro/p2b.py +419 -0
  469. ccxt/pro/paradex.py +352 -0
  470. ccxt/pro/phemex.py +1441 -0
  471. ccxt/pro/poloniex.py +1166 -0
  472. ccxt/pro/poloniexfutures.py +990 -0
  473. ccxt/pro/probit.py +551 -0
  474. ccxt/pro/upbit.py +520 -0
  475. ccxt/pro/vertex.py +943 -0
  476. ccxt/pro/wazirx.py +749 -0
  477. ccxt/pro/whitebit.py +864 -0
  478. ccxt/pro/woo.py +1078 -0
  479. ccxt/pro/woofipro.py +1183 -0
  480. ccxt/pro/xt.py +1067 -0
  481. ccxt/probit.py +1734 -0
  482. ccxt/ramzinex.py +476 -0
  483. ccxt/sarmayex.py +357 -0
  484. ccxt/sarrafex.py +478 -0
  485. ccxt/static_dependencies/__init__.py +1 -0
  486. ccxt/static_dependencies/ecdsa/__init__.py +14 -0
  487. ccxt/static_dependencies/ecdsa/_version.py +520 -0
  488. ccxt/static_dependencies/ecdsa/curves.py +56 -0
  489. ccxt/static_dependencies/ecdsa/der.py +221 -0
  490. ccxt/static_dependencies/ecdsa/ecdsa.py +310 -0
  491. ccxt/static_dependencies/ecdsa/ellipticcurve.py +197 -0
  492. ccxt/static_dependencies/ecdsa/keys.py +332 -0
  493. ccxt/static_dependencies/ecdsa/numbertheory.py +531 -0
  494. ccxt/static_dependencies/ecdsa/rfc6979.py +100 -0
  495. ccxt/static_dependencies/ecdsa/util.py +266 -0
  496. ccxt/static_dependencies/ethereum/__init__.py +7 -0
  497. ccxt/static_dependencies/ethereum/abi/__init__.py +16 -0
  498. ccxt/static_dependencies/ethereum/abi/abi.py +19 -0
  499. ccxt/static_dependencies/ethereum/abi/base.py +152 -0
  500. ccxt/static_dependencies/ethereum/abi/codec.py +217 -0
  501. ccxt/static_dependencies/ethereum/abi/constants.py +3 -0
  502. ccxt/static_dependencies/ethereum/abi/decoding.py +565 -0
  503. ccxt/static_dependencies/ethereum/abi/encoding.py +720 -0
  504. ccxt/static_dependencies/ethereum/abi/exceptions.py +139 -0
  505. ccxt/static_dependencies/ethereum/abi/grammar.py +443 -0
  506. ccxt/static_dependencies/ethereum/abi/packed.py +13 -0
  507. ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
  508. ccxt/static_dependencies/ethereum/abi/registry.py +643 -0
  509. ccxt/static_dependencies/ethereum/abi/tools/__init__.py +3 -0
  510. ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +230 -0
  511. ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
  512. ccxt/static_dependencies/ethereum/abi/utils/numeric.py +83 -0
  513. ccxt/static_dependencies/ethereum/abi/utils/padding.py +27 -0
  514. ccxt/static_dependencies/ethereum/abi/utils/string.py +19 -0
  515. ccxt/static_dependencies/ethereum/account/__init__.py +3 -0
  516. ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +4 -0
  517. ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +239 -0
  518. ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +40 -0
  519. ccxt/static_dependencies/ethereum/account/messages.py +263 -0
  520. ccxt/static_dependencies/ethereum/account/py.typed +0 -0
  521. ccxt/static_dependencies/ethereum/hexbytes/__init__.py +5 -0
  522. ccxt/static_dependencies/ethereum/hexbytes/_utils.py +54 -0
  523. ccxt/static_dependencies/ethereum/hexbytes/main.py +65 -0
  524. ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
  525. ccxt/static_dependencies/ethereum/typing/__init__.py +63 -0
  526. ccxt/static_dependencies/ethereum/typing/abi.py +6 -0
  527. ccxt/static_dependencies/ethereum/typing/bls.py +7 -0
  528. ccxt/static_dependencies/ethereum/typing/discovery.py +5 -0
  529. ccxt/static_dependencies/ethereum/typing/encoding.py +7 -0
  530. ccxt/static_dependencies/ethereum/typing/enums.py +17 -0
  531. ccxt/static_dependencies/ethereum/typing/ethpm.py +9 -0
  532. ccxt/static_dependencies/ethereum/typing/evm.py +20 -0
  533. ccxt/static_dependencies/ethereum/typing/networks.py +1122 -0
  534. ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
  535. ccxt/static_dependencies/ethereum/utils/__init__.py +115 -0
  536. ccxt/static_dependencies/ethereum/utils/abi.py +72 -0
  537. ccxt/static_dependencies/ethereum/utils/address.py +171 -0
  538. ccxt/static_dependencies/ethereum/utils/applicators.py +151 -0
  539. ccxt/static_dependencies/ethereum/utils/conversions.py +190 -0
  540. ccxt/static_dependencies/ethereum/utils/currency.py +107 -0
  541. ccxt/static_dependencies/ethereum/utils/curried/__init__.py +269 -0
  542. ccxt/static_dependencies/ethereum/utils/debug.py +20 -0
  543. ccxt/static_dependencies/ethereum/utils/decorators.py +132 -0
  544. ccxt/static_dependencies/ethereum/utils/encoding.py +6 -0
  545. ccxt/static_dependencies/ethereum/utils/exceptions.py +4 -0
  546. ccxt/static_dependencies/ethereum/utils/functional.py +75 -0
  547. ccxt/static_dependencies/ethereum/utils/hexadecimal.py +74 -0
  548. ccxt/static_dependencies/ethereum/utils/humanize.py +188 -0
  549. ccxt/static_dependencies/ethereum/utils/logging.py +159 -0
  550. ccxt/static_dependencies/ethereum/utils/module_loading.py +31 -0
  551. ccxt/static_dependencies/ethereum/utils/numeric.py +43 -0
  552. ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
  553. ccxt/static_dependencies/ethereum/utils/toolz.py +76 -0
  554. ccxt/static_dependencies/ethereum/utils/types.py +54 -0
  555. ccxt/static_dependencies/ethereum/utils/typing/__init__.py +18 -0
  556. ccxt/static_dependencies/ethereum/utils/typing/misc.py +14 -0
  557. ccxt/static_dependencies/ethereum/utils/units.py +31 -0
  558. ccxt/static_dependencies/keccak/__init__.py +3 -0
  559. ccxt/static_dependencies/keccak/keccak.py +197 -0
  560. ccxt/static_dependencies/lark/__init__.py +38 -0
  561. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  562. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  563. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  564. ccxt/static_dependencies/lark/common.py +86 -0
  565. ccxt/static_dependencies/lark/exceptions.py +292 -0
  566. ccxt/static_dependencies/lark/grammar.py +130 -0
  567. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  568. ccxt/static_dependencies/lark/indenter.py +143 -0
  569. ccxt/static_dependencies/lark/lark.py +658 -0
  570. ccxt/static_dependencies/lark/lexer.py +678 -0
  571. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  572. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  573. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  574. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  575. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  576. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  577. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  578. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  579. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  580. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  581. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  582. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  583. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  584. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  585. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  586. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  587. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  588. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  589. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  590. ccxt/static_dependencies/lark/tree.py +267 -0
  591. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  592. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  593. ccxt/static_dependencies/lark/utils.py +343 -0
  594. ccxt/static_dependencies/lark/visitors.py +596 -0
  595. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  596. ccxt/static_dependencies/marshmallow/base.py +65 -0
  597. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  598. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  599. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  600. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  601. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  602. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  603. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  604. ccxt/static_dependencies/marshmallow/types.py +12 -0
  605. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  606. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  607. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  608. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  609. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  610. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  611. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  612. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  613. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  614. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  615. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  616. ccxt/static_dependencies/msgpack/__init__.py +55 -0
  617. ccxt/static_dependencies/msgpack/exceptions.py +48 -0
  618. ccxt/static_dependencies/msgpack/ext.py +168 -0
  619. ccxt/static_dependencies/msgpack/fallback.py +951 -0
  620. ccxt/static_dependencies/parsimonious/__init__.py +10 -0
  621. ccxt/static_dependencies/parsimonious/exceptions.py +105 -0
  622. ccxt/static_dependencies/parsimonious/expressions.py +479 -0
  623. ccxt/static_dependencies/parsimonious/grammar.py +487 -0
  624. ccxt/static_dependencies/parsimonious/nodes.py +325 -0
  625. ccxt/static_dependencies/parsimonious/utils.py +40 -0
  626. ccxt/static_dependencies/starknet/__init__.py +0 -0
  627. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  628. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  629. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  630. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  631. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  632. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  633. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  634. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  635. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  636. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  637. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  638. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  639. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  640. ccxt/static_dependencies/starknet/common.py +15 -0
  641. ccxt/static_dependencies/starknet/constants.py +39 -0
  642. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  643. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  644. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  645. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  646. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  647. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  648. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  649. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  650. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  651. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  652. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  653. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  654. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  655. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  656. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  657. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  658. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  659. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  660. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  661. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  662. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  663. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  664. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  665. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  666. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  667. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  668. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  669. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  670. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  671. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  672. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  673. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  674. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  675. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  676. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  677. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  678. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  679. ccxt/static_dependencies/starkware/__init__.py +0 -0
  680. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  681. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  682. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  683. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  684. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  685. ccxt/static_dependencies/sympy/__init__.py +0 -0
  686. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  687. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  688. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  689. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  690. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  691. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  692. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  693. ccxt/static_dependencies/toolz/__init__.py +26 -0
  694. ccxt/static_dependencies/toolz/_signatures.py +784 -0
  695. ccxt/static_dependencies/toolz/_version.py +520 -0
  696. ccxt/static_dependencies/toolz/compatibility.py +30 -0
  697. ccxt/static_dependencies/toolz/curried/__init__.py +101 -0
  698. ccxt/static_dependencies/toolz/curried/exceptions.py +22 -0
  699. ccxt/static_dependencies/toolz/curried/operator.py +22 -0
  700. ccxt/static_dependencies/toolz/dicttoolz.py +339 -0
  701. ccxt/static_dependencies/toolz/functoolz.py +1049 -0
  702. ccxt/static_dependencies/toolz/itertoolz.py +1057 -0
  703. ccxt/static_dependencies/toolz/recipes.py +46 -0
  704. ccxt/static_dependencies/toolz/utils.py +9 -0
  705. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  706. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  707. ccxt/tabdeal.py +364 -0
  708. ccxt/test/__init__.py +3 -0
  709. ccxt/test/base/__init__.py +29 -0
  710. ccxt/test/base/test_account.py +26 -0
  711. ccxt/test/base/test_balance.py +56 -0
  712. ccxt/test/base/test_borrow_interest.py +35 -0
  713. ccxt/test/base/test_borrow_rate.py +32 -0
  714. ccxt/test/base/test_calculate_fee.py +51 -0
  715. ccxt/test/base/test_crypto.py +127 -0
  716. ccxt/test/base/test_currency.py +76 -0
  717. ccxt/test/base/test_datetime.py +109 -0
  718. ccxt/test/base/test_decimal_to_precision.py +392 -0
  719. ccxt/test/base/test_deep_extend.py +68 -0
  720. ccxt/test/base/test_deposit_withdrawal.py +50 -0
  721. ccxt/test/base/test_exchange_datetime_functions.py +76 -0
  722. ccxt/test/base/test_funding_rate_history.py +29 -0
  723. ccxt/test/base/test_last_price.py +31 -0
  724. ccxt/test/base/test_ledger_entry.py +45 -0
  725. ccxt/test/base/test_ledger_item.py +48 -0
  726. ccxt/test/base/test_leverage_tier.py +33 -0
  727. ccxt/test/base/test_liquidation.py +50 -0
  728. ccxt/test/base/test_margin_mode.py +24 -0
  729. ccxt/test/base/test_margin_modification.py +35 -0
  730. ccxt/test/base/test_market.py +193 -0
  731. ccxt/test/base/test_number.py +411 -0
  732. ccxt/test/base/test_ohlcv.py +33 -0
  733. ccxt/test/base/test_open_interest.py +32 -0
  734. ccxt/test/base/test_order.py +64 -0
  735. ccxt/test/base/test_order_book.py +69 -0
  736. ccxt/test/base/test_position.py +60 -0
  737. ccxt/test/base/test_shared_methods.py +353 -0
  738. ccxt/test/base/test_status.py +24 -0
  739. ccxt/test/base/test_throttle.py +126 -0
  740. ccxt/test/base/test_ticker.py +92 -0
  741. ccxt/test/base/test_trade.py +47 -0
  742. ccxt/test/base/test_trading_fee.py +26 -0
  743. ccxt/test/base/test_transaction.py +39 -0
  744. ccxt/test/test_async.py +1649 -0
  745. ccxt/test/test_sync.py +1648 -0
  746. ccxt/test/tests_async.py +1558 -0
  747. ccxt/test/tests_helpers.py +287 -0
  748. ccxt/test/tests_init.py +39 -0
  749. ccxt/test/tests_sync.py +1555 -0
  750. ccxt/tetherland.py +349 -0
  751. ccxt/timex.py +1593 -0
  752. ccxt/tokocrypto.py +2405 -0
  753. ccxt/tradeogre.py +608 -0
  754. ccxt/twox.py +326 -0
  755. ccxt/ubitex.py +409 -0
  756. ccxt/upbit.py +1833 -0
  757. ccxt/vertex.py +2922 -0
  758. ccxt/wallex.py +445 -0
  759. ccxt/wavesexchange.py +2472 -0
  760. ccxt/wazirx.py +1224 -0
  761. ccxt/whitebit.py +2469 -0
  762. ccxt/woo.py +3114 -0
  763. ccxt/woofipro.py +2533 -0
  764. ccxt/xt.py +4453 -0
  765. ccxt/yobit.py +1283 -0
  766. ccxt/zaif.py +725 -0
  767. ccxt/zonda.py +1828 -0
  768. ccxt_ir-4.3.46.0.1.dist-info/LICENSE.txt +21 -0
  769. ccxt_ir-4.3.46.0.1.dist-info/METADATA +655 -0
  770. ccxt_ir-4.3.46.0.1.dist-info/RECORD +772 -0
  771. ccxt_ir-4.3.46.0.1.dist-info/WHEEL +6 -0
  772. ccxt_ir-4.3.46.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1899 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+
6
+ from ccxt.async_support.base.exchange import Exchange
7
+ from ccxt.abstract.coinbaseinternational import ImplicitAPI
8
+ import hashlib
9
+ from ccxt.base.types import Balances, Currencies, Currency, Int, Market, Order, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
+ from typing import List
11
+ from typing import Any
12
+ from ccxt.base.errors import ExchangeError
13
+ from ccxt.base.errors import AuthenticationError
14
+ from ccxt.base.errors import PermissionDenied
15
+ from ccxt.base.errors import ArgumentsRequired
16
+ from ccxt.base.errors import BadRequest
17
+ from ccxt.base.errors import InvalidOrder
18
+ from ccxt.base.errors import DuplicateOrderId
19
+ from ccxt.base.decimal_to_precision import TICK_SIZE
20
+ from ccxt.base.precise import Precise
21
+
22
+
23
+ class coinbaseinternational(Exchange, ImplicitAPI):
24
+
25
+ def describe(self):
26
+ return self.deep_extend(super(coinbaseinternational, self).describe(), {
27
+ 'id': 'coinbaseinternational',
28
+ 'name': 'Coinbase International',
29
+ 'countries': ['US'],
30
+ 'certified': True,
31
+ 'pro': True,
32
+ 'rateLimit': 100, # 10 requests per second
33
+ 'version': 'v1',
34
+ 'userAgent': self.userAgents['chrome'],
35
+ 'headers': {
36
+ 'CB-VERSION': '2018-05-30',
37
+ },
38
+ 'has': {
39
+ 'CORS': True,
40
+ 'spot': True,
41
+ 'margin': True,
42
+ 'swap': True,
43
+ 'future': True,
44
+ 'option': False,
45
+ 'addMargin': False,
46
+ 'cancelAllOrders': True,
47
+ 'cancelOrder': True,
48
+ 'cancelOrders': False,
49
+ 'closeAllPositions': False,
50
+ 'closePosition': False,
51
+ 'createDepositAddress': True,
52
+ 'createLimitBuyOrder': True,
53
+ 'createLimitSellOrder': True,
54
+ 'createMarketBuyOrder': True,
55
+ 'createMarketBuyOrderWithCost': False,
56
+ 'createMarketOrderWithCost': False,
57
+ 'createMarketSellOrder': True,
58
+ 'createMarketSellOrderWithCost': False,
59
+ 'createOrder': True,
60
+ 'createPostOnlyOrder': True,
61
+ 'createReduceOnlyOrder': False,
62
+ 'createStopLimitOrder': True,
63
+ 'createStopMarketOrder': True,
64
+ 'createStopOrder': True,
65
+ 'editOrder': True,
66
+ 'fetchAccounts': True,
67
+ 'fetchBalance': True,
68
+ 'fetchBidsAsks': False,
69
+ 'fetchBorrowRateHistories': False,
70
+ 'fetchBorrowRateHistory': False,
71
+ 'fetchCanceledOrders': False,
72
+ 'fetchClosedOrders': False,
73
+ 'fetchCrossBorrowRate': False,
74
+ 'fetchCrossBorrowRates': False,
75
+ 'fetchCurrencies': True,
76
+ 'fetchDeposits': True,
77
+ 'fetchFundingHistory': False,
78
+ 'fetchFundingRate': False,
79
+ 'fetchFundingRateHistory': True,
80
+ 'fetchFundingRates': False,
81
+ 'fetchIndexOHLCV': False,
82
+ 'fetchIsolatedBorrowRate': False,
83
+ 'fetchIsolatedBorrowRates': False,
84
+ 'fetchL2OrderBook': False,
85
+ 'fetchLedger': False,
86
+ 'fetchLeverage': False,
87
+ 'fetchLeverageTiers': False,
88
+ 'fetchMarginAdjustmentHistory': False,
89
+ 'fetchMarginMode': False,
90
+ 'fetchMarkets': True,
91
+ 'fetchMarkOHLCV': False,
92
+ 'fetchMyBuys': True,
93
+ 'fetchMySells': True,
94
+ 'fetchMyTrades': True,
95
+ 'fetchOHLCV': False,
96
+ 'fetchOpenInterestHistory': False,
97
+ 'fetchOpenOrders': True,
98
+ 'fetchOrder': True,
99
+ 'fetchOrderBook': False,
100
+ 'fetchOrders': False,
101
+ 'fetchPosition': True,
102
+ 'fetchPositionHistory': False,
103
+ 'fetchPositionMode': False,
104
+ 'fetchPositions': True,
105
+ 'fetchPositionsHistory': False,
106
+ 'fetchPositionsRisk': False,
107
+ 'fetchPremiumIndexOHLCV': False,
108
+ 'fetchTicker': True,
109
+ 'fetchTickers': True,
110
+ 'fetchTime': False,
111
+ 'fetchTrades': False,
112
+ 'fetchTradingFee': False,
113
+ 'fetchTradingFees': False,
114
+ 'fetchWithdrawals': True,
115
+ 'reduceMargin': False,
116
+ 'sandbox': True,
117
+ 'setLeverage': False,
118
+ 'setMargin': True,
119
+ 'setMarginMode': False,
120
+ 'setPositionMode': False,
121
+ 'withdraw': True,
122
+ },
123
+ 'urls': {
124
+ 'logo': 'https://github.com/ccxt/ccxt/assets/43336371/866ae638-6ab5-4ebf-ab2c-cdcce9545625',
125
+ 'api': {
126
+ 'rest': 'https://api.international.coinbase.com/api',
127
+ },
128
+ 'test': {
129
+ 'rest': 'https://api-n5e1.coinbase.com/api',
130
+ },
131
+ 'www': 'https://international.coinbase.com',
132
+ 'doc': [
133
+ 'https://docs.cloud.coinbase.com/intx/docs',
134
+ ],
135
+ 'fees': [
136
+ 'https://help.coinbase.com/en/international-exchange/trading-deposits-withdrawals/international-exchange-fees',
137
+ ],
138
+ 'referral': '',
139
+ },
140
+ 'requiredCredentials': {
141
+ 'apiKey': True,
142
+ 'secret': True,
143
+ 'password': True,
144
+ },
145
+ 'api': {
146
+ 'v1': {
147
+ 'public': {
148
+ 'get': [
149
+ 'assets',
150
+ 'assets/{assets}',
151
+ 'assets/{asset}/networks',
152
+ 'instruments',
153
+ 'instruments/{instrument}',
154
+ 'instruments/{instrument}/quote',
155
+ 'instruments/{instrument}/funding',
156
+ '',
157
+ ],
158
+ },
159
+ 'private': {
160
+ 'get': [
161
+ 'orders',
162
+ 'orders/{id}',
163
+ 'portfolios',
164
+ 'portfolios/{portfolio}',
165
+ 'portfolios/{portfolio}/detail',
166
+ 'portfolios/{portfolio}/summary',
167
+ 'portfolios/{portfolio}/balances',
168
+ 'portfolios/{portfolio}/balances/{asset}',
169
+ 'portfolios/{portfolio}/positions',
170
+ 'portfolios/{portfolio}/positions/{instrument}',
171
+ 'portfolios/fills',
172
+ 'portfolios/{portfolio}/fills',
173
+ 'transfers',
174
+ 'transfers/{transfer_uuid}',
175
+ ],
176
+ 'post': [
177
+ 'orders',
178
+ 'portfolios',
179
+ 'portfolios/margin',
180
+ 'portfolios/transfer',
181
+ 'transfers/withdraw',
182
+ 'transfers/address',
183
+ 'transfers/create-counterparty-id',
184
+ 'transfers/validate-counterparty-id',
185
+ 'transfers/withdraw/counterparty',
186
+ ],
187
+ 'put': [
188
+ 'orders/{id}',
189
+ 'portfolios/{portfolio}',
190
+ ],
191
+ 'delete': [
192
+ 'orders',
193
+ 'orders/{id}',
194
+ ],
195
+ },
196
+ },
197
+ },
198
+ 'fees': {
199
+ 'trading': {
200
+ 'taker': self.parse_number('0.004'),
201
+ 'maker': self.parse_number('0.002'),
202
+ 'tierBased': True,
203
+ 'percentage': True,
204
+ 'tiers': {
205
+ 'taker': [
206
+ [self.parse_number('0'), self.parse_number('0.004')],
207
+ [self.parse_number('1000000'), self.parse_number('0.004')],
208
+ [self.parse_number('5000000'), self.parse_number('0.0035')],
209
+ [self.parse_number('10000000'), self.parse_number('0.0035')],
210
+ [self.parse_number('50000000'), self.parse_number('0.003')],
211
+ [self.parse_number('250000000'), self.parse_number('0.0025')],
212
+ ],
213
+ 'maker': [
214
+ [self.parse_number('0'), self.parse_number('0.002')],
215
+ [self.parse_number('1000000'), self.parse_number('0.0016')],
216
+ [self.parse_number('5000000'), self.parse_number('0.001')],
217
+ [self.parse_number('10000000'), self.parse_number('0.0008')],
218
+ [self.parse_number('50000000'), self.parse_number('0.0005')],
219
+ [self.parse_number('250000000'), self.parse_number('0')],
220
+ ],
221
+ },
222
+ },
223
+ },
224
+ 'precisionMode': TICK_SIZE,
225
+ 'exceptions': {
226
+ 'exact': {},
227
+ 'broad': {
228
+ 'DUPLICATE_CLIENT_ORDER_ID': DuplicateOrderId,
229
+ 'Order rejected': InvalidOrder,
230
+ 'market orders must be IoC': InvalidOrder,
231
+ 'tif is required': InvalidOrder,
232
+ 'Invalid replace order request': InvalidOrder,
233
+ 'Unauthorized': PermissionDenied,
234
+ 'invalid result_limit': BadRequest,
235
+ 'is a required field': BadRequest,
236
+ 'Not Found': BadRequest,
237
+ 'ip not allowed': AuthenticationError,
238
+ },
239
+ },
240
+ 'timeframes': {
241
+ '1m': 'ONE_MINUTE',
242
+ '5m': 'FIVE_MINUTE',
243
+ '15m': 'FIFTEEN_MINUTE',
244
+ '30m': 'THIRTY_MINUTE',
245
+ '1h': 'ONE_HOUR',
246
+ '2h': 'TWO_HOUR',
247
+ '6h': 'SIX_HOUR',
248
+ '1d': 'ONE_DAY',
249
+ },
250
+ 'options': {
251
+ 'brokerId': 'nfqkvdjp',
252
+ 'portfolio': '', # default portfolio id
253
+ 'withdraw': {
254
+ 'method': 'v1PrivatePostTransfersWithdraw', # use v1PrivatePostTransfersWithdrawCounterparty for counterparty withdrawals
255
+ },
256
+ 'networksById': {
257
+ 'ethereum': 'ETH',
258
+ 'arbitrum': 'ARBITRUM',
259
+ 'avacchain': 'AVAX',
260
+ 'optimism': 'OPTIMISM',
261
+ 'polygon': 'MATIC',
262
+ 'solana': 'SOL',
263
+ 'bitcoin': 'BTC',
264
+ },
265
+ },
266
+ })
267
+
268
+ async def handle_portfolio_and_params(self, methodName: str, params={}):
269
+ portfolio = None
270
+ portfolio, params = self.handle_option_and_params(params, methodName, 'portfolio')
271
+ if (portfolio is not None) and (portfolio != ''):
272
+ return [portfolio, params]
273
+ defaultPortfolio = self.safe_string(self.options, 'portfolio')
274
+ if (defaultPortfolio is not None) and (defaultPortfolio != ''):
275
+ return [defaultPortfolio, params]
276
+ accounts = await self.fetch_accounts()
277
+ for i in range(0, len(accounts)):
278
+ account = accounts[i]
279
+ info = self.safe_dict(account, 'info', {})
280
+ if self.safe_bool(info, 'is_default'):
281
+ portfolioId = self.safe_string(info, 'portfolio_id')
282
+ self.options['portfolio'] = portfolioId
283
+ return [portfolioId, params]
284
+ raise ArgumentsRequired(self.id + ' ' + methodName + '() requires a portfolio parameter or set the default portfolio with self.options["portfolio"]')
285
+
286
+ async def handle_network_id_and_params(self, currencyCode: str, methodName: str, params):
287
+ networkId = None
288
+ networkId, params = self.handle_option_and_params(params, methodName, 'network_arn_id')
289
+ if networkId is None:
290
+ await self.load_currency_networks(currencyCode)
291
+ networks = self.currencies[currencyCode]['networks']
292
+ network = self.safe_string_2(params, 'networkCode', 'network')
293
+ if network is None:
294
+ # find default network
295
+ if self.is_empty(networks):
296
+ raise BadRequest(self.id + ' createDepositAddress network not found for currency ' + currencyCode + ' please specify networkId in params')
297
+ defaultNetwork = self.find_default_network(networks)
298
+ networkId = defaultNetwork['id']
299
+ else:
300
+ networkId = self.network_code_to_id(network, currencyCode)
301
+ return [networkId, params]
302
+
303
+ async def fetch_accounts(self, params={}):
304
+ """
305
+ fetch all the accounts associated with a profile
306
+ :see: https://docs.cloud.coinbase.com/intx/reference/getportfolios
307
+ :param dict [params]: extra parameters specific to the exchange API endpoint
308
+ :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
309
+ """
310
+ await self.load_markets()
311
+ response = await self.v1PrivateGetPortfolios(params)
312
+ #
313
+ # [
314
+ # {
315
+ # "portfolio_id":"1ap32qsc-1-0",
316
+ # "portfolio_uuid":"028d7f6c-b92c-7361-8b7e-2932711e5a22",
317
+ # "name":"CCXT Portfolio 030624-17:16",
318
+ # "user_uuid":"e6cf46b6-a32f-5fa7-addb-3324d4526fbd",
319
+ # "maker_fee_rate":"0",
320
+ # "taker_fee_rate":"0.0002",
321
+ # "trading_lock":false,
322
+ # "borrow_disabled":false,
323
+ # "is_lsp":false,
324
+ # "is_default":true,
325
+ # "cross_collateral_enabled":false
326
+ # }
327
+ # ]
328
+ #
329
+ return self.parse_accounts(response, params)
330
+
331
+ def parse_account(self, account):
332
+ #
333
+ # {
334
+ # "portfolio_id":"1ap32qsc-1-0",
335
+ # "portfolio_uuid":"028d7f6c-b92c-7361-8b7e-2932711e5a22",
336
+ # "name":"CCXT Portfolio 030624-17:16",
337
+ # "user_uuid":"e6cf46b6-a32f-5fa7-addb-3324d4526fbd",
338
+ # "maker_fee_rate":"0",
339
+ # "taker_fee_rate":"0.0002",
340
+ # "trading_lock":false,
341
+ # "borrow_disabled":false,
342
+ # "is_lsp":false,
343
+ # "is_default":true,
344
+ # "cross_collateral_enabled":false
345
+ # }
346
+ #
347
+ return {
348
+ 'id': self.safe_string_2(account, 'portfolio_id', 'portfolio_uuid'),
349
+ 'type': None,
350
+ 'code': None,
351
+ 'info': account,
352
+ }
353
+
354
+ async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
355
+ """
356
+ fetches historical funding rate prices
357
+ :see: https://docs.cloud.coinbase.com/intx/reference/getinstrumentfunding
358
+ :param str symbol: unified symbol of the market to fetch the funding rate history for
359
+ :param int [since]: timestamp in ms of the earliest funding rate to fetch
360
+ :param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
361
+ :param dict [params]: extra parameters specific to the exchange API endpoint
362
+ :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)
363
+ """
364
+ if symbol is None:
365
+ raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
366
+ await self.load_markets()
367
+ paginate = False
368
+ paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
369
+ maxEntriesPerRequest = None
370
+ maxEntriesPerRequest, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'maxEntriesPerRequest', 100)
371
+ pageKey = 'ccxtPageKey'
372
+ if paginate:
373
+ return await self.fetch_paginated_call_incremental('fetchFundingRateHistory', symbol, since, limit, params, pageKey, maxEntriesPerRequest)
374
+ market = self.market(symbol)
375
+ page = self.safe_integer(params, pageKey, 1) - 1
376
+ request: dict = {
377
+ 'instrument': market['id'],
378
+ 'result_offset': self.safe_integer_2(params, 'offset', 'result_offset', page * maxEntriesPerRequest),
379
+ }
380
+ if limit is not None:
381
+ request['result_limit'] = limit
382
+ response = await self.v1PublicGetInstrumentsInstrumentFunding(self.extend(request, params))
383
+ #
384
+ # {
385
+ # "pagination":{
386
+ # "result_limit":"25",
387
+ # "result_offset":"0"
388
+ # },
389
+ # "results":[
390
+ # {
391
+ # "instrument_id":"149264167780483072",
392
+ # "funding_rate":"0.000011",
393
+ # "mark_price":"47388.1",
394
+ # "event_time":"2024-02-10T16:00:00Z"
395
+ # },
396
+ # ...
397
+ # ]
398
+ # }
399
+ #
400
+ rawRates = self.safe_list(response, 'results', [])
401
+ return self.parse_funding_rate_histories(rawRates, market, since, limit)
402
+
403
+ def parse_funding_rate_history(self, info, market: Market = None):
404
+ return self.parse_funding_rate(info, market)
405
+
406
+ def parse_funding_rate(self, contract, market: Market = None):
407
+ #
408
+ # {
409
+ # "instrument_id":"149264167780483072",
410
+ # "funding_rate":"0.000011",
411
+ # "mark_price":"47388.1",
412
+ # "event_time":"2024-02-10T16:00:00Z"
413
+ # }
414
+ #
415
+ fundingDatetime = self.safe_string_2(contract, 'event_time', 'time')
416
+ return {
417
+ 'info': contract,
418
+ 'symbol': self.safe_symbol(None, market),
419
+ 'markPrice': self.safe_number(contract, 'mark_price'),
420
+ 'indexPrice': None,
421
+ 'interestRate': None,
422
+ 'estimatedSettlePrice': None,
423
+ 'timestamp': self.parse8601(fundingDatetime),
424
+ 'datetime': fundingDatetime,
425
+ 'fundingRate': self.safe_number(contract, 'funding_rate'),
426
+ 'fundingTimestamp': self.parse8601(fundingDatetime),
427
+ 'fundingDatetime': fundingDatetime,
428
+ 'nextFundingRate': None,
429
+ 'nextFundingTimestamp': None,
430
+ 'nextFundingDatetime': None,
431
+ 'previousFundingRate': None,
432
+ 'previousFundingTimestamp': None,
433
+ 'previousFundingDatetime': None,
434
+ }
435
+
436
+ async def create_deposit_address(self, code: str, params={}):
437
+ """
438
+ create a currency deposit address
439
+ :see: https://docs.cloud.coinbase.com/intx/reference/createaddress
440
+ :see: https://docs.cloud.coinbase.com/intx/reference/createcounterpartyid
441
+ :param str code: unified currency code of the currency for the deposit address
442
+ :param dict [params]: extra parameters specific to the exchange API endpoint
443
+ :param str [params.network_arn_id]: Identifies the blockchain network(e.g., networks/ethereum-mainnet/assets/313ef8a9-ae5a-5f2f-8a56-572c0e2a4d5a) if not provided will pick default
444
+ :param str [params.network]: unified network code to identify the blockchain network
445
+ :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
446
+ """
447
+ await self.load_markets()
448
+ method = None
449
+ method, params = self.handle_option_and_params(params, 'createDepositAddress', 'method', 'v1PrivatePostTransfersAddress')
450
+ portfolio = None
451
+ portfolio, params = await self.handle_portfolio_and_params('createDepositAddress', params)
452
+ request: dict = {
453
+ 'portfolio': portfolio,
454
+ }
455
+ if method == 'v1PrivatePostTransfersAddress':
456
+ currency = self.currency(code)
457
+ request['asset'] = currency['id']
458
+ networkId = None
459
+ networkId, params = await self.handle_network_id_and_params(code, 'createDepositAddress', params)
460
+ request['network_arn_id'] = networkId
461
+ response = await getattr(self, method)(self.extend(request, params))
462
+ #
463
+ # v1PrivatePostTransfersAddress
464
+ # {
465
+ # address: "3LkwYscRyh6tUR1XTqXSJQoJnK7ucC1F4n",
466
+ # network_arn_id: "networks/bitcoin-mainnet/assets/6ecc0dcc-10a2-500e-b315-a3b9abae19ce",
467
+ # destination_tag: "",
468
+ # }
469
+ # v1PrivatePostTransfersCreateCounterpartyId
470
+ # {
471
+ # "portfolio_uuid":"018e0a8b-6b6b-70e0-9689-1e7926c2c8bc",
472
+ # "counterparty_id":"CB2ZPUCZBE"
473
+ # }
474
+ #
475
+ tag = self.safe_string(response, 'destination_tag')
476
+ address = self.safe_string_2(response, 'address', 'counterparty_id')
477
+ return {
478
+ 'currency': code,
479
+ 'tag': tag,
480
+ 'address': address,
481
+ 'info': response,
482
+ }
483
+
484
+ def find_default_network(self, networks):
485
+ networksArray = self.to_array(networks)
486
+ for i in range(0, len(networksArray)):
487
+ info = networksArray[i]['info']
488
+ is_default = self.safe_bool(info, 'is_default', False)
489
+ if is_default is True:
490
+ return networksArray[i]
491
+ return networksArray[0]
492
+
493
+ async def load_currency_networks(self, code, params={}):
494
+ currency = self.currency(code)
495
+ networks = self.safe_dict(currency, 'networks')
496
+ if networks is not None:
497
+ return
498
+ request: dict = {
499
+ 'asset': currency['id'],
500
+ }
501
+ rawNetworks = await self.v1PublicGetAssetsAssetNetworks(request)
502
+ #
503
+ # [
504
+ # {
505
+ # "asset_id" = self.parse_networks(rawNetworks)
506
+
507
+ def parse_networks(self, networks, params={}):
508
+ result: dict = {}
509
+ for i in range(0, len(networks)):
510
+ network = self.extend(self.parse_network(networks[i]), params)
511
+ result[network['network']] = network
512
+ return result
513
+
514
+ def parse_network(self, network, params={}):
515
+ #
516
+ # {
517
+ # "asset_id":"1",
518
+ # "asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
519
+ # "asset_name":"USDC",
520
+ # "network_arn_id":"networks/ethereum-mainnet/assets/9bc140b4-69c3-5fc9-bd0d-b041bcf40039",
521
+ # "min_withdrawal_amt":"1",
522
+ # "max_withdrawal_amt":"100000000",
523
+ # "network_confirms":35,
524
+ # "processing_time":485,
525
+ # "is_default":true,
526
+ # "network_name":"ethereum",
527
+ # "display_name":"Ethereum"
528
+ # }
529
+ #
530
+ currencyId = self.safe_string(network, 'asset_name')
531
+ currencyCode = self.safe_currency_code(currencyId)
532
+ networkId = self.safe_string(network, 'network_arn_id')
533
+ return self.safe_network({
534
+ 'info': network,
535
+ 'id': networkId,
536
+ 'name': self.safe_string(network, 'display_name'),
537
+ 'network': self.network_id_to_code(self.safe_string_n(network, ['network_name', 'display_name', 'network_arn_id'], ''), currencyCode),
538
+ 'active': None,
539
+ 'deposit': None,
540
+ 'withdraw': None,
541
+ 'precision': None,
542
+ 'fee': None,
543
+ 'limits': {
544
+ 'withdraw': {
545
+ 'min': self.safe_number(network, 'min_withdrawal_amt'),
546
+ 'max': self.safe_number(network, 'max_withdrawal_amt'),
547
+ },
548
+ 'deposit': {
549
+ 'min': None,
550
+ 'max': None,
551
+ },
552
+ },
553
+ })
554
+
555
+ async def set_margin(self, symbol: str, amount: float, params={}) -> Any:
556
+ """
557
+ Either adds or reduces margin in order to set the margin to a specific value
558
+ :see: https://docs.cloud.coinbase.com/intx/reference/setportfoliomarginoverride
559
+ :param str symbol: unified market symbol of the market to set margin in
560
+ :param float amount: the amount to set the margin to
561
+ :param dict [params]: parameters specific to the exchange API endpoint
562
+ :returns dict: A `margin structure <https://github.com/ccxt/ccxt/wiki/Manual#add-margin-structure>`
563
+ """
564
+ portfolio = None
565
+ portfolio, params = await self.handle_portfolio_and_params('setMargin', params)
566
+ if symbol is not None:
567
+ raise BadRequest(self.id + ' setMargin() only allows setting margin to full portfolio')
568
+ request: dict = {
569
+ 'portfolio': portfolio,
570
+ 'margin_override': amount,
571
+ }
572
+ return await self.v1PrivatePostPortfoliosMargin(self.extend(request, params))
573
+
574
+ async def fetch_deposits_withdrawals(self, code: str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
575
+ """
576
+ fetch history of deposits and withdrawals
577
+ :see: https://docs.cloud.coinbase.com/intx/reference/gettransfers
578
+ :param str [code]: unified currency code for the currency of the deposit/withdrawals, default is None
579
+ :param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
580
+ :param int [limit]: max number of deposit/withdrawals to return, default is None
581
+ :param dict [params]: extra parameters specific to the exchange API endpoint
582
+ :param str [params.portfolios]: Identifies the portfolios by UUID(e.g., 892e8c7c-e979-4cad-b61b-55a197932cf1) or portfolio ID(e.g., 5189861793641175). Can provide single or multiple portfolios to filter by or fetches transfers for all portfolios if none are provided.
583
+ :param int [params.until]: Only find transfers updated before self time. Use timestamp format
584
+ :param str [params.status]: The current status of transfer. Possible values: [PROCESSED, NEW, FAILED, STARTED]
585
+ :param str [params.type]: The type of transfer Possible values: [DEPOSIT, WITHDRAW, REBATE, STIPEND, INTERNAL, FUNDING]
586
+ :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)
587
+ :returns dict: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
588
+ """
589
+ await self.load_markets()
590
+ paginate = None
591
+ paginate, params = self.handle_option_and_params(params, 'fetchDepositsWithdrawals', 'paginate')
592
+ maxEntriesPerRequest = None
593
+ maxEntriesPerRequest, params = self.handle_option_and_params(params, 'fetchDepositsWithdrawals', 'maxEntriesPerRequest', 100)
594
+ pageKey = 'ccxtPageKey'
595
+ if paginate:
596
+ return await self.fetch_paginated_call_incremental('fetchDepositsWithdrawals', code, since, limit, params, pageKey, maxEntriesPerRequest)
597
+ page = self.safe_integer(params, pageKey, 1) - 1
598
+ request: dict = {
599
+ 'result_offset': self.safe_integer_2(params, 'offset', 'result_offset', page * maxEntriesPerRequest),
600
+ }
601
+ if since is not None:
602
+ request['time_from'] = self.iso8601(since)
603
+ if limit is not None:
604
+ newLimit = min(limit, 100)
605
+ request['result_limit'] = newLimit
606
+ portfolios = None
607
+ portfolios, params = self.handle_option_and_params(params, 'fetchDepositsWithdrawals', 'portfolios')
608
+ if portfolios is not None:
609
+ request['portfolios'] = portfolios
610
+ until = None
611
+ until, params = self.handle_option_and_params(params, 'fetchDepositsWithdrawals', 'until')
612
+ if until is not None:
613
+ request['time_to'] = self.iso8601(until)
614
+ response = await self.v1PrivateGetTransfers(self.extend(request, params))
615
+ #
616
+ # {
617
+ # "pagination":{
618
+ # "result_limit":25,
619
+ # "result_offset":0
620
+ # },
621
+ # "results":[
622
+ # {
623
+ # "transfer_uuid":"8e471d77-4208-45a8-9e5b-f3bd8a2c1fc3",
624
+ # "transfer_type":"WITHDRAW",
625
+ # "amount":"1.000000",
626
+ # "asset":"USDC",
627
+ # "status":"PROCESSED",
628
+ # "network_name":"ethereum",
629
+ # "created_at":"2024-03-14T02:32:18.497795Z",
630
+ # "updated_at":"2024-03-14T02:35:38.514588Z",
631
+ # "from_portfolio":{
632
+ # "id":"1yun54bb-1-6",
633
+ # "uuid":"018e0a8b-6b6b-70e0-9689-1e7926c2c8bc",
634
+ # "name":"fungus technology o?Portfolio"
635
+ # },
636
+ # "to_address":"0xcdcE79F820BE9d6C5033db5c31d1AE3A8c2399bB"
637
+ # }
638
+ # ]
639
+ # }
640
+ #
641
+ rawTransactions = self.safe_list(response, 'results', [])
642
+ return self.parse_transactions(rawTransactions)
643
+
644
+ async def fetch_position(self, symbol: str, params={}):
645
+ """
646
+ :see: https://docs.cloud.coinbase.com/intx/reference/getportfolioposition
647
+ fetch data on an open position
648
+ :param str symbol: unified market symbol of the market the position is held in
649
+ :param dict [params]: extra parameters specific to the exchange API endpoint
650
+ :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
651
+ """
652
+ await self.load_markets()
653
+ symbol = self.symbol(symbol)
654
+ portfolio = None
655
+ portfolio, params = await self.handle_portfolio_and_params('fetchPosition', params)
656
+ request: dict = {
657
+ 'portfolio': portfolio,
658
+ 'instrument': self.market_id(symbol),
659
+ }
660
+ position = await self.v1PrivateGetPortfoliosPortfolioPositionsInstrument(self.extend(request, params))
661
+ #
662
+ # {
663
+ # "symbol":"BTC-PERP",
664
+ # "instrument_id":"114jqr89-0-0",
665
+ # "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
666
+ # "vwap":"52482.3",
667
+ # "net_size":"0",
668
+ # "buy_order_size":"0.001",
669
+ # "sell_order_size":"0",
670
+ # "im_contribution":"0.2",
671
+ # "unrealized_pnl":"0",
672
+ # "mark_price":"52406.8",
673
+ # "entry_vwap":"52472.9"
674
+ # }
675
+ #
676
+ return self.parse_position(position)
677
+
678
+ def parse_position(self, position: dict, market: Market = None):
679
+ #
680
+ # {
681
+ # "symbol":"BTC-PERP",
682
+ # "instrument_id":"114jqr89-0-0",
683
+ # "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
684
+ # "vwap":"52482.3",
685
+ # "net_size":"0",
686
+ # "buy_order_size":"0.001",
687
+ # "sell_order_size":"0",
688
+ # "im_contribution":"0.2",
689
+ # "unrealized_pnl":"0",
690
+ # "mark_price":"52406.8",
691
+ # "entry_vwap":"52472.9"
692
+ # }
693
+ #
694
+ marketId = self.safe_string(position, 'symbol')
695
+ quantity = self.safe_string(position, 'net_size')
696
+ market = self.safe_market(marketId, market, '-')
697
+ side = 'long'
698
+ if Precise.string_le(quantity, '0'):
699
+ side = 'short'
700
+ quantity = Precise.string_mul('-1', quantity)
701
+ return self.safe_position({
702
+ 'info': position,
703
+ 'id': self.safe_string(position, 'id'),
704
+ 'symbol': market['symbol'],
705
+ 'entryPrice': None,
706
+ 'markPrice': self.safe_number(position, 'mark_price'),
707
+ 'notional': None,
708
+ 'collateral': None,
709
+ 'unrealizedPnl': self.safe_number(position, 'unrealized_pnl'),
710
+ 'side': side,
711
+ 'contracts': self.parse_number(quantity),
712
+ 'contractSize': self.safe_number(market, 'contractSize'),
713
+ 'timestamp': None,
714
+ 'datetime': None,
715
+ 'hedged': None,
716
+ 'maintenanceMargin': None,
717
+ 'maintenanceMarginPercentage': None,
718
+ 'initialMargin': self.safe_number(position, 'im_contribution'),
719
+ 'initialMarginPercentage': None,
720
+ 'leverage': None,
721
+ 'liquidationPrice': None,
722
+ 'marginRatio': None,
723
+ 'marginMode': None,
724
+ 'percentage': None,
725
+ })
726
+
727
+ async def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
728
+ """
729
+ :see: https://docs.cloud.coinbase.com/intx/reference/getportfoliopositions
730
+ fetch all open positions
731
+ :param str[] [symbols]: list of unified market symbols
732
+ :param dict [params]: extra parameters specific to the exchange API endpoint
733
+ :param str [method]: method name to call, "positionRisk", "account" or "option", default is "positionRisk"
734
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
735
+ """
736
+ await self.load_markets()
737
+ portfolio = None
738
+ portfolio, params = await self.handle_portfolio_and_params('fetchPositions', params)
739
+ request: dict = {
740
+ 'portfolio': portfolio,
741
+ }
742
+ response = await self.v1PrivateGetPortfoliosPortfolioPositions(self.extend(request, params))
743
+ #
744
+ # [
745
+ # {
746
+ # "symbol":"BTC-PERP",
747
+ # "instrument_id":"114jqr89-0-0",
748
+ # "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
749
+ # "vwap":"52482.3",
750
+ # "net_size":"0",
751
+ # "buy_order_size":"0.001",
752
+ # "sell_order_size":"0",
753
+ # "im_contribution":"0.2",
754
+ # "unrealized_pnl":"0",
755
+ # "mark_price":"52406.8",
756
+ # "entry_vwap":"52472.9"
757
+ # }
758
+ # ]
759
+ #
760
+ positions = self.parse_positions(response)
761
+ if self.is_empty(symbols):
762
+ return positions
763
+ symbols = self.market_symbols(symbols)
764
+ return self.filter_by_array_positions(positions, 'symbol', symbols, False)
765
+
766
+ async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
767
+ """
768
+ fetch all withdrawals made from an account
769
+ :see: https://docs.cloud.coinbase.com/intx/reference/gettransfers
770
+ :param str code: unified currency code
771
+ :param int [since]: the earliest time in ms to fetch withdrawals for
772
+ :param int [limit]: the maximum number of withdrawals structures to retrieve
773
+ :param dict [params]: extra parameters specific to the exchange API endpoint
774
+ :param str [params.portfolios]: Identifies the portfolios by UUID(e.g., 892e8c7c-e979-4cad-b61b-55a197932cf1) or portfolio ID(e.g., 5189861793641175). Can provide single or multiple portfolios to filter by or fetches transfers for all portfolios if none are provided.
775
+ :param int [params.until]: Only find transfers updated before self time. Use timestamp format
776
+ :param str [params.status]: The current status of transfer. Possible values: [PROCESSED, NEW, FAILED, STARTED]
777
+ :param str [params.type]: The type of transfer Possible values: [DEPOSIT, WITHDRAW, REBATE, STIPEND, INTERNAL, FUNDING]
778
+ :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)
779
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
780
+ """
781
+ await self.load_markets()
782
+ params['type'] = 'WITHDRAW'
783
+ return await self.fetch_deposits_withdrawals(code, since, limit, params)
784
+
785
+ async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
786
+ """
787
+ fetch all deposits made to an account
788
+ :param str code: unified currency code
789
+ :param int [since]: the earliest time in ms to fetch deposits for
790
+ :param int [limit]: the maximum number of deposits structures to retrieve
791
+ :param dict [params]: extra parameters specific to the exchange API endpoint
792
+ :param str [params.portfolios]: Identifies the portfolios by UUID(e.g., 892e8c7c-e979-4cad-b61b-55a197932cf1) or portfolio ID(e.g., 5189861793641175). Can provide single or multiple portfolios to filter by or fetches transfers for all portfolios if none are provided.
793
+ :param int [params.until]: Only find transfers updated before self time. Use timestamp format
794
+ :param str [params.status]: The current status of transfer. Possible values: [PROCESSED, NEW, FAILED, STARTED]
795
+ :param str [params.type]: The type of transfer Possible values: [DEPOSIT, WITHDRAW, REBATE, STIPEND, INTERNAL, FUNDING]
796
+ :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)
797
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
798
+ """
799
+ await self.load_markets()
800
+ params['type'] = 'DEPOSIT'
801
+ return await self.fetch_deposits_withdrawals(code, since, limit, params)
802
+
803
+ def parse_transaction_status(self, status: Str):
804
+ statuses: dict = {
805
+ 'PROCESSED': 'ok',
806
+ 'NEW': 'pending',
807
+ 'STARTED': 'pending',
808
+ 'FAILED': 'canceled',
809
+ }
810
+ return self.safe_string(statuses, status, status)
811
+
812
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
813
+ #
814
+ # {
815
+ # "idem":"8e471d77-4208-45a8-9e5b-f3bd8a2c1fc3"
816
+ # }
817
+ # transactionType = self.safe_string(transaction, 'type')
818
+ datetime = self.safe_string(transaction, 'updated_at')
819
+ fromPorfolio = self.safe_dict(transaction, 'from_portfolio', {})
820
+ addressFrom = self.safe_string_n(transaction, ['from_address', 'from_cb_account', self.safe_string_n(fromPorfolio, ['id', 'uuid', 'name']), 'from_counterparty_id'])
821
+ toPorfolio = self.safe_dict(transaction, 'from_portfolio', {})
822
+ addressTo = self.safe_string_n(transaction, ['to_address', 'to_cb_account', self.safe_string_n(toPorfolio, ['id', 'uuid', 'name']), 'to_counterparty_id'])
823
+ return {
824
+ 'info': transaction,
825
+ 'id': self.safe_string(transaction, 'transfer_uuid'),
826
+ 'txid': self.safe_string(transaction, 'transaction_uuid'),
827
+ 'timestamp': self.parse8601(datetime),
828
+ 'datetime': datetime,
829
+ 'network': self.network_id_to_code(self.safe_string(transaction, 'network_name')),
830
+ 'address': None, # TODO check if withdraw or deposit and populate
831
+ 'addressTo': addressTo,
832
+ 'addressFrom': addressFrom,
833
+ 'tag': None,
834
+ 'tagTo': None,
835
+ 'tagFrom': None,
836
+ 'type': self.safe_string(transaction, 'resource'),
837
+ 'amount': self.safe_number(transaction, 'amount'),
838
+ 'currency': self.safe_currency_code(self.safe_string(transaction, 'asset'), currency),
839
+ 'status': self.parse_transaction_status(self.safe_string(transaction, 'status')),
840
+ 'updated': self.parse8601(datetime),
841
+ 'fee': {
842
+ 'cost': None,
843
+ 'currency': None,
844
+ },
845
+ }
846
+
847
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
848
+ #
849
+ # {
850
+ # "portfolio_id":"1wp37qsc-1-0",
851
+ # "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
852
+ # "portfolio_name":"CCXT Portfolio 020624-17:16",
853
+ # "fill_id":"1xbfy19y-1-184",
854
+ # "exec_id":"280841526207070392",
855
+ # "order_id":"1xbfv8yw-1-0",
856
+ # "instrument_id":"114jqr89-0-0",
857
+ # "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
858
+ # "symbol":"BTC-PERP",
859
+ # "match_id":"280841526207053840",
860
+ # "fill_price":"52500",
861
+ # "fill_qty":"0.01",
862
+ # "client_id":"1x59ctku-1-1",
863
+ # "client_order_id":"ccxt3e4e2a5f-4a89-",
864
+ # "order_qty":"0.01",
865
+ # "limit_price":"52500",
866
+ # "total_filled":"0.01",
867
+ # "filled_vwap":"52500",
868
+ # "expire_time":"",
869
+ # "stop_price":"",
870
+ # "side":"BUY",
871
+ # "tif":"GTC",
872
+ # "stp_mode":"BOTH",
873
+ # "flags":"",
874
+ # "fee":"0.105",
875
+ # "fee_asset":"USDC",
876
+ # "order_status":"DONE",
877
+ # "event_time":"2024-02-15T00:43:57.631Z"
878
+ # }
879
+ #
880
+ marketId = self.safe_string(trade, 'symbol')
881
+ datetime = self.safe_string(trade, 'event_time')
882
+ return self.safe_trade({
883
+ 'info': trade,
884
+ 'id': self.safe_string_2(trade, 'fill_id', 'exec_id'),
885
+ 'order': self.safe_string(trade, 'order_id'),
886
+ 'timestamp': self.parse8601(datetime),
887
+ 'datetime': datetime,
888
+ 'symbol': self.safe_symbol(marketId, market),
889
+ 'type': None,
890
+ 'side': self.safe_string_lower(trade, 'side'),
891
+ 'takerOrMaker': None,
892
+ 'price': self.safe_number(trade, 'fill_price'),
893
+ 'amount': self.safe_number(trade, 'fill_qty'),
894
+ 'cost': None,
895
+ 'fee': {
896
+ 'cost': self.safe_number(trade, 'fee'),
897
+ 'currency': self.safe_currency_code(self.safe_string(trade, 'fee_asset')),
898
+ },
899
+ })
900
+
901
+ async def fetch_markets(self, params={}) -> List[Market]:
902
+ """
903
+ :see: https://docs.cloud.coinbase.com/intx/reference/getinstruments
904
+ retrieves data on all markets for coinbaseinternational
905
+ :param dict [params]: extra parameters specific to the exchange API endpoint
906
+ :returns dict[]: an array of objects representing market data
907
+ """
908
+ response = await self.v1PublicGetInstruments(params)
909
+ #
910
+ # [
911
+ # {
912
+ # "instrument_id":"149264164756389888",
913
+ # "instrument_uuid":"e9360798-6a10-45d6-af05-67c30eb91e2d",
914
+ # "symbol":"ETH-PERP",
915
+ # "type":"PERP",
916
+ # "base_asset_id":"118059611793145856",
917
+ # "base_asset_uuid":"d85dce9b-5b73-5c3c-8978-522ce1d1c1b4",
918
+ # "base_asset_name":"ETH",
919
+ # "quote_asset_id":"1",
920
+ # "quote_asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
921
+ # "quote_asset_name":"USDC",
922
+ # "base_increment":"0.0001",
923
+ # "quote_increment":"0.01",
924
+ # "price_band_percent":"0.02",
925
+ # "market_order_percent":"0.0075",
926
+ # "qty_24hr":"44434.8131",
927
+ # "notional_24hr":"110943454.279785",
928
+ # "avg_daily_qty":"1099171.6025",
929
+ # "avg_daily_notional":"2637240145.456987",
930
+ # "previous_day_qty":"78909.3939",
931
+ # "open_interest":"1270.749",
932
+ # "position_limit_qty":"1831.9527",
933
+ # "position_limit_adq_pct":"0.05",
934
+ # "replacement_cost":"0.23",
935
+ # "base_imf":"0.1",
936
+ # "min_notional_value":"10",
937
+ # "funding_interval":"3600000000000",
938
+ # "trading_state":"TRADING",
939
+ # "quote":{
940
+ # "best_bid_price":"2490.8",
941
+ # "best_bid_size":"9.0515",
942
+ # "best_ask_price":"2490.81",
943
+ # "best_ask_size":"4.8486",
944
+ # "trade_price":"2490.39",
945
+ # "trade_qty":"0.9508",
946
+ # "index_price":"2490.5",
947
+ # "mark_price":"2490.8",
948
+ # "settlement_price":"2490.81",
949
+ # "limit_up":"2615.42",
950
+ # "limit_down":"2366.34",
951
+ # "predicted_funding":"0.000009",
952
+ # "timestamp":"2024-02-10T16:07:39.454Z"
953
+ # }
954
+ # },
955
+ # ...
956
+ # ]
957
+ #
958
+ return self.parse_markets(response)
959
+
960
+ def parse_market(self, market: dict) -> Market:
961
+ #
962
+ # {
963
+ # "instrument_id":"149264164756389888",
964
+ # "instrument_uuid":"e9360798-6a10-45d6-af05-67c30eb91e2d",
965
+ # "symbol":"ETH-PERP",
966
+ # "type":"PERP",
967
+ # "base_asset_id":"118059611793145856",
968
+ # "base_asset_uuid":"d85dce9b-5b73-5c3c-8978-522ce1d1c1b4",
969
+ # "base_asset_name":"ETH",
970
+ # "quote_asset_id":"1",
971
+ # "quote_asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
972
+ # "quote_asset_name":"USDC",
973
+ # "base_increment":"0.0001",
974
+ # "quote_increment":"0.01",
975
+ # "price_band_percent":"0.02",
976
+ # "market_order_percent":"0.0075",
977
+ # "qty_24hr":"44434.8131",
978
+ # "notional_24hr":"110943454.279785",
979
+ # "avg_daily_qty":"1099171.6025",
980
+ # "avg_daily_notional":"2637240145.456987",
981
+ # "previous_day_qty":"78909.3939",
982
+ # "open_interest":"1270.749",
983
+ # "position_limit_qty":"1831.9527",
984
+ # "position_limit_adq_pct":"0.05",
985
+ # "replacement_cost":"0.23",
986
+ # "base_imf":"0.1",
987
+ # "min_notional_value":"10",
988
+ # "funding_interval":"3600000000000",
989
+ # "trading_state":"TRADING",
990
+ # "quote":{
991
+ # "best_bid_price":"2490.8",
992
+ # "best_bid_size":"9.0515",
993
+ # "best_ask_price":"2490.81",
994
+ # "best_ask_size":"4.8486",
995
+ # "trade_price":"2490.39",
996
+ # "trade_qty":"0.9508",
997
+ # "index_price":"2490.5",
998
+ # "mark_price":"2490.8",
999
+ # "settlement_price":"2490.81",
1000
+ # "limit_up":"2615.42",
1001
+ # "limit_down":"2366.34",
1002
+ # "predicted_funding":"0.000009",
1003
+ # "timestamp":"2024-02-10T16:07:39.454Z"
1004
+ # }
1005
+ # }
1006
+ #
1007
+ marketId = self.safe_string(market, 'symbol')
1008
+ baseId = self.safe_string(market, 'base_asset_name')
1009
+ quoteId = self.safe_string(market, 'quote_asset_name')
1010
+ typeId = self.safe_string(market, 'type') # 'SPOT', 'PERP'
1011
+ isSpot = (typeId == 'SPOT')
1012
+ fees = self.fees
1013
+ symbol = baseId + '/' + quoteId
1014
+ settleId = None
1015
+ if not isSpot:
1016
+ settleId = quoteId
1017
+ symbol += ':' + quoteId
1018
+ return {
1019
+ 'id': marketId,
1020
+ 'lowercaseId': marketId.lower(),
1021
+ 'symbol': symbol,
1022
+ 'base': baseId,
1023
+ 'quote': quoteId,
1024
+ 'settle': settleId if settleId else None,
1025
+ 'baseId': baseId,
1026
+ 'quoteId': quoteId,
1027
+ 'settleId': settleId if settleId else None,
1028
+ 'type': 'spot' if isSpot else 'swap',
1029
+ 'spot': isSpot,
1030
+ 'margin': False,
1031
+ 'swap': not isSpot,
1032
+ 'future': False,
1033
+ 'option': False,
1034
+ 'active': self.safe_string(market, 'trading_state') == 'TRADING',
1035
+ 'contract': not isSpot,
1036
+ 'linear': None if isSpot else (settleId == quoteId),
1037
+ 'inverse': None if isSpot else (settleId != quoteId),
1038
+ 'taker': fees['trading']['taker'],
1039
+ 'maker': fees['trading']['maker'],
1040
+ 'contractSize': None if isSpot else 1,
1041
+ 'expiry': None,
1042
+ 'expiryDatetime': None,
1043
+ 'strike': None,
1044
+ 'optionType': None,
1045
+ 'precision': {
1046
+ 'amount': self.safe_number(market, 'base_increment'),
1047
+ 'price': self.safe_number(market, 'quote_increment'),
1048
+ 'cost': self.safe_number(market, 'quote_increment'),
1049
+ },
1050
+ 'limits': {
1051
+ 'leverage': {
1052
+ 'min': None,
1053
+ 'max': self.safe_number(market, 'base_imf'),
1054
+ },
1055
+ 'amount': {
1056
+ 'min': None,
1057
+ 'max': None if isSpot else self.safe_number(market, 'position_limit_qty'),
1058
+ },
1059
+ 'price': {
1060
+ 'min': None,
1061
+ 'max': None,
1062
+ },
1063
+ 'cost': {
1064
+ 'min': self.safe_number(market, 'min_notional_value'),
1065
+ 'max': None,
1066
+ },
1067
+ },
1068
+ 'info': market,
1069
+ 'created': None,
1070
+ }
1071
+
1072
+ async def fetch_currencies(self, params={}) -> Currencies:
1073
+ """
1074
+ fetches all available currencies on an exchange
1075
+ :see: https://docs.cloud.coinbase.com/intx/reference/getassets
1076
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1077
+ :returns dict: an associative dictionary of currencies
1078
+ """
1079
+ currencies = await self.v1PublicGetAssets(params)
1080
+ #
1081
+ # [
1082
+ # {
1083
+ # "asset_id":"1",
1084
+ # "asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
1085
+ # "asset_name":"USDC",
1086
+ # "status":"ACTIVE",
1087
+ # "collateral_weight":1.0,
1088
+ # "supported_networks_enabled":true
1089
+ # },
1090
+ # ...
1091
+ # ]
1092
+ #
1093
+ result: dict = {}
1094
+ for i in range(0, len(currencies)):
1095
+ currency = self.parse_currency(currencies[i])
1096
+ result[currency['code']] = currency
1097
+ return result
1098
+
1099
+ def parse_currency(self, currency: dict):
1100
+ #
1101
+ # {
1102
+ # "asset_id":"1",
1103
+ # "asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
1104
+ # "asset_name":"USDC",
1105
+ # "status":"ACTIVE",
1106
+ # "collateral_weight":1.0,
1107
+ # "supported_networks_enabled":true
1108
+ # }
1109
+ #
1110
+ id = self.safe_string(currency, 'asset_name')
1111
+ code = self.safe_currency_code(id)
1112
+ statusId = self.safe_string(currency, 'status')
1113
+ return {
1114
+ 'id': id,
1115
+ 'name': code,
1116
+ 'code': code,
1117
+ 'precision': None,
1118
+ 'info': currency,
1119
+ 'active': (statusId == 'ACTIVE'),
1120
+ 'deposit': None,
1121
+ 'withdraw': None,
1122
+ 'networks': None,
1123
+ 'fee': None,
1124
+ 'fees': None,
1125
+ 'limits': self.limits,
1126
+ }
1127
+
1128
+ async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
1129
+ """
1130
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1131
+ :see: https://docs.cloud.coinbase.com/intx/reference/getinstruments
1132
+ :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1133
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1134
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
1135
+ """
1136
+ await self.load_markets()
1137
+ symbols = self.market_symbols(symbols)
1138
+ instruments = await self.v1PublicGetInstruments(params)
1139
+ tickers: dict = {}
1140
+ for i in range(0, len(instruments)):
1141
+ instrument = instruments[i]
1142
+ marketId = self.safe_string(instrument, 'symbol')
1143
+ symbol = self.safe_symbol(marketId)
1144
+ quote = self.safe_dict(instrument, 'quote', {})
1145
+ tickers[symbol] = self.parse_ticker(quote, self.safe_market(marketId))
1146
+ return self.filter_by_array(tickers, 'symbol', symbols, True)
1147
+
1148
+ async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
1149
+ """
1150
+ fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1151
+ :see: https://docs.cloud.coinbase.com/intx/reference/getinstrumentquote
1152
+ :param str symbol: unified symbol of the market to fetch the ticker for
1153
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1154
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
1155
+ """
1156
+ await self.load_markets()
1157
+ market = self.market(symbol)
1158
+ request: dict = {
1159
+ 'instrument': self.market_id(symbol),
1160
+ }
1161
+ ticker = await self.v1PublicGetInstrumentsInstrumentQuote(self.extend(request, params))
1162
+ return self.parse_ticker(ticker, market)
1163
+
1164
+ def parse_ticker(self, ticker: object, market: Market = None) -> Ticker:
1165
+ #
1166
+ # {
1167
+ # "best_bid_price":"2490.8",
1168
+ # "best_bid_size":"9.0515",
1169
+ # "best_ask_price":"2490.81",
1170
+ # "best_ask_size":"4.8486",
1171
+ # "trade_price":"2490.39",
1172
+ # "trade_qty":"0.9508",
1173
+ # "index_price":"2490.5",
1174
+ # "mark_price":"2490.8",
1175
+ # "settlement_price":"2490.81",
1176
+ # "limit_up":"2615.42",
1177
+ # "limit_down":"2366.34",
1178
+ # "predicted_funding":"0.000009",
1179
+ # "timestamp":"2024-02-10T16:07:39.454Z"
1180
+ # }
1181
+ #
1182
+ datetime = self.safe_string(ticker, 'timestamp')
1183
+ return self.safe_ticker({
1184
+ 'info': ticker,
1185
+ 'symbol': self.safe_symbol(None, market),
1186
+ 'timestamp': self.parse8601(datetime),
1187
+ 'datetime': datetime,
1188
+ 'bid': self.safe_number(ticker, 'best_bid_price'),
1189
+ 'bidVolume': self.safe_number(ticker, 'best_bid_size'),
1190
+ 'ask': self.safe_number(ticker, 'best_ask_price'),
1191
+ 'askVolume': self.safe_number(ticker, 'best_ask_size'),
1192
+ 'high': None,
1193
+ 'low': None,
1194
+ 'open': None,
1195
+ 'close': None,
1196
+ 'last': None,
1197
+ 'change': None,
1198
+ 'percentage': None,
1199
+ 'average': None,
1200
+ 'vwap': None,
1201
+ 'baseVolume': None,
1202
+ 'quoteVolume': None,
1203
+ 'previousClose': None,
1204
+ })
1205
+
1206
+ async def fetch_balance(self, params={}) -> Balances:
1207
+ """
1208
+ query for balance and get the amount of funds available for trading or funds locked in orders
1209
+ :see: https://docs.cloud.coinbase.com/intx/reference/getportfoliobalances
1210
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1211
+ :param boolean [params.v3]: default False, set True to use v3 api endpoint
1212
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1213
+ """
1214
+ await self.load_markets()
1215
+ portfolio = None
1216
+ portfolio, params = await self.handle_portfolio_and_params('fetchBalance', params)
1217
+ request: dict = {
1218
+ 'portfolio': portfolio,
1219
+ }
1220
+ balances = await self.v1PrivateGetPortfoliosPortfolioBalances(self.extend(request, params))
1221
+ #
1222
+ # [
1223
+ # {
1224
+ # "asset_id":"0-0-1",
1225
+ # "asset_name":"USDC",
1226
+ # "asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
1227
+ # "quantity":"500000.0000000000",
1228
+ # "hold":"0",
1229
+ # "hold_available_for_collateral":"0",
1230
+ # "transfer_hold":"0",
1231
+ # "collateral_value":"500000.0",
1232
+ # "max_withdraw_amount":"500000.0000000000",
1233
+ # "loan":"0",
1234
+ # "loan_collateral_requirement":"0.0"
1235
+ # }
1236
+ # ]
1237
+ #
1238
+ return self.parse_balance(balances)
1239
+
1240
+ def parse_balance(self, response) -> Balances:
1241
+ #
1242
+ # {
1243
+ # "asset_id":"0-0-1",
1244
+ # "asset_name":"USDC",
1245
+ # "asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
1246
+ # "quantity":"500000.0000000000",
1247
+ # "hold":"0",
1248
+ # "hold_available_for_collateral":"0",
1249
+ # "transfer_hold":"0",
1250
+ # "collateral_value":"500000.0",
1251
+ # "max_withdraw_amount":"500000.0000000000",
1252
+ # "loan":"0",
1253
+ # "loan_collateral_requirement":"0.0"
1254
+ # }
1255
+ #
1256
+ result: dict = {
1257
+ 'info': response,
1258
+ }
1259
+ for i in range(0, len(response)):
1260
+ rawBalance = response[i]
1261
+ currencyId = self.safe_string(rawBalance, 'asset_name')
1262
+ code = self.safe_currency_code(currencyId)
1263
+ account = self.account()
1264
+ account['total'] = self.safe_string(rawBalance, 'quantity')
1265
+ account['used'] = self.safe_string(rawBalance, 'hold')
1266
+ result[code] = account
1267
+ return self.safe_balance(result)
1268
+
1269
+ async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
1270
+ """
1271
+ Transfer an amount of asset from one portfolio to another.
1272
+ :see: https://docs.cloud.coinbase.com/intx/reference/createportfolioassettransfer
1273
+ :param str code: unified currency code
1274
+ :param float amount: amount to transfer
1275
+ :param str fromAccount: account to transfer from
1276
+ :param str toAccount: account to transfer to
1277
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1278
+ :returns dict: a `transfer structure <https://github.com/ccxt/ccxt/wiki/Manual#transfer-structure>`
1279
+ """
1280
+ await self.load_markets()
1281
+ currency = self.currency(code)
1282
+ request: dict = {
1283
+ 'asset': currency['id'],
1284
+ 'ammount': amount,
1285
+ 'from': fromAccount,
1286
+ 'to': toAccount,
1287
+ }
1288
+ response = await self.v1PrivatePostPortfoliosTransfer(self.extend(request, params))
1289
+ success = self.safe_bool(response, 'success')
1290
+ return {
1291
+ 'info': response,
1292
+ 'id': None,
1293
+ 'timestamp': None,
1294
+ 'datetime': None,
1295
+ 'currency': code,
1296
+ 'amount': amount,
1297
+ 'fromAccount': fromAccount,
1298
+ 'toAccount': toAccount,
1299
+ 'status': 'ok' if success else 'failed',
1300
+ }
1301
+
1302
+ async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: float = None, params={}):
1303
+ """
1304
+ create a trade order
1305
+ :see: https://docs.cloud.coinbase.com/intx/reference/createorder
1306
+ :param str symbol: unified symbol of the market to create an order in
1307
+ :param str type: 'market' or 'limit'
1308
+ :param str side: 'buy' or 'sell'
1309
+ :param float amount: how much you want to trade in units of the base currency, quote currency for 'market' 'buy' orders
1310
+ :param float [price]: the price to fulfill the order, in units of the quote currency, ignored in market orders
1311
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1312
+ :param float [params.stopPrice]: price to trigger stop orders
1313
+ :param float [params.triggerPrice]: price to trigger stop orders
1314
+ :param float [params.stopLossPrice]: price to trigger stop-loss orders
1315
+ :param bool [params.postOnly]: True or False
1316
+ :param str [params.tif]: 'GTC', 'IOC', 'GTD' default is 'GTC' for limit orders and 'IOC' for market orders
1317
+ :param str [params.expire_time]: The expiration time required for orders with the time in force set to GTT. Must not go beyond 30 days of the current time. Uses ISO-8601 format(e.g., 2023-03-16T23:59:53Z)
1318
+ :param str [params.stp_mode]: Possible values: [NONE, AGGRESSING, BOTH] Specifies the behavior for self match handling. None disables the functionality, new cancels the newest order, and both cancels both orders.
1319
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1320
+ """
1321
+ await self.load_markets()
1322
+ market = self.market(symbol)
1323
+ typeId = type.upper()
1324
+ stopPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'stop_price'])
1325
+ clientOrderIdprefix = self.safe_string(self.options, 'brokerId', 'nfqkvdjp')
1326
+ clientOrderId = clientOrderIdprefix + '-' + self.uuid()
1327
+ clientOrderId = clientOrderId[0:17]
1328
+ request: dict = {
1329
+ 'client_order_id': clientOrderId,
1330
+ 'side': side.upper(),
1331
+ 'instrument': market['id'],
1332
+ 'size': self.amount_to_precision(market['symbol'], amount),
1333
+ }
1334
+ if stopPrice is not None:
1335
+ if type == 'limit':
1336
+ typeId = 'STOP_LIMIT'
1337
+ else:
1338
+ typeId = 'STOP'
1339
+ request['stop_price'] = stopPrice
1340
+ request['type'] = typeId
1341
+ if type == 'limit':
1342
+ if price is None:
1343
+ raise InvalidOrder(self.id + 'createOrder() requires a price parameter for a limit order types')
1344
+ request['price'] = price
1345
+ portfolio = None
1346
+ portfolio, params = await self.handle_portfolio_and_params('createOrder', params)
1347
+ if portfolio is not None:
1348
+ request['portfolio'] = portfolio
1349
+ postOnly = self.safe_bool_2(params, 'postOnly', 'post_only')
1350
+ tif = self.safe_string_2(params, 'tif', 'timeInForce')
1351
+ # market orders must be IOC
1352
+ if typeId == 'MARKET':
1353
+ if tif is not None and tif != 'IOC':
1354
+ raise InvalidOrder(self.id + 'createOrder() market orders must have tif set to "IOC"')
1355
+ tif = 'IOC'
1356
+ else:
1357
+ tif = 'GTC' if (tif is None) else tif
1358
+ if postOnly is not None:
1359
+ request['post_only'] = postOnly
1360
+ request['tif'] = tif
1361
+ params = self.omit(params, ['client_order_id', 'user', 'postOnly', 'timeInForce'])
1362
+ response = await self.v1PrivatePostOrders(self.extend(request, params))
1363
+ #
1364
+ # {
1365
+ # "order_id":"1x96skvg-1-0",
1366
+ # "client_order_id":"ccxt",
1367
+ # "side":"BUY",
1368
+ # "instrument_id":"114jqr89-0-0",
1369
+ # "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
1370
+ # "symbol":"BTC-PERP",
1371
+ # "portfolio_id":"1wp37qsc-1-0",
1372
+ # "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
1373
+ # "type":"LIMIT",
1374
+ # "price":"10000",
1375
+ # "size":"0.001",
1376
+ # "tif":"GTC",
1377
+ # "stp_mode":"BOTH",
1378
+ # "event_type":"NEW",
1379
+ # "order_status":"WORKING",
1380
+ # "leaves_qty":"0.001",
1381
+ # "exec_qty":"0",
1382
+ # "avg_price":"0",
1383
+ # "fee":"0"
1384
+ # }
1385
+ #
1386
+ return self.parse_order(response, market)
1387
+
1388
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1389
+ #
1390
+ # {
1391
+ # "order_id":"1x96skvg-1-0",
1392
+ # "client_order_id":"ccxt",
1393
+ # "side":"BUY",
1394
+ # "instrument_id":"114jqr89-0-0",
1395
+ # "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
1396
+ # "symbol":"BTC-PERP",
1397
+ # "portfolio_id":"1wp37qsc-1-0",
1398
+ # "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
1399
+ # "type":"LIMIT",
1400
+ # "price":"10000",
1401
+ # "size":"0.001",
1402
+ # "tif":"GTC",
1403
+ # "stp_mode":"BOTH",
1404
+ # "event_type":"NEW",
1405
+ # "order_status":"WORKING",
1406
+ # "leaves_qty":"0.001",
1407
+ # "exec_qty":"0",
1408
+ # "avg_price":"0",
1409
+ # "fee":"0"
1410
+ # }
1411
+ #
1412
+ marketId = self.safe_string(order, 'symbol')
1413
+ feeCost = self.safe_number(order, 'fee')
1414
+ fee = None
1415
+ if feeCost is not None:
1416
+ fee = {
1417
+ 'cost': feeCost,
1418
+ }
1419
+ datetime = self.safe_string_2(order, 'submit_time', 'event_time')
1420
+ return self.safe_order({
1421
+ 'info': order,
1422
+ 'id': self.safe_string(order, 'order_id'),
1423
+ 'clientOrderId': self.safe_string(order, 'client_order_id'),
1424
+ 'timestamp': self.parse8601(datetime),
1425
+ 'datetime': datetime,
1426
+ 'lastTradeTimestamp': None,
1427
+ 'symbol': self.safe_symbol(marketId, market),
1428
+ 'type': self.parse_order_type(self.safe_string(order, 'type')),
1429
+ 'timeInForce': self.safe_string(order, 'tif'),
1430
+ 'postOnly': None,
1431
+ 'side': self.safe_string_lower(order, 'side'),
1432
+ 'price': self.safe_string(order, 'price'),
1433
+ 'stopPrice': self.safe_string(order, 'stop_price'),
1434
+ 'triggerPrice': self.safe_string(order, 'stop_price'),
1435
+ 'amount': self.safe_string(order, 'size'),
1436
+ 'filled': self.safe_string(order, 'exec_qty'),
1437
+ 'remaining': self.safe_string(order, 'leaves_qty'),
1438
+ 'cost': None,
1439
+ 'average': self.safe_string(order, 'avg_price'),
1440
+ 'status': self.parse_order_status(self.safe_string(order, 'order_status')),
1441
+ 'fee': fee,
1442
+ 'trades': None,
1443
+ }, market)
1444
+
1445
+ def parse_order_status(self, status: Str):
1446
+ statuses: dict = {
1447
+ 'NEW': 'open',
1448
+ 'PARTIAL_FILLED': 'open',
1449
+ 'FILLED': 'closed',
1450
+ 'CANCELED': 'canceled',
1451
+ 'REPLACED': 'canceled',
1452
+ 'PENDING_CANCEL': 'open',
1453
+ 'REJECTED': 'rejected',
1454
+ 'PENDING_NEW': 'open',
1455
+ 'EXPIRED': 'expired',
1456
+ 'PENDING_REPLACE': 'open',
1457
+ }
1458
+ return self.safe_string(statuses, status, status)
1459
+
1460
+ def parse_order_type(self, type: Str):
1461
+ if type == 'UNKNOWN_ORDER_TYPE':
1462
+ return None
1463
+ types: dict = {
1464
+ 'MARKET': 'market',
1465
+ 'LIMIT': 'limit',
1466
+ 'STOP': 'limit',
1467
+ 'STOP_LIMIT': 'limit',
1468
+ }
1469
+ return self.safe_string(types, type, type)
1470
+
1471
+ async def cancel_order(self, id: str, symbol: Str = None, params={}):
1472
+ """
1473
+ cancels an open order
1474
+ :see: https://docs.cloud.coinbase.com/intx/reference/cancelorder
1475
+ :param str id: order id
1476
+ :param str symbol: not used by coinbaseinternational cancelOrder()
1477
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1478
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1479
+ """
1480
+ await self.load_markets()
1481
+ portfolio = None
1482
+ portfolio, params = await self.handle_portfolio_and_params('cancelOrder', params)
1483
+ request: dict = {
1484
+ 'portfolio': portfolio,
1485
+ 'id': id,
1486
+ }
1487
+ market = None
1488
+ if symbol is not None:
1489
+ market = self.market(symbol)
1490
+ orders = await self.v1PrivateDeleteOrdersId(self.extend(request, params))
1491
+ #
1492
+ # {
1493
+ # "order_id":"1x96skvg-1-0",
1494
+ # "client_order_id":"ccxt",
1495
+ # "side":"BUY",
1496
+ # "instrument_id":"114jqr89-0-0",
1497
+ # "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
1498
+ # "symbol":"BTC-PERP",
1499
+ # "portfolio_id":"1wp37qsc-1-0",
1500
+ # "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
1501
+ # "type":"LIMIT",
1502
+ # "price":"10000",
1503
+ # "size":"0.001",
1504
+ # "tif":"GTC",
1505
+ # "stp_mode":"BOTH",
1506
+ # "event_type":"CANCELED",
1507
+ # "order_status":"DONE",
1508
+ # "leaves_qty":"0.001",
1509
+ # "exec_qty":"0",
1510
+ # "avg_price":"0",
1511
+ # "fee":"0"
1512
+ # }
1513
+ #
1514
+ return self.parse_order(orders, market)
1515
+
1516
+ async def cancel_all_orders(self, symbol: str = None, params={}):
1517
+ """
1518
+ cancel all open orders
1519
+ :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
1520
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1521
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1522
+ """
1523
+ await self.load_markets()
1524
+ portfolio = None
1525
+ portfolio, params = await self.handle_portfolio_and_params('cancelAllOrders', params)
1526
+ request: dict = {
1527
+ 'portfolio': portfolio,
1528
+ }
1529
+ market = None
1530
+ if symbol:
1531
+ market = self.market(symbol)
1532
+ request['instrument'] = market['id']
1533
+ orders = await self.v1PrivateDeleteOrders(self.extend(request, params))
1534
+ return self.parse_orders(orders, market)
1535
+
1536
+ async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float = None, price: float = None, params={}):
1537
+ """
1538
+ edit a trade order
1539
+ :see: https://docs.cloud.coinbase.com/intx/reference/modifyorder
1540
+ :param str id: cancel order id
1541
+ :param str symbol: unified symbol of the market to create an order in
1542
+ :param str type: 'market' or 'limit'
1543
+ :param str side: 'buy' or 'sell'
1544
+ :param float amount: how much of currency you want to trade in units of base currency
1545
+ :param float [price]: the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
1546
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1547
+ :param str params['clientOrderId']: client order id
1548
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1549
+ """
1550
+ await self.load_markets()
1551
+ market = self.market(symbol)
1552
+ request: dict = {
1553
+ 'id': id,
1554
+ }
1555
+ portfolio = None
1556
+ portfolio, params = await self.handle_portfolio_and_params('editOrder', params)
1557
+ if portfolio is not None:
1558
+ request['portfolio'] = portfolio
1559
+ if amount is not None:
1560
+ request['size'] = self.amount_to_precision(symbol, amount)
1561
+ if price is not None:
1562
+ request['price'] = self.price_to_precision(symbol, price)
1563
+ stopPrice = self.safe_number_n(params, ['stopPrice', 'stop_price', 'triggerPrice'])
1564
+ if stopPrice is not None:
1565
+ request['stop_price'] = stopPrice
1566
+ clientOrderId = self.safe_string_2(params, 'client_order_id', 'clientOrderId')
1567
+ if clientOrderId is None:
1568
+ raise BadRequest(self.id + ' editOrder() requires a clientOrderId parameter')
1569
+ request['client_order_id'] = clientOrderId
1570
+ order = await self.v1PrivatePutOrdersId(self.extend(request, params))
1571
+ return self.parse_order(order, market)
1572
+
1573
+ async def fetch_order(self, id: str, symbol: Str = None, params={}):
1574
+ """
1575
+ fetches information on an order made by the user
1576
+ :see: https://docs.cloud.coinbase.com/intx/reference/modifyorder
1577
+ :param str id: the order id
1578
+ :param str symbol: unified market symbol that the order was made in
1579
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1580
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1581
+ """
1582
+ await self.load_markets()
1583
+ market = None
1584
+ if symbol is not None:
1585
+ market = self.market(symbol)
1586
+ portfolio = None
1587
+ portfolio, params = await self.handle_portfolio_and_params('fetchOrder', params)
1588
+ request: dict = {
1589
+ 'id': id,
1590
+ 'portfolio': portfolio,
1591
+ }
1592
+ order = await self.v1PrivateGetOrdersId(self.extend(request, params))
1593
+ #
1594
+ # {
1595
+ # "order_id":"1x96skvg-1-0",
1596
+ # "client_order_id":"ccxt",
1597
+ # "side":"BUY",
1598
+ # "instrument_id":"114jqr89-0-0",
1599
+ # "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
1600
+ # "symbol":"BTC-PERP",
1601
+ # "portfolio_id":"1wp37qsc-1-0",
1602
+ # "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
1603
+ # "type":"LIMIT",
1604
+ # "price":"10000",
1605
+ # "size":"0.001",
1606
+ # "tif":"GTC",
1607
+ # "stp_mode":"BOTH",
1608
+ # "event_type":"NEW",
1609
+ # "event_time":"2024-02-14T03:25:14Z",
1610
+ # "submit_time":"2024-02-14T03:25:13.999Z",
1611
+ # "order_status":"WORKING",
1612
+ # "leaves_qty":"0.001",
1613
+ # "exec_qty":"0",
1614
+ # "avg_price":"0",
1615
+ # "fee":"0"
1616
+ # }
1617
+ #
1618
+ return self.parse_order(order, market)
1619
+
1620
+ async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1621
+ """
1622
+ fetches information on all currently open orders
1623
+ :see: https://docs.cloud.coinbase.com/intx/reference/getorders
1624
+ :param str symbol: unified market symbol of the orders
1625
+ :param int [since]: timestamp in ms of the earliest order, default is None
1626
+ :param int [limit]: the maximum number of open order structures to retrieve
1627
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1628
+ :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)
1629
+ :param int [params.offset]: offset
1630
+ :param str [params.event_type]: The most recent type of event that happened to the order. Allowed values: NEW, TRADE, REPLACED
1631
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1632
+ """
1633
+ await self.load_markets()
1634
+ portfolio = None
1635
+ portfolio, params = await self.handle_portfolio_and_params('fetchOpenOrders', params)
1636
+ paginate = False
1637
+ paginate, params = self.handle_option_and_params(params, 'fetchOpenOrders', 'paginate')
1638
+ maxEntriesPerRequest = None
1639
+ maxEntriesPerRequest, params = self.handle_option_and_params(params, 'fetchOpenOrders', 'maxEntriesPerRequest', 100)
1640
+ pageKey = 'ccxtPageKey'
1641
+ if paginate:
1642
+ return await self.fetch_paginated_call_incremental('fetchOpenOrders', symbol, since, limit, params, pageKey, maxEntriesPerRequest)
1643
+ page = self.safe_integer(params, pageKey, 1) - 1
1644
+ request: dict = {
1645
+ 'portfolio': portfolio,
1646
+ 'result_offset': self.safe_integer_2(params, 'offset', 'result_offset', page * maxEntriesPerRequest),
1647
+ }
1648
+ market = None
1649
+ if symbol:
1650
+ market = self.market(symbol)
1651
+ request['instrument'] = symbol
1652
+ if limit is not None:
1653
+ if limit > 100:
1654
+ raise BadRequest(self.id + ' fetchOpenOrders() maximum limit is 100')
1655
+ request['result_limit'] = limit
1656
+ if since is not None:
1657
+ request['ref_datetime'] = self.iso8601(since)
1658
+ response = await self.v1PrivateGetOrders(self.extend(request, params))
1659
+ #
1660
+ # {
1661
+ # "pagination":{
1662
+ # "result_limit":25,
1663
+ # "result_offset":0
1664
+ # },
1665
+ # "results":[
1666
+ # {
1667
+ # "order_id":"1y4cm6b4-1-0",
1668
+ # "client_order_id":"ccxtd0dd4b5d-8e5f-",
1669
+ # "side":"SELL",
1670
+ # "instrument_id":"114jqr89-0-0",
1671
+ # "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
1672
+ # "symbol":"BTC-PERP",
1673
+ # "portfolio_id":"1wp37qsc-1-0",
1674
+ # "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
1675
+ # "type":"LIMIT",
1676
+ # "price":"54000",
1677
+ # "size":"0.01",
1678
+ # "tif":"GTC",
1679
+ # "stp_mode":"BOTH",
1680
+ # "event_type":"NEW",
1681
+ # "event_time":"2024-02-24T16:46:37.413Z",
1682
+ # "submit_time":"2024-02-24T16:46:37.412Z",
1683
+ # "order_status":"WORKING",
1684
+ # "leaves_qty":"0.01",
1685
+ # "exec_qty":"0",
1686
+ # "avg_price":"0",
1687
+ # "fee":"0"
1688
+ # },
1689
+ # ...
1690
+ # ]
1691
+ # }
1692
+ #
1693
+ rawOrders = self.safe_list(response, 'results', [])
1694
+ return self.parse_orders(rawOrders, market, since, limit)
1695
+
1696
+ async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1697
+ """
1698
+ fetch all trades made by the user
1699
+ :see: https://docs.cloud.coinbase.com/intx/reference/getmultiportfoliofills
1700
+ :param str symbol: unified market symbol of the trades
1701
+ :param int [since]: timestamp in ms of the earliest order, default is None
1702
+ :param int [limit]: the maximum number of trade structures to fetch
1703
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1704
+ :param int [params.until]: the latest time in ms to fetch trades for
1705
+ :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)
1706
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1707
+ """
1708
+ await self.load_markets()
1709
+ paginate = False
1710
+ paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
1711
+ pageKey = 'ccxtPageKey'
1712
+ maxEntriesPerRequest = None
1713
+ maxEntriesPerRequest, params = self.handle_option_and_params(params, 'fetchMyTrades', 'maxEntriesPerRequest', 100)
1714
+ if paginate:
1715
+ return await self.fetch_paginated_call_incremental('fetchMyTrades', symbol, since, limit, params, pageKey, maxEntriesPerRequest)
1716
+ market = None
1717
+ if symbol is not None:
1718
+ market = self.market(symbol)
1719
+ page = self.safe_integer(params, pageKey, 1) - 1
1720
+ request: dict = {
1721
+ 'result_offset': self.safe_integer_2(params, 'offset', 'result_offset', page * maxEntriesPerRequest),
1722
+ }
1723
+ if limit is not None:
1724
+ if limit > 100:
1725
+ raise BadRequest(self.id + ' fetchMyTrades() maximum limit is 100. Consider setting paginate to True to fetch more trades.')
1726
+ request['result_limit'] = limit
1727
+ if since is not None:
1728
+ request['time_from'] = self.iso8601(since)
1729
+ until = self.safe_string_n(params, ['until'])
1730
+ if until is not None:
1731
+ params = self.omit(params, ['until'])
1732
+ request['ref_datetime'] = self.iso8601(until)
1733
+ response = await self.v1PrivateGetPortfoliosFills(self.extend(request, params))
1734
+ #
1735
+ # {
1736
+ # "pagination":{
1737
+ # "result_limit":25,
1738
+ # "result_offset":0
1739
+ # },
1740
+ # "results":[
1741
+ # {
1742
+ # "portfolio_id":"1wp37qsc-1-0",
1743
+ # "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
1744
+ # "portfolio_name":"CCXT Portfolio 020624-17:16",
1745
+ # "fill_id":"1xbfy19y-1-184",
1746
+ # "exec_id":"280841526207070392",
1747
+ # "order_id":"1xbfv8yw-1-0",
1748
+ # "instrument_id":"114jqr89-0-0",
1749
+ # "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
1750
+ # "symbol":"BTC-PERP",
1751
+ # "match_id":"280841526207053840",
1752
+ # "fill_price":"52500",
1753
+ # "fill_qty":"0.01",
1754
+ # "client_id":"1x59ctku-1-1",
1755
+ # "client_order_id":"ccxt3e4e2a5f-4a89-",
1756
+ # "order_qty":"0.01",
1757
+ # "limit_price":"52500",
1758
+ # "total_filled":"0.01",
1759
+ # "filled_vwap":"52500",
1760
+ # "expire_time":"",
1761
+ # "stop_price":"",
1762
+ # "side":"BUY",
1763
+ # "tif":"GTC",
1764
+ # "stp_mode":"BOTH",
1765
+ # "flags":"",
1766
+ # "fee":"0.105",
1767
+ # "fee_asset":"USDC",
1768
+ # "order_status":"DONE",
1769
+ # "event_time":"2024-02-15T00:43:57.631Z"
1770
+ # },
1771
+ # ]
1772
+ # }
1773
+ #
1774
+ trades = self.safe_list(response, 'results', [])
1775
+ return self.parse_trades(trades, market, since, limit)
1776
+
1777
+ async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
1778
+ """
1779
+ make a withdrawal
1780
+ :see: https://docs.cloud.coinbase.com/intx/reference/withdraw
1781
+ :see: https://docs.cloud.coinbase.com/intx/reference/counterpartywithdraw
1782
+ :param str code: unified currency code
1783
+ :param float amount: the amount to withdraw
1784
+ :param str address: the address to withdraw to
1785
+ :param str [tag]: an optional tag for the withdrawal
1786
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1787
+ :param boolean [params.add_network_fee_to_total]: if True, deducts network fee from the portfolio, otherwise deduct fee from the withdrawal
1788
+ :param str [params.network_arn_id]: Identifies the blockchain network(e.g., networks/ethereum-mainnet/assets/313ef8a9-ae5a-5f2f-8a56-572c0e2a4d5a)
1789
+ :param str [params.nonce]: a unique integer representing the withdrawal request
1790
+ :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1791
+ """
1792
+ tag, params = self.handle_withdraw_tag_and_params(tag, params)
1793
+ self.check_address(address)
1794
+ await self.load_markets()
1795
+ currency = self.currency(code)
1796
+ portfolio = None
1797
+ portfolio, params = await self.handle_portfolio_and_params('withdraw', params)
1798
+ method = None
1799
+ method, params = self.handle_option_and_params(params, 'withdraw', 'method', 'v1PrivatePostTransfersWithdraw')
1800
+ networkId = None
1801
+ networkId, params = await self.handle_network_id_and_params(code, 'withdraw', params)
1802
+ request: dict = {
1803
+ 'portfolio': portfolio,
1804
+ 'type': 'send',
1805
+ 'asset': currency['id'],
1806
+ 'address': address,
1807
+ 'amount': amount,
1808
+ 'currency': currency['id'],
1809
+ 'network_arn_id': networkId,
1810
+ 'nonce': self.nonce(),
1811
+ }
1812
+ response = await getattr(self, method)(self.extend(request, params))
1813
+ #
1814
+ # {
1815
+ # "idem":"8e471d77-4208-45a8-9e5b-f3bd8a2c1fc3"
1816
+ # }
1817
+ #
1818
+ return self.parse_transaction(response, currency)
1819
+
1820
+ def safe_network(self, network):
1821
+ withdrawEnabled = self.safe_bool(network, 'withdraw')
1822
+ depositEnabled = self.safe_bool(network, 'deposit')
1823
+ limits = self.safe_dict(network, 'limits')
1824
+ withdraw = self.safe_dict(limits, 'withdraw')
1825
+ withdrawMax = self.safe_number(withdraw, 'max')
1826
+ deposit = self.safe_dict(limits, 'deposit')
1827
+ depositMax = self.safe_number(deposit, 'max')
1828
+ if withdrawEnabled is None and withdrawMax is not None:
1829
+ withdrawEnabled = (withdrawMax > 0)
1830
+ if depositEnabled is None and depositMax is not None:
1831
+ depositEnabled = (depositMax > 0)
1832
+ networkId = self.safe_string(network, 'id')
1833
+ isEnabled = (withdrawEnabled and depositEnabled)
1834
+ return {
1835
+ 'info': network['info'],
1836
+ 'id': networkId,
1837
+ 'name': self.safe_string(network, 'name'),
1838
+ 'network': self.safe_string(network, 'network'),
1839
+ 'active': self.safe_bool(network, 'active', isEnabled),
1840
+ 'deposit': depositEnabled,
1841
+ 'withdraw': withdrawEnabled,
1842
+ 'fee': self.safe_number(network, 'fee'),
1843
+ 'precision': self.safe_number(network, 'precision'),
1844
+ 'limits': {
1845
+ 'withdraw': {
1846
+ 'min': self.safe_number(withdraw, 'min'),
1847
+ 'max': withdrawMax,
1848
+ },
1849
+ 'deposit': {
1850
+ 'min': self.safe_number(deposit, 'min'),
1851
+ 'max': depositMax,
1852
+ },
1853
+ },
1854
+ }
1855
+
1856
+ def sign(self, path, api=[], method='GET', params={}, headers=None, body=None):
1857
+ version = api[0]
1858
+ signed = api[1] == 'private'
1859
+ fullPath = '/' + version + '/' + self.implode_params(path, params)
1860
+ query = self.omit(params, self.extract_params(path))
1861
+ savedPath = '/api' + fullPath
1862
+ if method == 'GET' or method == 'DELETE':
1863
+ if query:
1864
+ fullPath += '?' + self.urlencode_with_array_repeat(query)
1865
+ url = self.urls['api']['rest'] + fullPath
1866
+ if signed:
1867
+ self.check_required_credentials()
1868
+ nonce = str(self.nonce())
1869
+ payload = ''
1870
+ if method != 'GET':
1871
+ if query:
1872
+ body = self.json(query)
1873
+ payload = body
1874
+ auth = nonce + method + savedPath + payload
1875
+ signature = self.hmac(self.encode(auth), self.base64_to_binary(self.secret), hashlib.sha256, 'base64')
1876
+ headers = {
1877
+ 'CB-ACCESS-TIMESTAMP': nonce,
1878
+ 'CB-ACCESS-SIGN': signature,
1879
+ 'CB-ACCESS-PASSPHRASE': self.password,
1880
+ 'CB-ACCESS-KEY': self.apiKey,
1881
+ }
1882
+ return {'url': url, 'method': method, 'body': body, 'headers': headers}
1883
+
1884
+ def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
1885
+ #
1886
+ # {
1887
+ # "title":"io.javalin.http.BadRequestResponse: Order rejected(DUPLICATE_CLIENT_ORDER_ID - duplicate client order id detected)",
1888
+ # "status":400
1889
+ # }
1890
+ #
1891
+ if response is None:
1892
+ return None # fallback to default error handler
1893
+ feedback = self.id + ' ' + body
1894
+ errMsg = self.safe_string(response, 'title')
1895
+ if errMsg is not None:
1896
+ self.throw_exactly_matched_exception(self.exceptions['exact'], errMsg, feedback)
1897
+ self.throw_broadly_matched_exception(self.exceptions['broad'], errMsg, feedback)
1898
+ raise ExchangeError(feedback)
1899
+ return None