ccxt-ir 4.3.46.0.3__py2.py3-none-any.whl → 4.5.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 (529) hide show
  1. ccxt/__init__.py +39 -35
  2. ccxt/abantether.py +8 -8
  3. ccxt/abstract/alpaca.py +4 -0
  4. ccxt/abstract/apex.py +31 -0
  5. ccxt/abstract/bigone.py +1 -1
  6. ccxt/abstract/binance.py +106 -48
  7. ccxt/abstract/binancecoinm.py +106 -48
  8. ccxt/abstract/binanceus.py +141 -83
  9. ccxt/abstract/binanceusdm.py +106 -48
  10. ccxt/abstract/bingx.py +50 -1
  11. ccxt/abstract/bitbank.py +5 -0
  12. ccxt/abstract/bitfinex.py +136 -65
  13. ccxt/abstract/bitflyer.py +1 -0
  14. ccxt/abstract/bitget.py +67 -0
  15. ccxt/abstract/bitmart.py +19 -1
  16. ccxt/abstract/bitopro.py +1 -0
  17. ccxt/abstract/bitrue.py +68 -68
  18. ccxt/abstract/bitstamp.py +1 -0
  19. ccxt/abstract/blofin.py +30 -0
  20. ccxt/abstract/btcbox.py +2 -0
  21. ccxt/abstract/bybit.py +28 -13
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbaseexchange.py +1 -0
  24. ccxt/abstract/coinbaseinternational.py +1 -1
  25. ccxt/abstract/cryptocom.py +16 -0
  26. ccxt/abstract/cryptomus.py +20 -0
  27. ccxt/abstract/defx.py +69 -0
  28. ccxt/abstract/deribit.py +1 -0
  29. ccxt/abstract/derive.py +117 -0
  30. ccxt/abstract/digifinex.py +1 -0
  31. ccxt/abstract/ellipx.py +25 -0
  32. ccxt/abstract/foxbit.py +26 -0
  33. ccxt/abstract/gate.py +19 -0
  34. ccxt/abstract/gateio.py +19 -0
  35. ccxt/abstract/gemini.py +1 -0
  36. ccxt/abstract/hibachi.py +26 -0
  37. ccxt/abstract/hyperliquid.py +1 -1
  38. ccxt/abstract/independentreserve.py +6 -0
  39. ccxt/abstract/kraken.py +1 -0
  40. ccxt/abstract/krakenfutures.py +4 -0
  41. ccxt/abstract/kucoin.py +10 -0
  42. ccxt/abstract/kucoinfutures.py +18 -0
  43. ccxt/abstract/lbank.py +2 -1
  44. ccxt/abstract/luno.py +1 -0
  45. ccxt/abstract/mexc.py +2 -0
  46. ccxt/abstract/modetrade.py +119 -0
  47. ccxt/abstract/myokx.py +349 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +25 -0
  50. ccxt/abstract/okxus.py +349 -0
  51. ccxt/abstract/onetrading.py +0 -12
  52. ccxt/abstract/paradex.py +23 -0
  53. ccxt/abstract/phemex.py +2 -0
  54. ccxt/abstract/poloniex.py +36 -0
  55. ccxt/abstract/tradeogre.py +3 -1
  56. ccxt/abstract/upbit.py +51 -34
  57. ccxt/abstract/whitebit.py +16 -0
  58. ccxt/abstract/woo.py +64 -6
  59. ccxt/abstract/xt.py +10 -5
  60. ccxt/afratether.py +8 -8
  61. ccxt/alpaca.py +828 -51
  62. ccxt/apex.py +1875 -0
  63. ccxt/arzinja.py +7 -7
  64. ccxt/arzplus.py +9 -9
  65. ccxt/ascendex.py +501 -306
  66. ccxt/async_support/__init__.py +39 -35
  67. ccxt/async_support/abantether.py +8 -8
  68. ccxt/async_support/afratether.py +10 -10
  69. ccxt/async_support/alpaca.py +828 -51
  70. ccxt/async_support/apex.py +1875 -0
  71. ccxt/async_support/arzinja.py +10 -10
  72. ccxt/async_support/arzplus.py +12 -12
  73. ccxt/async_support/ascendex.py +502 -306
  74. ccxt/async_support/base/exchange.py +303 -89
  75. ccxt/async_support/base/ws/cache.py +9 -3
  76. ccxt/async_support/base/ws/client.py +173 -38
  77. ccxt/async_support/base/ws/future.py +25 -37
  78. ccxt/async_support/bequant.py +5 -3
  79. ccxt/async_support/bigone.py +279 -144
  80. ccxt/async_support/binance.py +2347 -1158
  81. ccxt/async_support/binancecoinm.py +9 -3
  82. ccxt/async_support/binanceus.py +17 -3
  83. ccxt/async_support/binanceusdm.py +9 -4
  84. ccxt/async_support/bingx.py +2962 -920
  85. ccxt/async_support/bit2c.py +147 -27
  86. ccxt/async_support/bitbank.py +151 -23
  87. ccxt/async_support/bitbns.py +104 -30
  88. ccxt/async_support/bitfinex.py +3291 -1113
  89. ccxt/async_support/bitflyer.py +202 -27
  90. ccxt/async_support/bitget.py +3683 -1538
  91. ccxt/async_support/bithumb.py +195 -38
  92. ccxt/async_support/bitimen.py +12 -12
  93. ccxt/async_support/bitir.py +38 -38
  94. ccxt/async_support/bitmart.py +1288 -350
  95. ccxt/async_support/bitmex.py +260 -75
  96. ccxt/async_support/bitopro.py +262 -62
  97. ccxt/async_support/bitpin.py +17 -16
  98. ccxt/async_support/bitrue.py +459 -290
  99. ccxt/async_support/bitso.py +199 -54
  100. ccxt/async_support/bitstamp.py +230 -96
  101. ccxt/async_support/bitteam.py +167 -25
  102. ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
  103. ccxt/async_support/bitvavo.py +213 -49
  104. ccxt/async_support/blockchaincom.py +160 -46
  105. ccxt/async_support/blofin.py +502 -120
  106. ccxt/async_support/btcalpha.py +169 -31
  107. ccxt/async_support/btcbox.py +292 -23
  108. ccxt/async_support/btcmarkets.py +211 -58
  109. ccxt/async_support/btcturk.py +161 -38
  110. ccxt/async_support/bybit.py +1775 -1030
  111. ccxt/async_support/cex.py +1440 -1303
  112. ccxt/async_support/coinbase.py +724 -212
  113. ccxt/async_support/coinbaseadvanced.py +2 -1
  114. ccxt/async_support/coinbaseexchange.py +388 -89
  115. ccxt/async_support/coinbaseinternational.py +412 -57
  116. ccxt/async_support/coincatch.py +177 -78
  117. ccxt/async_support/coincheck.py +135 -19
  118. ccxt/async_support/coinex.py +606 -232
  119. ccxt/async_support/coinmate.py +189 -63
  120. ccxt/async_support/coinmetro.py +195 -54
  121. ccxt/async_support/coinone.py +158 -51
  122. ccxt/async_support/coinsph.py +336 -61
  123. ccxt/async_support/coinspot.py +151 -52
  124. ccxt/async_support/cryptocom.py +661 -111
  125. ccxt/async_support/cryptomus.py +1137 -0
  126. ccxt/async_support/defx.py +2071 -0
  127. ccxt/async_support/delta.py +299 -99
  128. ccxt/async_support/deribit.py +348 -126
  129. ccxt/async_support/derive.py +2572 -0
  130. ccxt/async_support/digifinex.py +430 -214
  131. ccxt/async_support/ellipx.py +2029 -0
  132. ccxt/async_support/eterex.py +10 -10
  133. ccxt/async_support/excoino.py +31 -31
  134. ccxt/async_support/exir.py +14 -14
  135. ccxt/async_support/exmo.py +344 -131
  136. ccxt/async_support/exnovin.py +10 -10
  137. ccxt/async_support/farhadexchange.py +12 -12
  138. ccxt/async_support/fmfwio.py +2 -1
  139. ccxt/async_support/foxbit.py +1935 -0
  140. ccxt/async_support/gate.py +1351 -529
  141. ccxt/async_support/gateio.py +2 -1
  142. ccxt/async_support/gemini.py +144 -39
  143. ccxt/async_support/hashkey.py +152 -109
  144. ccxt/async_support/hibachi.py +2080 -0
  145. ccxt/async_support/hitbtc.py +395 -167
  146. ccxt/async_support/hitobit.py +12 -12
  147. ccxt/async_support/hollaex.py +307 -119
  148. ccxt/async_support/htx.py +851 -383
  149. ccxt/async_support/huobi.py +2 -1
  150. ccxt/async_support/hyperliquid.py +1848 -536
  151. ccxt/async_support/independentreserve.py +288 -15
  152. ccxt/async_support/indodax.py +190 -33
  153. ccxt/async_support/jibitex.py +12 -12
  154. ccxt/async_support/kraken.py +795 -351
  155. ccxt/async_support/krakenfutures.py +214 -62
  156. ccxt/async_support/kucoin.py +715 -396
  157. ccxt/async_support/kucoinfutures.py +652 -89
  158. ccxt/async_support/latoken.py +217 -113
  159. ccxt/async_support/lbank.py +425 -97
  160. ccxt/async_support/luno.py +382 -35
  161. ccxt/async_support/mercado.py +113 -6
  162. ccxt/async_support/mexc.py +874 -437
  163. ccxt/async_support/modetrade.py +2818 -0
  164. ccxt/async_support/myokx.py +54 -0
  165. ccxt/async_support/ndax.py +221 -64
  166. ccxt/async_support/nobitex.py +32 -38
  167. ccxt/async_support/novadax.py +190 -34
  168. ccxt/async_support/oceanex.py +217 -28
  169. ccxt/async_support/okcoin.py +253 -145
  170. ccxt/async_support/okexchange.py +11 -11
  171. ccxt/async_support/okx.py +1088 -351
  172. ccxt/async_support/okxus.py +54 -0
  173. ccxt/async_support/ompfinex.py +32 -27
  174. ccxt/async_support/onetrading.py +213 -392
  175. ccxt/async_support/oxfun.py +245 -166
  176. ccxt/async_support/p2b.py +151 -29
  177. ccxt/async_support/paradex.py +562 -49
  178. ccxt/async_support/paymium.py +82 -19
  179. ccxt/async_support/phemex.py +713 -172
  180. ccxt/async_support/poloniex.py +1602 -283
  181. ccxt/async_support/probit.py +224 -95
  182. ccxt/async_support/ramzinex.py +34 -30
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +15 -14
  186. ccxt/async_support/tetherland.py +9 -9
  187. ccxt/async_support/timex.py +210 -51
  188. ccxt/async_support/tokocrypto.py +167 -47
  189. ccxt/async_support/tradeogre.py +266 -31
  190. ccxt/async_support/twox.py +9 -9
  191. ccxt/async_support/ubitex.py +12 -12
  192. ccxt/async_support/upbit.py +568 -165
  193. ccxt/async_support/vertex.py +160 -32
  194. ccxt/async_support/wallex.py +12 -12
  195. ccxt/async_support/wavesexchange.py +165 -30
  196. ccxt/async_support/whitebit.py +975 -127
  197. ccxt/async_support/woo.py +1918 -1016
  198. ccxt/async_support/woofipro.py +433 -141
  199. ccxt/async_support/xt.py +649 -193
  200. ccxt/async_support/yobit.py +195 -70
  201. ccxt/async_support/zaif.py +91 -15
  202. ccxt/async_support/zonda.py +151 -36
  203. ccxt/base/decimal_to_precision.py +14 -10
  204. ccxt/base/errors.py +49 -18
  205. ccxt/base/exchange.py +1556 -450
  206. ccxt/base/precise.py +10 -0
  207. ccxt/base/types.py +114 -6
  208. ccxt/bequant.py +5 -3
  209. ccxt/bigone.py +279 -144
  210. ccxt/binance.py +2347 -1158
  211. ccxt/binancecoinm.py +9 -3
  212. ccxt/binanceus.py +17 -3
  213. ccxt/binanceusdm.py +9 -4
  214. ccxt/bingx.py +2962 -920
  215. ccxt/bit2c.py +147 -27
  216. ccxt/bitbank.py +151 -23
  217. ccxt/bitbns.py +104 -30
  218. ccxt/bitfinex.py +3290 -1113
  219. ccxt/bitflyer.py +202 -27
  220. ccxt/bitget.py +3683 -1538
  221. ccxt/bithumb.py +194 -38
  222. ccxt/bitimen.py +9 -9
  223. ccxt/bitir.py +35 -35
  224. ccxt/bitmart.py +1288 -350
  225. ccxt/bitmex.py +260 -75
  226. ccxt/bitopro.py +262 -62
  227. ccxt/bitpin.py +15 -14
  228. ccxt/bitrue.py +459 -290
  229. ccxt/bitso.py +199 -54
  230. ccxt/bitstamp.py +230 -96
  231. ccxt/bitteam.py +167 -25
  232. ccxt/{huobijp.py → bittrade.py} +158 -30
  233. ccxt/bitvavo.py +213 -49
  234. ccxt/blockchaincom.py +160 -46
  235. ccxt/blofin.py +502 -120
  236. ccxt/btcalpha.py +169 -31
  237. ccxt/btcbox.py +291 -23
  238. ccxt/btcmarkets.py +211 -58
  239. ccxt/btcturk.py +161 -38
  240. ccxt/bybit.py +1775 -1030
  241. ccxt/cex.py +1439 -1303
  242. ccxt/coinbase.py +724 -212
  243. ccxt/coinbaseadvanced.py +2 -1
  244. ccxt/coinbaseexchange.py +388 -89
  245. ccxt/coinbaseinternational.py +412 -57
  246. ccxt/coincatch.py +177 -78
  247. ccxt/coincheck.py +135 -19
  248. ccxt/coinex.py +606 -232
  249. ccxt/coinmate.py +189 -63
  250. ccxt/coinmetro.py +194 -54
  251. ccxt/coinone.py +158 -51
  252. ccxt/coinsph.py +336 -61
  253. ccxt/coinspot.py +151 -52
  254. ccxt/cryptocom.py +661 -111
  255. ccxt/cryptomus.py +1137 -0
  256. ccxt/defx.py +2070 -0
  257. ccxt/delta.py +299 -99
  258. ccxt/deribit.py +348 -126
  259. ccxt/derive.py +2571 -0
  260. ccxt/digifinex.py +430 -214
  261. ccxt/ellipx.py +2029 -0
  262. ccxt/eterex.py +7 -7
  263. ccxt/excoino.py +29 -29
  264. ccxt/exir.py +11 -11
  265. ccxt/exmo.py +343 -131
  266. ccxt/exnovin.py +8 -8
  267. ccxt/farhadexchange.py +10 -10
  268. ccxt/fmfwio.py +2 -1
  269. ccxt/foxbit.py +1935 -0
  270. ccxt/gate.py +1351 -529
  271. ccxt/gateio.py +2 -1
  272. ccxt/gemini.py +144 -39
  273. ccxt/hashkey.py +152 -109
  274. ccxt/hibachi.py +2079 -0
  275. ccxt/hitbtc.py +395 -167
  276. ccxt/hitobit.py +9 -9
  277. ccxt/hollaex.py +307 -119
  278. ccxt/htx.py +851 -383
  279. ccxt/huobi.py +2 -1
  280. ccxt/hyperliquid.py +1848 -536
  281. ccxt/independentreserve.py +287 -15
  282. ccxt/indodax.py +190 -33
  283. ccxt/jibitex.py +9 -9
  284. ccxt/kraken.py +794 -351
  285. ccxt/krakenfutures.py +214 -62
  286. ccxt/kucoin.py +715 -396
  287. ccxt/kucoinfutures.py +652 -89
  288. ccxt/latoken.py +217 -113
  289. ccxt/lbank.py +425 -97
  290. ccxt/luno.py +382 -35
  291. ccxt/mercado.py +113 -6
  292. ccxt/mexc.py +873 -437
  293. ccxt/modetrade.py +2818 -0
  294. ccxt/myokx.py +54 -0
  295. ccxt/ndax.py +221 -64
  296. ccxt/nobitex.py +30 -36
  297. ccxt/novadax.py +190 -34
  298. ccxt/oceanex.py +217 -28
  299. ccxt/okcoin.py +253 -145
  300. ccxt/okexchange.py +9 -9
  301. ccxt/okx.py +1088 -351
  302. ccxt/okxus.py +54 -0
  303. ccxt/ompfinex.py +29 -24
  304. ccxt/onetrading.py +213 -392
  305. ccxt/oxfun.py +245 -166
  306. ccxt/p2b.py +151 -29
  307. ccxt/paradex.py +562 -49
  308. ccxt/paymium.py +82 -19
  309. ccxt/phemex.py +712 -172
  310. ccxt/poloniex.py +1601 -283
  311. ccxt/pro/__init__.py +76 -17
  312. ccxt/pro/alpaca.py +21 -6
  313. ccxt/pro/apex.py +984 -0
  314. ccxt/pro/ascendex.py +58 -10
  315. ccxt/pro/bequant.py +6 -1
  316. ccxt/pro/binance.py +728 -156
  317. ccxt/pro/binancecoinm.py +6 -2
  318. ccxt/pro/binanceus.py +8 -4
  319. ccxt/pro/binanceusdm.py +7 -2
  320. ccxt/pro/bingx.py +333 -142
  321. ccxt/pro/bitfinex.py +727 -262
  322. ccxt/pro/bitget.py +570 -79
  323. ccxt/pro/bithumb.py +20 -6
  324. ccxt/pro/bitmart.py +216 -87
  325. ccxt/pro/bitmex.py +47 -9
  326. ccxt/pro/bitopro.py +26 -14
  327. ccxt/pro/bitrue.py +22 -22
  328. ccxt/pro/bitstamp.py +54 -21
  329. ccxt/pro/{huobijp.py → bittrade.py} +7 -6
  330. ccxt/pro/bitvavo.py +191 -67
  331. ccxt/pro/blockchaincom.py +21 -8
  332. ccxt/pro/blofin.py +9 -1
  333. ccxt/pro/bybit.py +632 -245
  334. ccxt/pro/cex.py +59 -24
  335. ccxt/pro/coinbase.py +102 -73
  336. ccxt/pro/coinbaseadvanced.py +2 -1
  337. ccxt/pro/coinbaseexchange.py +8 -8
  338. ccxt/pro/coinbaseinternational.py +181 -25
  339. ccxt/pro/coincatch.py +6 -7
  340. ccxt/pro/coincheck.py +11 -6
  341. ccxt/pro/coinex.py +967 -665
  342. ccxt/pro/coinone.py +16 -9
  343. ccxt/pro/cryptocom.py +448 -45
  344. ccxt/pro/defx.py +831 -0
  345. ccxt/pro/deribit.py +150 -14
  346. ccxt/pro/derive.py +704 -0
  347. ccxt/pro/exmo.py +239 -6
  348. ccxt/pro/gate.py +623 -65
  349. ccxt/pro/gateio.py +2 -1
  350. ccxt/pro/gemini.py +27 -11
  351. ccxt/pro/hashkey.py +2 -2
  352. ccxt/pro/hitbtc.py +196 -91
  353. ccxt/pro/hollaex.py +23 -7
  354. ccxt/pro/htx.py +51 -14
  355. ccxt/pro/huobi.py +2 -1
  356. ccxt/pro/hyperliquid.py +591 -27
  357. ccxt/pro/independentreserve.py +9 -6
  358. ccxt/pro/kraken.py +640 -320
  359. ccxt/pro/krakenfutures.py +62 -35
  360. ccxt/pro/kucoin.py +267 -46
  361. ccxt/pro/kucoinfutures.py +165 -21
  362. ccxt/pro/lbank.py +102 -21
  363. ccxt/pro/luno.py +12 -8
  364. ccxt/pro/mexc.py +877 -111
  365. ccxt/pro/modetrade.py +1271 -0
  366. ccxt/pro/myokx.py +38 -0
  367. ccxt/pro/ndax.py +15 -2
  368. ccxt/pro/okcoin.py +23 -4
  369. ccxt/pro/okx.py +573 -98
  370. ccxt/pro/okxus.py +38 -0
  371. ccxt/pro/onetrading.py +30 -13
  372. ccxt/pro/oxfun.py +131 -27
  373. ccxt/pro/p2b.py +88 -22
  374. ccxt/pro/paradex.py +3 -3
  375. ccxt/pro/phemex.py +75 -21
  376. ccxt/pro/poloniex.py +124 -41
  377. ccxt/pro/probit.py +87 -80
  378. ccxt/pro/tradeogre.py +272 -0
  379. ccxt/pro/upbit.py +152 -12
  380. ccxt/pro/vertex.py +8 -3
  381. ccxt/pro/whitebit.py +58 -5
  382. ccxt/pro/woo.py +228 -37
  383. ccxt/pro/woofipro.py +106 -18
  384. ccxt/pro/xt.py +111 -5
  385. ccxt/probit.py +224 -95
  386. ccxt/protobuf/__init__.py +0 -0
  387. ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
  388. ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
  389. ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
  390. ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
  391. ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
  392. ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
  393. ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
  394. ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
  395. ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
  396. ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
  397. ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
  398. ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
  399. ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
  400. ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
  401. ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
  402. ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
  403. ccxt/protobuf/mexc/__init__.py +0 -0
  404. ccxt/ramzinex.py +32 -28
  405. ccxt/sarmayex.py +7 -7
  406. ccxt/sarrafex.py +10 -10
  407. ccxt/static_dependencies/__init__.py +1 -1
  408. ccxt/static_dependencies/lark/py.typed +0 -0
  409. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  410. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  411. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  412. ccxt/tabdeal.py +13 -12
  413. ccxt/test/tests_async.py +261 -57
  414. ccxt/test/tests_helpers.py +1 -3
  415. ccxt/test/tests_init.py +4 -3
  416. ccxt/test/tests_sync.py +261 -57
  417. ccxt/tetherland.py +7 -7
  418. ccxt/timex.py +210 -51
  419. ccxt/tokocrypto.py +167 -47
  420. ccxt/tradeogre.py +266 -31
  421. ccxt/twox.py +7 -7
  422. ccxt/ubitex.py +9 -9
  423. ccxt/upbit.py +568 -165
  424. ccxt/vertex.py +160 -32
  425. ccxt/wallex.py +9 -9
  426. ccxt/wavesexchange.py +165 -30
  427. ccxt/whitebit.py +975 -127
  428. ccxt/woo.py +1917 -1016
  429. ccxt/woofipro.py +432 -141
  430. ccxt/xt.py +649 -193
  431. ccxt/yobit.py +194 -70
  432. ccxt/zaif.py +91 -15
  433. ccxt/zonda.py +151 -36
  434. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.1.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/WHEEL +1 -1
  437. ccxt/__test__.py +0 -7
  438. ccxt/abstract/ace.py +0 -15
  439. ccxt/abstract/bitbay.py +0 -53
  440. ccxt/abstract/bitcoincom.py +0 -115
  441. ccxt/abstract/bitfinex2.py +0 -139
  442. ccxt/abstract/bitpanda.py +0 -35
  443. ccxt/abstract/bl3p.py +0 -19
  444. ccxt/abstract/coinlist.py +0 -54
  445. ccxt/abstract/currencycom.py +0 -68
  446. ccxt/abstract/hitbtc3.py +0 -115
  447. ccxt/abstract/idex.py +0 -26
  448. ccxt/abstract/kuna.py +0 -182
  449. ccxt/abstract/lykke.py +0 -29
  450. ccxt/abstract/poloniexfutures.py +0 -48
  451. ccxt/abstract/wazirx.py +0 -30
  452. ccxt/ace.py +0 -1012
  453. ccxt/async_support/ace.py +0 -1012
  454. ccxt/async_support/base/ws/aiohttp_client.py +0 -125
  455. ccxt/async_support/base/ws/fast_client.py +0 -96
  456. ccxt/async_support/bitbay.py +0 -17
  457. ccxt/async_support/bitcoincom.py +0 -17
  458. ccxt/async_support/bitfinex2.py +0 -3552
  459. ccxt/async_support/bitpanda.py +0 -16
  460. ccxt/async_support/bl3p.py +0 -485
  461. ccxt/async_support/coinlist.py +0 -2243
  462. ccxt/async_support/currencycom.py +0 -1950
  463. ccxt/async_support/hitbtc3.py +0 -16
  464. ccxt/async_support/idex.py +0 -1766
  465. ccxt/async_support/kuna.py +0 -1841
  466. ccxt/async_support/lykke.py +0 -1270
  467. ccxt/async_support/poloniexfutures.py +0 -1717
  468. ccxt/async_support/wazirx.py +0 -1224
  469. ccxt/bitbay.py +0 -17
  470. ccxt/bitcoincom.py +0 -17
  471. ccxt/bitfinex2.py +0 -3552
  472. ccxt/bitpanda.py +0 -16
  473. ccxt/bl3p.py +0 -485
  474. ccxt/coinlist.py +0 -2243
  475. ccxt/currencycom.py +0 -1950
  476. ccxt/hitbtc3.py +0 -16
  477. ccxt/idex.py +0 -1766
  478. ccxt/kuna.py +0 -1841
  479. ccxt/lykke.py +0 -1270
  480. ccxt/poloniexfutures.py +0 -1717
  481. ccxt/pro/bitcoincom.py +0 -34
  482. ccxt/pro/bitfinex2.py +0 -1083
  483. ccxt/pro/bitpanda.py +0 -15
  484. ccxt/pro/currencycom.py +0 -536
  485. ccxt/pro/idex.py +0 -672
  486. ccxt/pro/poloniexfutures.py +0 -990
  487. ccxt/pro/wazirx.py +0 -749
  488. ccxt/test/base/__init__.py +0 -29
  489. ccxt/test/base/test_account.py +0 -26
  490. ccxt/test/base/test_balance.py +0 -56
  491. ccxt/test/base/test_borrow_interest.py +0 -35
  492. ccxt/test/base/test_borrow_rate.py +0 -32
  493. ccxt/test/base/test_calculate_fee.py +0 -51
  494. ccxt/test/base/test_crypto.py +0 -127
  495. ccxt/test/base/test_currency.py +0 -76
  496. ccxt/test/base/test_datetime.py +0 -109
  497. ccxt/test/base/test_decimal_to_precision.py +0 -392
  498. ccxt/test/base/test_deep_extend.py +0 -68
  499. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  500. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  501. ccxt/test/base/test_funding_rate_history.py +0 -29
  502. ccxt/test/base/test_last_price.py +0 -31
  503. ccxt/test/base/test_ledger_entry.py +0 -45
  504. ccxt/test/base/test_ledger_item.py +0 -48
  505. ccxt/test/base/test_leverage_tier.py +0 -33
  506. ccxt/test/base/test_liquidation.py +0 -50
  507. ccxt/test/base/test_margin_mode.py +0 -24
  508. ccxt/test/base/test_margin_modification.py +0 -35
  509. ccxt/test/base/test_market.py +0 -193
  510. ccxt/test/base/test_number.py +0 -411
  511. ccxt/test/base/test_ohlcv.py +0 -33
  512. ccxt/test/base/test_open_interest.py +0 -32
  513. ccxt/test/base/test_order.py +0 -64
  514. ccxt/test/base/test_order_book.py +0 -69
  515. ccxt/test/base/test_position.py +0 -60
  516. ccxt/test/base/test_shared_methods.py +0 -353
  517. ccxt/test/base/test_status.py +0 -24
  518. ccxt/test/base/test_throttle.py +0 -126
  519. ccxt/test/base/test_ticker.py +0 -92
  520. ccxt/test/base/test_trade.py +0 -47
  521. ccxt/test/base/test_trading_fee.py +0 -26
  522. ccxt/test/base/test_transaction.py +0 -39
  523. ccxt/test/test_async.py +0 -1649
  524. ccxt/test/test_sync.py +0 -1648
  525. ccxt/wazirx.py +0 -1224
  526. ccxt_ir-4.3.46.0.3.dist-info/RECORD +0 -773
  527. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  528. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info/licenses}/LICENSE.txt +0 -0
  529. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/top_level.txt +0 -0
ccxt/coinbase.py CHANGED
@@ -6,13 +6,14 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.coinbase import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, Balances, Conversion, Currencies, Currency, Int, Market, MarketInterface, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction
9
+ from ccxt.base.types import Account, Any, Balances, Conversion, Currencies, Currency, DepositAddress, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction, MarketInterface
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
13
13
  from ccxt.base.errors import PermissionDenied
14
14
  from ccxt.base.errors import ArgumentsRequired
15
15
  from ccxt.base.errors import BadRequest
16
+ from ccxt.base.errors import InsufficientFunds
16
17
  from ccxt.base.errors import InvalidOrder
17
18
  from ccxt.base.errors import OrderNotFound
18
19
  from ccxt.base.errors import NotSupported
@@ -24,15 +25,15 @@ from ccxt.base.precise import Precise
24
25
 
25
26
  class coinbase(Exchange, ImplicitAPI):
26
27
 
27
- def describe(self):
28
+ def describe(self) -> Any:
28
29
  return self.deep_extend(super(coinbase, self).describe(), {
29
30
  'id': 'coinbase',
30
31
  'name': 'Coinbase Advanced',
31
32
  'countries': ['US'],
32
33
  'pro': True,
33
- 'certified': True,
34
+ 'certified': False,
34
35
  # rate-limits:
35
- # ADVANCED API: https://docs.cloud.coinbase.com/advanced-trade-api/docs/rest-api-rate-limits
36
+ # ADVANCED API: https://docs.cloud.coinbase.com/advanced-trade/docs/rest-api-rate-limits
36
37
  # - max 30 req/second for private data, 10 req/s for public data
37
38
  # DATA API : https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/rate-limiting
38
39
  # - max 10000 req/hour(to prevent userland mistakes we apply ~3 req/second RL per call
@@ -50,6 +51,9 @@ class coinbase(Exchange, ImplicitAPI):
50
51
  'future': False,
51
52
  'option': False,
52
53
  'addMargin': False,
54
+ 'borrowCrossMargin': False,
55
+ 'borrowIsolatedMargin': False,
56
+ 'borrowMargin': False,
53
57
  'cancelOrder': True,
54
58
  'cancelOrders': True,
55
59
  'closeAllPositions': False,
@@ -64,6 +68,8 @@ class coinbase(Exchange, ImplicitAPI):
64
68
  'createMarketSellOrder': True,
65
69
  'createMarketSellOrderWithCost': False,
66
70
  'createOrder': True,
71
+ 'createOrderWithTakeProfitAndStopLoss': False,
72
+ 'createOrderWithTakeProfitAndStopLossWs': False,
67
73
  'createPostOnlyOrder': True,
68
74
  'createReduceOnlyOrder': False,
69
75
  'createStopLimitOrder': True,
@@ -74,8 +80,12 @@ class coinbase(Exchange, ImplicitAPI):
74
80
  'fetchAccounts': True,
75
81
  'fetchBalance': True,
76
82
  'fetchBidsAsks': True,
83
+ 'fetchBorrowInterest': False,
84
+ 'fetchBorrowRate': False,
77
85
  'fetchBorrowRateHistories': False,
78
86
  'fetchBorrowRateHistory': False,
87
+ 'fetchBorrowRates': False,
88
+ 'fetchBorrowRatesPerSymbol': False,
79
89
  'fetchCanceledOrders': True,
80
90
  'fetchClosedOrders': True,
81
91
  'fetchConvertQuote': True,
@@ -88,44 +98,74 @@ class coinbase(Exchange, ImplicitAPI):
88
98
  'fetchDepositAddress': 'emulated',
89
99
  'fetchDepositAddresses': False,
90
100
  'fetchDepositAddressesByNetwork': True,
101
+ 'fetchDepositMethodId': True,
102
+ 'fetchDepositMethodIds': True,
91
103
  'fetchDeposits': True,
104
+ 'fetchDepositsWithdrawals': True,
92
105
  'fetchFundingHistory': False,
106
+ 'fetchFundingInterval': False,
107
+ 'fetchFundingIntervals': False,
93
108
  'fetchFundingRate': False,
94
109
  'fetchFundingRateHistory': False,
95
110
  'fetchFundingRates': False,
111
+ 'fetchGreeks': False,
96
112
  'fetchIndexOHLCV': False,
97
113
  'fetchIsolatedBorrowRate': False,
98
114
  'fetchIsolatedBorrowRates': False,
115
+ 'fetchIsolatedPositions': False,
99
116
  'fetchL2OrderBook': False,
100
117
  'fetchLedger': True,
101
118
  'fetchLeverage': False,
119
+ 'fetchLeverages': False,
102
120
  'fetchLeverageTiers': False,
121
+ 'fetchLiquidations': False,
122
+ 'fetchLongShortRatio': False,
123
+ 'fetchLongShortRatioHistory': False,
124
+ 'fetchMarginAdjustmentHistory': False,
103
125
  'fetchMarginMode': False,
126
+ 'fetchMarginModes': False,
127
+ 'fetchMarketLeverageTiers': False,
104
128
  'fetchMarkets': True,
105
129
  'fetchMarkOHLCV': False,
130
+ 'fetchMarkPrices': False,
106
131
  'fetchMyBuys': True,
132
+ 'fetchMyLiquidations': False,
107
133
  'fetchMySells': True,
134
+ 'fetchMySettlementHistory': False,
108
135
  'fetchMyTrades': True,
109
136
  'fetchOHLCV': True,
137
+ 'fetchOpenInterest': False,
110
138
  'fetchOpenInterestHistory': False,
139
+ 'fetchOpenInterests': False,
111
140
  'fetchOpenOrders': True,
141
+ 'fetchOption': False,
142
+ 'fetchOptionChain': False,
112
143
  'fetchOrder': True,
113
144
  'fetchOrderBook': True,
114
145
  'fetchOrders': True,
115
146
  'fetchPosition': True,
147
+ 'fetchPositionHistory': False,
116
148
  'fetchPositionMode': False,
117
149
  'fetchPositions': True,
150
+ 'fetchPositionsForSymbol': False,
151
+ 'fetchPositionsHistory': False,
118
152
  'fetchPositionsRisk': False,
119
153
  'fetchPremiumIndexOHLCV': False,
154
+ 'fetchSettlementHistory': False,
120
155
  'fetchTicker': True,
121
156
  'fetchTickers': True,
122
157
  'fetchTime': True,
123
158
  'fetchTrades': True,
124
159
  'fetchTradingFee': 'emulated',
125
160
  'fetchTradingFees': True,
161
+ 'fetchVolatilityHistory': False,
126
162
  'fetchWithdrawals': True,
127
163
  'reduceMargin': False,
164
+ 'repayCrossMargin': False,
165
+ 'repayIsolatedMargin': False,
166
+ 'repayMargin': False,
128
167
  'setLeverage': False,
168
+ 'setMargin': False,
129
169
  'setMarginMode': False,
130
170
  'setPositionMode': False,
131
171
  'withdraw': True,
@@ -138,7 +178,7 @@ class coinbase(Exchange, ImplicitAPI):
138
178
  'www': 'https://www.coinbase.com',
139
179
  'doc': [
140
180
  'https://developers.coinbase.com/api/v2',
141
- 'https://docs.cloud.coinbase.com/advanced-trade-api/docs/welcome',
181
+ 'https://docs.cloud.coinbase.com/advanced-trade/docs/welcome',
142
182
  ],
143
183
  'fees': [
144
184
  'https://support.coinbase.com/customer/portal/articles/2109597-buy-sell-bank-transfer-fees',
@@ -277,8 +317,8 @@ class coinbase(Exchange, ImplicitAPI):
277
317
  },
278
318
  'fees': {
279
319
  'trading': {
280
- 'taker': self.parse_number('0.006'),
281
- 'maker': self.parse_number('0.004'),
320
+ 'taker': self.parse_number('0.012'),
321
+ 'maker': self.parse_number('0.006'), # {"pricing_tier":"Advanced 1","usd_from":"0","usd_to":"1000","taker_fee_rate":"0.012","maker_fee_rate":"0.006","aop_from":"","aop_to":""}
282
322
  'tierBased': True,
283
323
  'percentage': True,
284
324
  'tiers': {
@@ -329,11 +369,14 @@ class coinbase(Exchange, ImplicitAPI):
329
369
  'rate_limit_exceeded': RateLimitExceeded, # 429 Rate limit exceeded
330
370
  'internal_server_error': ExchangeError, # 500 Internal server error
331
371
  'UNSUPPORTED_ORDER_CONFIGURATION': BadRequest,
332
- 'INSUFFICIENT_FUND': BadRequest,
372
+ 'INSUFFICIENT_FUND': InsufficientFunds,
333
373
  'PERMISSION_DENIED': PermissionDenied,
334
374
  'INVALID_ARGUMENT': BadRequest,
375
+ 'PREVIEW_STOP_PRICE_ABOVE_LAST_TRADE_PRICE': InvalidOrder,
376
+ 'PREVIEW_INSUFFICIENT_FUND': InsufficientFunds,
335
377
  },
336
378
  'broad': {
379
+ 'Insufficient balance in source account': InsufficientFunds,
337
380
  'request timestamp expired': InvalidNonce, # {"errors":[{"id":"authentication_error","message":"request timestamp expired"}]}
338
381
  'order with self orderID was not found': OrderNotFound, # {"error":"unknown","error_details":"order with self orderID was not found","message":"order with self orderID was not found"}
339
382
  },
@@ -374,6 +417,8 @@ class coinbase(Exchange, ImplicitAPI):
374
417
  'createMarketBuyOrderRequiresPrice': True,
375
418
  'advanced': True, # set to True if using any v3 endpoints from the advanced trade API
376
419
  'fetchMarkets': 'fetchMarketsV3', # 'fetchMarketsV3' or 'fetchMarketsV2'
420
+ 'timeDifference': 0, # the difference between system clock and exchange server clock
421
+ 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
377
422
  'fetchTicker': 'fetchTickerV3', # 'fetchTickerV3' or 'fetchTickerV2'
378
423
  'fetchTickers': 'fetchTickersV3', # 'fetchTickersV3' or 'fetchTickersV2'
379
424
  'fetchAccounts': 'fetchAccountsV3', # 'fetchAccountsV3' or 'fetchAccountsV2'
@@ -381,12 +426,99 @@ class coinbase(Exchange, ImplicitAPI):
381
426
  'fetchTime': 'v2PublicGetTime', # 'v2PublicGetTime' or 'v3PublicGetBrokerageTime'
382
427
  'user_native_currency': 'USD', # needed to get fees for v3
383
428
  },
429
+ 'features': {
430
+ 'default': {
431
+ 'sandbox': False,
432
+ 'createOrder': {
433
+ 'marginMode': True,
434
+ 'triggerPrice': True,
435
+ 'triggerPriceType': None,
436
+ 'triggerDirection': True,
437
+ 'stopLossPrice': True,
438
+ 'takeProfitPrice': True,
439
+ 'attachedStopLossTakeProfit': None,
440
+ 'timeInForce': {
441
+ 'IOC': True,
442
+ 'FOK': True,
443
+ 'PO': True,
444
+ 'GTD': True,
445
+ },
446
+ 'hedged': False,
447
+ 'trailing': False,
448
+ 'leverage': True, # todo implement
449
+ 'marketBuyByCost': True,
450
+ 'marketBuyRequiresPrice': True,
451
+ 'selfTradePrevention': False,
452
+ 'iceberg': False,
453
+ },
454
+ 'createOrders': None,
455
+ 'fetchMyTrades': {
456
+ 'marginMode': False,
457
+ 'limit': 3000,
458
+ 'daysBack': None,
459
+ 'untilDays': 10000,
460
+ 'symbolRequired': False,
461
+ },
462
+ 'fetchOrder': {
463
+ 'marginMode': False,
464
+ 'trigger': False,
465
+ 'trailing': False,
466
+ 'symbolRequired': False,
467
+ },
468
+ 'fetchOpenOrders': {
469
+ 'marginMode': False,
470
+ 'limit': None,
471
+ 'trigger': False,
472
+ 'trailing': False,
473
+ 'symbolRequired': False,
474
+ },
475
+ 'fetchOrders': {
476
+ 'marginMode': False,
477
+ 'limit': None,
478
+ 'daysBack': None,
479
+ 'untilDays': 10000,
480
+ 'trigger': False,
481
+ 'trailing': False,
482
+ 'symbolRequired': False,
483
+ },
484
+ 'fetchClosedOrders': {
485
+ 'marginMode': False,
486
+ 'limit': None,
487
+ 'daysBack': None,
488
+ 'daysBackCanceled': None,
489
+ 'untilDays': 10000,
490
+ 'trigger': False,
491
+ 'trailing': False,
492
+ 'symbolRequired': False,
493
+ },
494
+ 'fetchOHLCV': {
495
+ 'limit': 300,
496
+ },
497
+ },
498
+ 'spot': {
499
+ 'extends': 'default',
500
+ },
501
+ 'swap': {
502
+ 'linear': {
503
+ 'extends': 'default',
504
+ },
505
+ 'inverse': None,
506
+ },
507
+ 'future': {
508
+ 'linear': {
509
+ 'extends': 'default',
510
+ },
511
+ 'inverse': None,
512
+ },
513
+ },
384
514
  })
385
515
 
386
- def fetch_time(self, params={}):
516
+ def fetch_time(self, params={}) -> Int:
387
517
  """
388
518
  fetches the current integer timestamp in milliseconds from the exchange server
389
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-time#http-request
519
+
520
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-time#http-request
521
+
390
522
  :param dict [params]: extra parameters specific to the exchange API endpoint
391
523
  :param str [params.method]: 'v2PublicGetTime' or 'v3PublicGetBrokerageTime' default is 'v2PublicGetTime'
392
524
  :returns int: the current integer timestamp in milliseconds from the exchange server
@@ -420,8 +552,10 @@ class coinbase(Exchange, ImplicitAPI):
420
552
  def fetch_accounts(self, params={}) -> List[Account]:
421
553
  """
422
554
  fetch all the accounts associated with a profile
423
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getaccounts
424
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-accounts#list-accounts
555
+
556
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getaccounts
557
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-accounts#list-accounts
558
+
425
559
  :param dict [params]: extra parameters specific to the exchange API endpoint
426
560
  :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)
427
561
  :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
@@ -550,7 +684,9 @@ class coinbase(Exchange, ImplicitAPI):
550
684
  def fetch_portfolios(self, params={}) -> List[Account]:
551
685
  """
552
686
  fetch all the portfolios
553
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getportfolios
687
+
688
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getportfolios
689
+
554
690
  :param dict [params]: extra parameters specific to the exchange API endpoint
555
691
  :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
556
692
  """
@@ -637,10 +773,12 @@ class coinbase(Exchange, ImplicitAPI):
637
773
  'info': account,
638
774
  }
639
775
 
640
- def create_deposit_address(self, code: str, params={}):
776
+ def create_deposit_address(self, code: str, params={}) -> DepositAddress:
641
777
  """
642
778
  create a currency deposit address
643
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-addresses#create-address
779
+
780
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-addresses#create-address
781
+
644
782
  :param str code: unified currency code of the currency for the deposit address
645
783
  :param dict [params]: extra parameters specific to the exchange API endpoint
646
784
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
@@ -655,7 +793,7 @@ class coinbase(Exchange, ImplicitAPI):
655
793
  accountId = account['id']
656
794
  break
657
795
  if accountId is None:
658
- raise ExchangeError(self.id + ' createDepositAddress() could not find the account with matching currency code, specify an `account_id` extra param')
796
+ raise ExchangeError(self.id + ' createDepositAddress() could not find the account with matching currency code ' + code + ', specify an `account_id` extra param to target specific wallet')
659
797
  request: dict = {
660
798
  'account_id': accountId,
661
799
  }
@@ -703,14 +841,17 @@ class coinbase(Exchange, ImplicitAPI):
703
841
  'currency': code,
704
842
  'tag': tag,
705
843
  'address': address,
844
+ 'network': None,
706
845
  'info': response,
707
846
  }
708
847
 
709
848
  def fetch_my_sells(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
710
849
  """
711
- * @ignore
850
+ @ignore
712
851
  fetch sells
713
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-sells#list-sells
852
+
853
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-sells#list-sells
854
+
714
855
  :param str symbol: not used by coinbase fetchMySells()
715
856
  :param int [since]: timestamp in ms of the earliest sell, default is None
716
857
  :param int [limit]: max number of sells to return, default is None
@@ -726,9 +867,11 @@ class coinbase(Exchange, ImplicitAPI):
726
867
 
727
868
  def fetch_my_buys(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
728
869
  """
729
- * @ignore
870
+ @ignore
730
871
  fetch buys
731
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-buys#list-buys
872
+
873
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-buys#list-buys
874
+
732
875
  :param str symbol: not used by coinbase fetchMyBuys()
733
876
  :param int [since]: timestamp in ms of the earliest buy, default is None
734
877
  :param int [limit]: max number of buys to return, default is None
@@ -751,30 +894,60 @@ class coinbase(Exchange, ImplicitAPI):
751
894
 
752
895
  def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
753
896
  """
754
- fetch all withdrawals made from an account
755
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-withdrawals#list-withdrawals
897
+ Fetch all withdrawals made from an account. Won't return crypto withdrawals. Use fetchLedger for those.
898
+
899
+ https://docs.cdp.coinbase.com/coinbase-app/docs/api-withdrawals#list-withdrawals
900
+
756
901
  :param str code: unified currency code
757
902
  :param int [since]: the earliest time in ms to fetch withdrawals for
758
903
  :param int [limit]: the maximum number of withdrawals structures to retrieve
759
904
  :param dict [params]: extra parameters specific to the exchange API endpoint
905
+ :param str [params.currencyType]: "fiat" or "crypto"
760
906
  :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
761
907
  """
762
- # fiat only, for crypto transactions use fetchLedger
908
+ currencyType = None
909
+ currencyType, params = self.handle_option_and_params(params, 'fetchWithdrawals', 'currencyType')
910
+ if currencyType == 'crypto':
911
+ results = self.fetch_transactions_with_method('v2PrivateGetAccountsAccountIdTransactions', code, since, limit, params)
912
+ return self.filter_by_array(results, 'type', 'withdrawal', False)
763
913
  return self.fetch_transactions_with_method('v2PrivateGetAccountsAccountIdWithdrawals', code, since, limit, params)
764
914
 
765
915
  def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
766
916
  """
767
- fetch all deposits made to an account
768
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-deposits#list-deposits
917
+ Fetch all fiat deposits made to an account. Won't return crypto deposits or staking rewards. Use fetchLedger for those.
918
+
919
+ https://docs.cdp.coinbase.com/coinbase-app/docs/api-deposits#list-deposits
920
+
769
921
  :param str code: unified currency code
770
922
  :param int [since]: the earliest time in ms to fetch deposits for
771
923
  :param int [limit]: the maximum number of deposits structures to retrieve
772
924
  :param dict [params]: extra parameters specific to the exchange API endpoint
925
+ :param str [params.currencyType]: "fiat" or "crypto"
773
926
  :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
774
927
  """
775
- # fiat only, for crypto transactions use fetchLedger
928
+ currencyType = None
929
+ currencyType, params = self.handle_option_and_params(params, 'fetchWithdrawals', 'currencyType')
930
+ if currencyType == 'crypto':
931
+ results = self.fetch_transactions_with_method('v2PrivateGetAccountsAccountIdTransactions', code, since, limit, params)
932
+ return self.filter_by_array(results, 'type', 'deposit', False)
776
933
  return self.fetch_transactions_with_method('v2PrivateGetAccountsAccountIdDeposits', code, since, limit, params)
777
934
 
935
+ def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
936
+ """
937
+ fetch history of deposits and withdrawals
938
+
939
+ https://docs.cdp.coinbase.com/coinbase-app/docs/api-transactions
940
+
941
+ :param str [code]: unified currency code for the currency of the deposit/withdrawals, default is None
942
+ :param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
943
+ :param int [limit]: max number of deposit/withdrawals to return, default = 50, Min: 1, Max: 100
944
+ :param dict [params]: extra parameters specific to the exchange API endpoint
945
+ :returns dict: a list of `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
946
+ """
947
+ self.load_markets()
948
+ results = self.fetch_transactions_with_method('v2PrivateGetAccountsAccountIdTransactions', code, since, limit, params)
949
+ return self.filter_by_array(results, 'type', ['deposit', 'withdrawal'], False)
950
+
778
951
  def parse_transaction_status(self, status: Str):
779
952
  statuses: dict = {
780
953
  'created': 'pending',
@@ -898,16 +1071,59 @@ class coinbase(Exchange, ImplicitAPI):
898
1071
  # "hide_native_amount": False
899
1072
  # }
900
1073
  #
1074
+ #
1075
+ # crypto deposit & withdrawal(using `/transactions` endpoint)
1076
+ # {
1077
+ # "amount": {
1078
+ # "amount": "0.00014200",(negative for withdrawal)
1079
+ # "currency": "BTC"
1080
+ # },
1081
+ # "created_at": "2024-03-29T15:48:30Z",
1082
+ # "id": "0031a605-241d-514d-a97b-d4b99f3225d3",
1083
+ # "idem": "092a979b-017e-4403-940a-2ca57811f442", # field present only in case of withdrawal
1084
+ # "native_amount": {
1085
+ # "amount": "9.85",(negative for withdrawal)
1086
+ # "currency": "USD"
1087
+ # },
1088
+ # "network": {
1089
+ # "status": "pending", # if status is `off_blockchain` then no more other fields are hasattr(self, present) object
1090
+ # "hash": "5jYuvrNsvX2DZoMnzGYzVpYxJLfYu4GSK3xetG1H5LHrSovsuFCFYdFMwNRoiht3s6fBk92MM8QLLnz65xuEFTrE",
1091
+ # "network_name": "solana",
1092
+ # "transaction_fee": {
1093
+ # "amount": "0.000100000",
1094
+ # "currency": "SOL"
1095
+ # }
1096
+ # },
1097
+ # "resource": "transaction",
1098
+ # "resource_path": "/v2/accounts/dc504b1c-248e-5b68-a3b0-b991f7fa84e6/transactions/0031a605-241d-514d-a97b-d4b99f3225d3",
1099
+ # "status": "completed",
1100
+ # "type": "send",
1101
+ # "from": { # in some cases, field might be present for deposit
1102
+ # "id": "7fd10cd7-b091-5cee-ba41-c29e49a7cccf",
1103
+ # "name": "Coinbase",
1104
+ # "resource": "user"
1105
+ # },
1106
+ # "to": { # field only present for withdrawal
1107
+ # "address": "5HA12BNthAvBwNYARYf9y5MqqCpB4qhCNFCs1Qw48ACE",
1108
+ # "resource": "address"
1109
+ # },
1110
+ # "description": "C3 - One Time BTC Credit . Reference Case # 123.", # in some cases, field might be present for deposit
1111
+ # }
1112
+ #
901
1113
  transactionType = self.safe_string(transaction, 'type')
902
1114
  amountAndCurrencyObject = None
903
1115
  feeObject = None
1116
+ network = self.safe_dict(transaction, 'network', {})
904
1117
  if transactionType == 'send':
905
- network = self.safe_dict(transaction, 'network', {})
906
- amountAndCurrencyObject = self.safe_dict(network, 'transaction_amount', {})
1118
+ amountAndCurrencyObject = self.safe_dict(network, 'transaction_amount')
907
1119
  feeObject = self.safe_dict(network, 'transaction_fee', {})
908
1120
  else:
909
- amountAndCurrencyObject = self.safe_dict(transaction, 'subtotal', {})
1121
+ amountAndCurrencyObject = self.safe_dict(transaction, 'subtotal')
910
1122
  feeObject = self.safe_dict(transaction, 'fee', {})
1123
+ if amountAndCurrencyObject is None:
1124
+ amountAndCurrencyObject = self.safe_dict(transaction, 'amount')
1125
+ amountString = self.safe_string(amountAndCurrencyObject, 'amount')
1126
+ amountStringAbs = Precise.string_abs(amountString)
911
1127
  status = self.parse_transaction_status(self.safe_string(transaction, 'status'))
912
1128
  if status is None:
913
1129
  committed = self.safe_bool(transaction, 'committed')
@@ -916,23 +1132,31 @@ class coinbase(Exchange, ImplicitAPI):
916
1132
  currencyId = self.safe_string(amountAndCurrencyObject, 'currency')
917
1133
  feeCurrencyId = self.safe_string(feeObject, 'currency')
918
1134
  datetime = self.safe_string(transaction, 'created_at')
919
- toObject = self.safe_dict(transaction, 'to', {})
920
- toAddress = self.safe_string(toObject, 'address')
1135
+ resource = self.safe_string(transaction, 'resource')
1136
+ type = resource
1137
+ if not self.in_array(type, ['deposit', 'withdrawal']):
1138
+ if Precise.string_gt(amountString, '0'):
1139
+ type = 'deposit'
1140
+ elif Precise.string_lt(amountString, '0'):
1141
+ type = 'withdrawal'
1142
+ toObject = self.safe_dict(transaction, 'to')
1143
+ addressTo = self.safe_string(toObject, 'address')
1144
+ networkId = self.safe_string(network, 'network_name')
921
1145
  return {
922
1146
  'info': transaction,
923
1147
  'id': id,
924
- 'txid': id,
1148
+ 'txid': self.safe_string(network, 'hash', id),
925
1149
  'timestamp': self.parse8601(datetime),
926
1150
  'datetime': datetime,
927
- 'network': None,
928
- 'address': toAddress,
929
- 'addressTo': toAddress,
1151
+ 'network': self.network_id_to_code(networkId),
1152
+ 'address': addressTo,
1153
+ 'addressTo': addressTo,
930
1154
  'addressFrom': None,
931
1155
  'tag': None,
932
1156
  'tagTo': None,
933
1157
  'tagFrom': None,
934
- 'type': self.safe_string(transaction, 'resource'),
935
- 'amount': self.safe_number(amountAndCurrencyObject, 'amount'),
1158
+ 'type': type,
1159
+ 'amount': self.parse_number(amountStringAbs),
936
1160
  'currency': self.safe_currency_code(currencyId, currency),
937
1161
  'status': status,
938
1162
  'updated': self.parse8601(self.safe_string(transaction, 'updated_at')),
@@ -1069,20 +1293,24 @@ class coinbase(Exchange, ImplicitAPI):
1069
1293
 
1070
1294
  def fetch_markets(self, params={}) -> List[Market]:
1071
1295
  """
1072
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getpublicproducts
1073
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-currencies#get-fiat-currencies
1074
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates
1296
+
1297
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpublicproducts
1298
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-currencies#get-fiat-currencies
1299
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates
1300
+
1075
1301
  retrieves data on all markets for coinbase
1076
1302
  :param dict [params]: extra parameters specific to the exchange API endpoint
1077
1303
  :param boolean [params.usePrivate]: use private endpoint for fetching markets
1078
1304
  :returns dict[]: an array of objects representing market data
1079
1305
  """
1306
+ if self.options['adjustForTimeDifference']:
1307
+ self.load_time_difference()
1080
1308
  method = self.safe_string(self.options, 'fetchMarkets', 'fetchMarketsV3')
1081
1309
  if method == 'fetchMarketsV3':
1082
1310
  return self.fetch_markets_v3(params)
1083
1311
  return self.fetch_markets_v2(params)
1084
1312
 
1085
- def fetch_markets_v2(self, params={}):
1313
+ def fetch_markets_v2(self, params={}) -> List[Market]:
1086
1314
  response = self.fetch_currencies_from_cache(params)
1087
1315
  currencies = self.safe_dict(response, 'currencies', {})
1088
1316
  exchangeRates = self.safe_dict(response, 'exchangeRates', {})
@@ -1101,7 +1329,7 @@ class coinbase(Exchange, ImplicitAPI):
1101
1329
  quoteCurrency = data[j]
1102
1330
  quoteId = self.safe_string(quoteCurrency, 'id')
1103
1331
  quote = self.safe_currency_code(quoteId)
1104
- result.append({
1332
+ result.append(self.safe_market_structure({
1105
1333
  'id': baseId + '-' + quoteId,
1106
1334
  'symbol': base + '/' + quote,
1107
1335
  'base': base,
@@ -1148,10 +1376,10 @@ class coinbase(Exchange, ImplicitAPI):
1148
1376
  },
1149
1377
  },
1150
1378
  'info': quoteCurrency,
1151
- })
1379
+ }))
1152
1380
  return result
1153
1381
 
1154
- def fetch_markets_v3(self, params={}):
1382
+ def fetch_markets_v3(self, params={}) -> List[Market]:
1155
1383
  usePrivate = False
1156
1384
  usePrivate, params = self.handle_option_and_params(params, 'fetchMarkets', 'usePrivate', False)
1157
1385
  spotUnresolvedPromises = []
@@ -1235,9 +1463,6 @@ class coinbase(Exchange, ImplicitAPI):
1235
1463
  self.v3PublicGetBrokerageMarketProducts(self.extend(params, {'product_type': 'FUTURE'})),
1236
1464
  self.v3PublicGetBrokerageMarketProducts(self.extend(params, {'product_type': 'FUTURE', 'contract_expiry_type': 'PERPETUAL'})),
1237
1465
  ]
1238
- if self.check_required_credentials(False):
1239
- unresolvedContractPromises.append(self.extend(params, {'product_type': 'FUTURE'}))
1240
- unresolvedContractPromises.append(self.extend(params, {'product_type': 'FUTURE', 'contract_expiry_type': 'PERPETUAL'}))
1241
1466
  except Exception as e:
1242
1467
  unresolvedContractPromises = [] # the sync version of ccxt won't have the promise.all line so the request is made here. Some users can't access perpetual products
1243
1468
  promises = spotUnresolvedPromises
@@ -1250,8 +1475,8 @@ class coinbase(Exchange, ImplicitAPI):
1250
1475
  fees = self.safe_dict(promises, 1, {})
1251
1476
  expiringFutures = self.safe_dict(contractPromises, 0, {})
1252
1477
  perpetualFutures = self.safe_dict(contractPromises, 1, {})
1253
- expiringFees = self.safe_dict(contractPromises, 2, {})
1254
- perpetualFees = self.safe_dict(contractPromises, 3, {})
1478
+ expiringFees = self.safe_dict(contractPromises, 0, {})
1479
+ perpetualFees = self.safe_dict(contractPromises, 1, {})
1255
1480
  #
1256
1481
  # {
1257
1482
  # "total_volume": 0,
@@ -1284,7 +1509,18 @@ class coinbase(Exchange, ImplicitAPI):
1284
1509
  perpetualData = self.safe_list(perpetualFutures, 'products', [])
1285
1510
  for i in range(0, len(perpetualData)):
1286
1511
  result.append(self.parse_contract_market(perpetualData[i], perpetualFeeTier))
1287
- return result
1512
+ newMarkets = []
1513
+ for i in range(0, len(result)):
1514
+ market = result[i]
1515
+ info = self.safe_value(market, 'info', {})
1516
+ realMarketIds = self.safe_list(info, 'alias_to', [])
1517
+ length = len(realMarketIds)
1518
+ if length > 0:
1519
+ market['alias'] = realMarketIds[0]
1520
+ else:
1521
+ market['alias'] = None
1522
+ newMarkets.append(market)
1523
+ return newMarkets
1288
1524
 
1289
1525
  def parse_spot_market(self, market, feeTier) -> MarketInterface:
1290
1526
  #
@@ -1326,6 +1562,10 @@ class coinbase(Exchange, ImplicitAPI):
1326
1562
  marketType = self.safe_string_lower(market, 'product_type')
1327
1563
  tradingDisabled = self.safe_bool(market, 'trading_disabled')
1328
1564
  stablePairs = self.safe_list(self.options, 'stablePairs', [])
1565
+ defaultTakerFee = self.safe_number(self.fees['trading'], 'taker')
1566
+ defaultMakerFee = self.safe_number(self.fees['trading'], 'maker')
1567
+ takerFee = 0.00001 if self.in_array(id, stablePairs) else self.safe_number(feeTier, 'taker_fee_rate', defaultTakerFee)
1568
+ makerFee = 0.0 if self.in_array(id, stablePairs) else self.safe_number(feeTier, 'maker_fee_rate', defaultMakerFee)
1329
1569
  return self.safe_market_structure({
1330
1570
  'id': id,
1331
1571
  'symbol': base + '/' + quote,
@@ -1345,8 +1585,8 @@ class coinbase(Exchange, ImplicitAPI):
1345
1585
  'contract': False,
1346
1586
  'linear': None,
1347
1587
  'inverse': None,
1348
- 'taker': 0.00001 if self.in_array(id, stablePairs) else self.safe_number(feeTier, 'taker_fee_rate'),
1349
- 'maker': 0.0 if self.in_array(id, stablePairs) else self.safe_number(feeTier, 'maker_fee_rate'),
1588
+ 'taker': takerFee,
1589
+ 'maker': makerFee,
1350
1590
  'contractSize': None,
1351
1591
  'expiry': None,
1352
1592
  'expiryDatetime': None,
@@ -1621,50 +1861,53 @@ class coinbase(Exchange, ImplicitAPI):
1621
1861
  def fetch_currencies(self, params={}) -> Currencies:
1622
1862
  """
1623
1863
  fetches all available currencies on an exchange
1624
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-currencies#get-fiat-currencies
1625
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates
1864
+
1865
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-currencies#get-fiat-currencies
1866
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates
1867
+
1626
1868
  :param dict [params]: extra parameters specific to the exchange API endpoint
1627
1869
  :returns dict: an associative dictionary of currencies
1628
1870
  """
1629
- response = self.fetch_currencies_from_cache(params)
1630
- currencies = self.safe_list(response, 'currencies', [])
1631
- #
1632
- # fiat
1633
- #
1634
- # {
1635
- # id: 'IMP',
1636
- # name: 'Isle of Man Pound',
1637
- # min_size: '0.01'
1638
- # },
1639
- #
1640
- # crypto
1871
+ promises = [
1872
+ self.v2PublicGetCurrencies(params),
1873
+ self.v2PublicGetCurrenciesCrypto(params),
1874
+ self.v2PublicGetExchangeRates(params),
1875
+ ]
1876
+ promisesResult = promises
1877
+ fiatResponse = self.safe_dict(promisesResult, 0, {})
1641
1878
  #
1642
- # {
1643
- # asset_id: '9476e3be-b731-47fa-82be-347fabc573d9',
1644
- # code: 'AERO',
1645
- # name: 'Aerodrome Finance',
1646
- # color: '#0433FF',
1647
- # sort_index: '340',
1648
- # exponent: '8',
1649
- # type: 'crypto',
1650
- # address_regex: '^(?:0x)?[0-9a-fA-F]{40}$'
1651
- # }
1879
+ # [
1880
+ # "data": [
1881
+ # {
1882
+ # id: 'IMP',
1883
+ # name: 'Isle of Man Pound',
1884
+ # min_size: '0.01'
1885
+ # },
1886
+ # ...
1652
1887
  #
1888
+ cryptoResponse = self.safe_dict(promisesResult, 1, {})
1653
1889
  #
1654
- # {
1655
- # "data":{
1656
- # "currency":"USD",
1657
- # "rates":{
1658
- # "AED":"3.67",
1659
- # "AFN":"78.21",
1660
- # "ALL":"110.42",
1661
- # "AMD":"474.18",
1662
- # "ANG":"1.75",
1663
- # ...
1664
- # },
1665
- # }
1666
- # }
1667
- #
1890
+ # [
1891
+ # "data": [
1892
+ # {
1893
+ # asset_id: '9476e3be-b731-47fa-82be-347fabc573d9',
1894
+ # code: 'AERO',
1895
+ # name: 'Aerodrome Finance',
1896
+ # color: '#0433FF',
1897
+ # sort_index: '340',
1898
+ # exponent: '8',
1899
+ # type: 'crypto',
1900
+ # address_regex: '^(?:0x)?[0-9a-fA-F]{40}$'
1901
+ # },
1902
+ # ...
1903
+ #
1904
+ ratesResponse = self.safe_dict(promisesResult, 2, {})
1905
+ fiatData = self.safe_list(fiatResponse, 'data', [])
1906
+ cryptoData = self.safe_list(cryptoResponse, 'data', [])
1907
+ ratesData = self.safe_dict(ratesResponse, 'data', {})
1908
+ rates = self.safe_dict(ratesData, 'rates', {})
1909
+ ratesIds = list(rates.keys())
1910
+ currencies = self.array_concat(fiatData, cryptoData)
1668
1911
  result: dict = {}
1669
1912
  networks: dict = {}
1670
1913
  networksById: dict = {}
@@ -1676,17 +1919,19 @@ class coinbase(Exchange, ImplicitAPI):
1676
1919
  name = self.safe_string(currency, 'name')
1677
1920
  self.options['networks'][code] = name.lower()
1678
1921
  self.options['networksById'][code] = name.lower()
1679
- result[code] = {
1680
- 'info': currency, # the original payload
1922
+ type = 'crypto' if (assetId is not None) else 'fiat'
1923
+ result[code] = self.safe_currency_structure({
1924
+ 'info': currency,
1681
1925
  'id': id,
1682
1926
  'code': code,
1683
- 'type': 'crypto' if (assetId is not None) else 'fiat',
1684
- 'name': self.safe_string(currency, 'name'),
1927
+ 'type': type,
1928
+ 'name': name,
1685
1929
  'active': True,
1686
1930
  'deposit': None,
1687
1931
  'withdraw': None,
1688
1932
  'fee': None,
1689
1933
  'precision': None,
1934
+ 'networks': {}, # todo
1690
1935
  'limits': {
1691
1936
  'amount': {
1692
1937
  'min': self.safe_number(currency, 'min_size'),
@@ -1697,11 +1942,23 @@ class coinbase(Exchange, ImplicitAPI):
1697
1942
  'max': None,
1698
1943
  },
1699
1944
  },
1700
- }
1945
+ })
1701
1946
  if assetId is not None:
1702
1947
  lowerCaseName = name.lower()
1703
1948
  networks[code] = lowerCaseName
1704
1949
  networksById[lowerCaseName] = code
1950
+ # we have to add other currencies here( https://discord.com/channels/1220414409550336183/1220464770239430761/1372215891940479098 )
1951
+ for i in range(0, len(ratesIds)):
1952
+ currencyId = ratesIds[i]
1953
+ code = self.safe_currency_code(currencyId)
1954
+ if not (code in result):
1955
+ result[code] = self.safe_currency_structure({
1956
+ 'info': {},
1957
+ 'id': currencyId,
1958
+ 'code': code,
1959
+ 'type': 'crypto',
1960
+ 'networks': {}, # todo
1961
+ })
1705
1962
  self.options['networks'] = self.extend(networks, self.options['networks'])
1706
1963
  self.options['networksById'] = self.extend(networksById, self.options['networksById'])
1707
1964
  return result
@@ -1709,8 +1966,10 @@ class coinbase(Exchange, ImplicitAPI):
1709
1966
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
1710
1967
  """
1711
1968
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1712
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getproducts
1713
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates
1969
+
1970
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getproducts
1971
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates
1972
+
1714
1973
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1715
1974
  :param dict [params]: extra parameters specific to the exchange API endpoint
1716
1975
  :param boolean [params.usePrivate]: use private endpoint for fetching tickers
@@ -1721,7 +1980,7 @@ class coinbase(Exchange, ImplicitAPI):
1721
1980
  return self.fetch_tickers_v3(symbols, params)
1722
1981
  return self.fetch_tickers_v2(symbols, params)
1723
1982
 
1724
- def fetch_tickers_v2(self, symbols: Strings = None, params={}):
1983
+ def fetch_tickers_v2(self, symbols: Strings = None, params={}) -> Tickers:
1725
1984
  self.load_markets()
1726
1985
  symbols = self.market_symbols(symbols)
1727
1986
  request: dict = {
@@ -1754,7 +2013,7 @@ class coinbase(Exchange, ImplicitAPI):
1754
2013
  result[symbol] = self.parse_ticker(rates[baseId], market)
1755
2014
  return self.filter_by_array_tickers(result, 'symbol', symbols)
1756
2015
 
1757
- def fetch_tickers_v3(self, symbols: Strings = None, params={}):
2016
+ def fetch_tickers_v3(self, symbols: Strings = None, params={}) -> Tickers:
1758
2017
  self.load_markets()
1759
2018
  symbols = self.market_symbols(symbols)
1760
2019
  request: dict = {}
@@ -1821,10 +2080,12 @@ class coinbase(Exchange, ImplicitAPI):
1821
2080
  def fetch_ticker(self, symbol: str, params={}) -> Ticker:
1822
2081
  """
1823
2082
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1824
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getmarkettrades
1825
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-spot-price
1826
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-buy-price
1827
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-sell-price
2083
+
2084
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getmarkettrades
2085
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-spot-price
2086
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-buy-price
2087
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-sell-price
2088
+
1828
2089
  :param str symbol: unified symbol of the market to fetch the ticker for
1829
2090
  :param dict [params]: extra parameters specific to the exchange API endpoint
1830
2091
  :param boolean [params.usePrivate]: whether to use the private endpoint for fetching the ticker
@@ -1931,34 +2192,44 @@ class coinbase(Exchange, ImplicitAPI):
1931
2192
  # fetchTickersV3
1932
2193
  #
1933
2194
  # [
1934
- # {
1935
- # "product_id": "TONE-USD",
1936
- # "price": "0.01523",
1937
- # "price_percentage_change_24h": "1.94109772423025",
1938
- # "volume_24h": "19773129",
1939
- # "volume_percentage_change_24h": "437.0170530929949",
1940
- # "base_increment": "1",
1941
- # "quote_increment": "0.00001",
1942
- # "quote_min_size": "1",
1943
- # "quote_max_size": "10000000",
1944
- # "base_min_size": "26.7187147229469674",
1945
- # "base_max_size": "267187147.2294696735908216",
1946
- # "base_name": "TE-FOOD",
1947
- # "quote_name": "US Dollar",
1948
- # "watched": False,
1949
- # "is_disabled": False,
1950
- # "new": False,
1951
- # "status": "online",
1952
- # "cancel_only": False,
1953
- # "limit_only": False,
1954
- # "post_only": False,
1955
- # "trading_disabled": False,
1956
- # "auction_mode": False,
1957
- # "product_type": "SPOT",
1958
- # "quote_currency_id": "USD",
1959
- # "base_currency_id": "TONE",
1960
- # "fcm_trading_session_details": null,
1961
- # "mid_market_price": ""
2195
+ # {
2196
+ # "product_id": "ETH-USD",
2197
+ # "price": "4471.59",
2198
+ # "price_percentage_change_24h": "0.14243387238731",
2199
+ # "volume_24h": "87329.92990204",
2200
+ # "volume_percentage_change_24h": "-60.7789801794578",
2201
+ # "base_increment": "0.00000001",
2202
+ # "quote_increment": "0.01",
2203
+ # "quote_min_size": "1",
2204
+ # "quote_max_size": "150000000",
2205
+ # "base_min_size": "0.00000001",
2206
+ # "base_max_size": "42000",
2207
+ # "base_name": "Ethereum",
2208
+ # "quote_name": "US Dollar",
2209
+ # "watched": False,
2210
+ # "is_disabled": False,
2211
+ # "new": False,
2212
+ # "status": "online",
2213
+ # "cancel_only": False,
2214
+ # "limit_only": False,
2215
+ # "post_only": False,
2216
+ # "trading_disabled": False,
2217
+ # "auction_mode": False,
2218
+ # "product_type": "SPOT",
2219
+ # "quote_currency_id": "USD",
2220
+ # "base_currency_id": "ETH",
2221
+ # "fcm_trading_session_details": null,
2222
+ # "mid_market_price": "",
2223
+ # "alias": "",
2224
+ # "alias_to": ["ETH-USDC"],
2225
+ # "base_display_symbol": "ETH",
2226
+ # "quote_display_symbol": "USD",
2227
+ # "view_only": False,
2228
+ # "price_increment": "0.01",
2229
+ # "display_name": "ETH-USD",
2230
+ # "product_venue": "CBE",
2231
+ # "approximate_quote_24h_volume": "390503641.25",
2232
+ # "new_at": "2023-01-01T00:00:00Z"
1962
2233
  # },
1963
2234
  # ...
1964
2235
  # ]
@@ -1989,15 +2260,18 @@ class coinbase(Exchange, ImplicitAPI):
1989
2260
  if ('bids' in ticker):
1990
2261
  bids = self.safe_list(ticker, 'bids', [])
1991
2262
  asks = self.safe_list(ticker, 'asks', [])
1992
- bid = self.safe_number(bids[0], 'price')
1993
- bidVolume = self.safe_number(bids[0], 'size')
1994
- ask = self.safe_number(asks[0], 'price')
1995
- askVolume = self.safe_number(asks[0], 'size')
2263
+ firstBid = self.safe_dict(bids, 0, {})
2264
+ firstAsk = self.safe_dict(asks, 0, {})
2265
+ bid = self.safe_number(firstBid, 'price')
2266
+ bidVolume = self.safe_number(firstBid, 'size')
2267
+ ask = self.safe_number(firstAsk, 'price')
2268
+ askVolume = self.safe_number(firstAsk, 'size')
1996
2269
  marketId = self.safe_string(ticker, 'product_id')
2270
+ market = self.safe_market(marketId, market)
1997
2271
  last = self.safe_number(ticker, 'price')
1998
2272
  datetime = self.safe_string(ticker, 'time')
1999
2273
  return self.safe_ticker({
2000
- 'symbol': self.safe_symbol(marketId, market),
2274
+ 'symbol': market['symbol'],
2001
2275
  'timestamp': self.parse8601(datetime),
2002
2276
  'datetime': datetime,
2003
2277
  'bid': bid,
@@ -2014,8 +2288,8 @@ class coinbase(Exchange, ImplicitAPI):
2014
2288
  'change': None,
2015
2289
  'percentage': self.safe_number(ticker, 'price_percentage_change_24h'),
2016
2290
  'average': None,
2017
- 'baseVolume': None,
2018
- 'quoteVolume': None,
2291
+ 'baseVolume': self.safe_number(ticker, 'volume_24h'),
2292
+ 'quoteVolume': self.safe_number(ticker, 'approximate_quote_24h_volume'),
2019
2293
  'info': ticker,
2020
2294
  }, market)
2021
2295
 
@@ -2068,12 +2342,15 @@ class coinbase(Exchange, ImplicitAPI):
2068
2342
  def fetch_balance(self, params={}) -> Balances:
2069
2343
  """
2070
2344
  query for balance and get the amount of funds available for trading or funds locked in orders
2071
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getaccounts
2072
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-accounts#list-accounts
2073
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getfcmbalancesummary
2345
+
2346
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getaccounts
2347
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-accounts#list-accounts
2348
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfcmbalancesummary
2349
+
2074
2350
  :param dict [params]: extra parameters specific to the exchange API endpoint
2075
2351
  :param boolean [params.v3]: default False, set True to use v3 api endpoint
2076
- :param dict [params.type]: "spot"(default) or "swap" or "future"
2352
+ :param str [params.type]: "spot"(default) or "swap" or "future"
2353
+ :param int [params.limit]: default 250, maximum number of accounts to return
2077
2354
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
2078
2355
  """
2079
2356
  self.load_markets()
@@ -2090,7 +2367,7 @@ class coinbase(Exchange, ImplicitAPI):
2090
2367
  request['limit'] = 250
2091
2368
  response = self.v3PrivateGetBrokerageAccounts(self.extend(request, params))
2092
2369
  else:
2093
- request['limit'] = 100
2370
+ request['limit'] = 250
2094
2371
  response = self.v2PrivateGetAccounts(self.extend(request, params))
2095
2372
  #
2096
2373
  # v2PrivateGetAccounts
@@ -2099,7 +2376,7 @@ class coinbase(Exchange, ImplicitAPI):
2099
2376
  # "ending_before":null,
2100
2377
  # "starting_after":null,
2101
2378
  # "previous_ending_before":null,
2102
- # "next_starting_after":"6b17acd6-2e68-5eb0-9f45-72d67cef578b",
2379
+ # "next_starting_after":"6b17acd6-2e68-5eb0-9f45-72d67cef578a",
2103
2380
  # "limit":100,
2104
2381
  # "order":"desc",
2105
2382
  # "previous_uri":null,
@@ -2166,16 +2443,18 @@ class coinbase(Exchange, ImplicitAPI):
2166
2443
  params['type'] = marketType
2167
2444
  return self.parse_custom_balance(response, params)
2168
2445
 
2169
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
2446
+ def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
2170
2447
  """
2171
- fetch the history of changes, actions done by the user or operations that altered balance of the user
2172
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-transactions#list-transactions
2173
- :param str code: unified currency code, default is None
2448
+ Fetch the history of changes, i.e. actions done by the user or operations that altered the balance. Will return staking rewards, and crypto deposits or withdrawals.
2449
+
2450
+ https://docs.cdp.coinbase.com/coinbase-app/docs/api-transactions#list-transactions
2451
+
2452
+ :param str [code]: unified currency code, default is None
2174
2453
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
2175
- :param int [limit]: max number of ledger entrys to return, default is None
2454
+ :param int [limit]: max number of ledger entries to return, default is None
2176
2455
  :param dict [params]: extra parameters specific to the exchange API endpoint
2177
- :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)
2178
- :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
2456
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
2457
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
2179
2458
  """
2180
2459
  self.load_markets()
2181
2460
  paginate = False
@@ -2189,7 +2468,7 @@ class coinbase(Exchange, ImplicitAPI):
2189
2468
  request, params = self.prepare_account_request_with_currency_code(code, limit, params)
2190
2469
  # for pagination use parameter 'starting_after'
2191
2470
  # the value for the next page can be obtained from the result of the previous call in the 'pagination' field
2192
- # eg: instance.last_json_response.pagination.next_starting_after
2471
+ # eg: instance.last_http_response -> pagination.next_starting_after
2193
2472
  response = self.v2PrivateGetAccountsAccountIdTransactions(self.extend(request, params))
2194
2473
  ledger = self.parse_ledger(response['data'], currency, since, limit)
2195
2474
  length = len(ledger)
@@ -2200,7 +2479,7 @@ class coinbase(Exchange, ImplicitAPI):
2200
2479
  pagination = self.safe_dict(response, 'pagination', {})
2201
2480
  cursor = self.safe_string(pagination, 'next_starting_after')
2202
2481
  if (cursor is not None) and (cursor != ''):
2203
- last['next_starting_after'] = cursor
2482
+ last['info']['next_starting_after'] = cursor
2204
2483
  ledger[lastIndex] = last
2205
2484
  return ledger
2206
2485
 
@@ -2224,7 +2503,7 @@ class coinbase(Exchange, ImplicitAPI):
2224
2503
  }
2225
2504
  return self.safe_string(types, type, type)
2226
2505
 
2227
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
2506
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
2228
2507
  #
2229
2508
  # crypto deposit transaction
2230
2509
  #
@@ -2478,6 +2757,7 @@ class coinbase(Exchange, ImplicitAPI):
2478
2757
  direction = 'in'
2479
2758
  currencyId = self.safe_string(amountInfo, 'currency')
2480
2759
  code = self.safe_currency_code(currencyId, currency)
2760
+ currency = self.safe_currency(currencyId, currency)
2481
2761
  #
2482
2762
  # the address and txid do not belong to the unified ledger structure
2483
2763
  #
@@ -2510,7 +2790,7 @@ class coinbase(Exchange, ImplicitAPI):
2510
2790
  numParts = len(parts)
2511
2791
  if numParts > 3:
2512
2792
  accountId = parts[3]
2513
- return {
2793
+ return self.safe_ledger_entry({
2514
2794
  'info': item,
2515
2795
  'id': id,
2516
2796
  'timestamp': timestamp,
@@ -2526,7 +2806,7 @@ class coinbase(Exchange, ImplicitAPI):
2526
2806
  'after': None,
2527
2807
  'status': status,
2528
2808
  'fee': fee,
2529
- }
2809
+ }, currency)
2530
2810
 
2531
2811
  def find_account_id(self, code, params={}):
2532
2812
  self.load_markets()
@@ -2567,7 +2847,9 @@ class coinbase(Exchange, ImplicitAPI):
2567
2847
  def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
2568
2848
  """
2569
2849
  create a market buy order by providing the symbol and cost
2570
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_postorder
2850
+
2851
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_postorder
2852
+
2571
2853
  :param str symbol: unified symbol of the market to create an order in
2572
2854
  :param float cost: how much you want to trade in units of the quote currency
2573
2855
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2583,7 +2865,9 @@ class coinbase(Exchange, ImplicitAPI):
2583
2865
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
2584
2866
  """
2585
2867
  create a trade order
2586
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_postorder
2868
+
2869
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_postorder
2870
+
2587
2871
  :param str symbol: unified symbol of the market to create an order in
2588
2872
  :param str type: 'market' or 'limit'
2589
2873
  :param str side: 'buy' or 'sell'
@@ -2615,10 +2899,10 @@ class coinbase(Exchange, ImplicitAPI):
2615
2899
  'product_id': market['id'],
2616
2900
  'side': side.upper(),
2617
2901
  }
2618
- stopPrice = self.safe_number_n(params, ['stopPrice', 'stop_price', 'triggerPrice'])
2902
+ triggerPrice = self.safe_number_n(params, ['stopPrice', 'stop_price', 'triggerPrice'])
2619
2903
  stopLossPrice = self.safe_number(params, 'stopLossPrice')
2620
2904
  takeProfitPrice = self.safe_number(params, 'takeProfitPrice')
2621
- isStop = stopPrice is not None
2905
+ isStop = triggerPrice is not None
2622
2906
  isStopLoss = stopLossPrice is not None
2623
2907
  isTakeProfit = takeProfitPrice is not None
2624
2908
  timeInForce = self.safe_string(params, 'timeInForce')
@@ -2636,7 +2920,7 @@ class coinbase(Exchange, ImplicitAPI):
2636
2920
  'stop_limit_stop_limit_gtd': {
2637
2921
  'base_size': self.amount_to_precision(symbol, amount),
2638
2922
  'limit_price': self.price_to_precision(symbol, price),
2639
- 'stop_price': self.price_to_precision(symbol, stopPrice),
2923
+ 'stop_price': self.price_to_precision(symbol, triggerPrice),
2640
2924
  'stop_direction': stopDirection,
2641
2925
  'end_time': endTime,
2642
2926
  },
@@ -2646,25 +2930,25 @@ class coinbase(Exchange, ImplicitAPI):
2646
2930
  'stop_limit_stop_limit_gtc': {
2647
2931
  'base_size': self.amount_to_precision(symbol, amount),
2648
2932
  'limit_price': self.price_to_precision(symbol, price),
2649
- 'stop_price': self.price_to_precision(symbol, stopPrice),
2933
+ 'stop_price': self.price_to_precision(symbol, triggerPrice),
2650
2934
  'stop_direction': stopDirection,
2651
2935
  },
2652
2936
  }
2653
2937
  elif isStopLoss or isTakeProfit:
2654
- triggerPrice = None
2938
+ tpslPrice = None
2655
2939
  if isStopLoss:
2656
2940
  if stopDirection is None:
2657
2941
  stopDirection = 'STOP_DIRECTION_STOP_UP' if (side == 'buy') else 'STOP_DIRECTION_STOP_DOWN'
2658
- triggerPrice = self.price_to_precision(symbol, stopLossPrice)
2942
+ tpslPrice = self.price_to_precision(symbol, stopLossPrice)
2659
2943
  else:
2660
2944
  if stopDirection is None:
2661
2945
  stopDirection = 'STOP_DIRECTION_STOP_DOWN' if (side == 'buy') else 'STOP_DIRECTION_STOP_UP'
2662
- triggerPrice = self.price_to_precision(symbol, takeProfitPrice)
2946
+ tpslPrice = self.price_to_precision(symbol, takeProfitPrice)
2663
2947
  request['order_configuration'] = {
2664
2948
  'stop_limit_stop_limit_gtc': {
2665
2949
  'base_size': self.amount_to_precision(symbol, amount),
2666
2950
  'limit_price': self.price_to_precision(symbol, price),
2667
- 'stop_price': triggerPrice,
2951
+ 'stop_price': tpslPrice,
2668
2952
  'stop_direction': stopDirection,
2669
2953
  },
2670
2954
  }
@@ -2915,7 +3199,6 @@ class coinbase(Exchange, ImplicitAPI):
2915
3199
  'postOnly': postOnly,
2916
3200
  'side': self.safe_string_lower(order, 'side'),
2917
3201
  'price': price,
2918
- 'stopPrice': triggerPrice,
2919
3202
  'triggerPrice': triggerPrice,
2920
3203
  'amount': amount,
2921
3204
  'filled': self.safe_string(order, 'filled_size'),
@@ -2965,7 +3248,9 @@ class coinbase(Exchange, ImplicitAPI):
2965
3248
  def cancel_order(self, id: str, symbol: Str = None, params={}):
2966
3249
  """
2967
3250
  cancels an open order
2968
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_cancelorders
3251
+
3252
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_cancelorders
3253
+
2969
3254
  :param str id: order id
2970
3255
  :param str symbol: not used by coinbase cancelOrder()
2971
3256
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2978,7 +3263,9 @@ class coinbase(Exchange, ImplicitAPI):
2978
3263
  def cancel_orders(self, ids, symbol: Str = None, params={}):
2979
3264
  """
2980
3265
  cancel multiple orders
2981
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_cancelorders
3266
+
3267
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_cancelorders
3268
+
2982
3269
  :param str[] ids: order ids
2983
3270
  :param str symbol: not used by coinbase cancelOrders()
2984
3271
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -3013,13 +3300,15 @@ class coinbase(Exchange, ImplicitAPI):
3013
3300
  def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
3014
3301
  """
3015
3302
  edit a trade order
3016
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_editorder
3303
+
3304
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_editorder
3305
+
3017
3306
  :param str id: cancel order id
3018
3307
  :param str symbol: unified symbol of the market to create an order in
3019
3308
  :param str type: 'market' or 'limit'
3020
3309
  :param str side: 'buy' or 'sell'
3021
3310
  :param float amount: how much of currency you want to trade in units of base currency
3022
- :param float [price]: the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
3311
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
3023
3312
  :param dict [params]: extra parameters specific to the exchange API endpoint
3024
3313
  :param boolean [params.preview]: default to False, wether to use the test/preview endpoint or not
3025
3314
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -3054,7 +3343,9 @@ class coinbase(Exchange, ImplicitAPI):
3054
3343
  def fetch_order(self, id: str, symbol: Str = None, params={}):
3055
3344
  """
3056
3345
  fetches information on an order made by the user
3057
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_gethistoricalorder
3346
+
3347
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorder
3348
+
3058
3349
  :param str id: the order id
3059
3350
  :param str symbol: unified market symbol that the order was made in
3060
3351
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -3113,7 +3404,9 @@ class coinbase(Exchange, ImplicitAPI):
3113
3404
  def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = 100, params={}) -> List[Order]:
3114
3405
  """
3115
3406
  fetches information on multiple orders made by the user
3116
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_gethistoricalorders
3407
+
3408
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorders
3409
+
3117
3410
  :param str symbol: unified market symbol that the orders were made in
3118
3411
  :param int [since]: the earliest time in ms to fetch orders
3119
3412
  :param int [limit]: the maximum number of order structures to retrieve
@@ -3265,7 +3558,9 @@ class coinbase(Exchange, ImplicitAPI):
3265
3558
  def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
3266
3559
  """
3267
3560
  fetches information on all currently open orders
3268
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_gethistoricalorders
3561
+
3562
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorders
3563
+
3269
3564
  :param str symbol: unified market symbol of the orders
3270
3565
  :param int [since]: timestamp in ms of the earliest order, default is None
3271
3566
  :param int [limit]: the maximum number of open order structures to retrieve
@@ -3284,7 +3579,9 @@ class coinbase(Exchange, ImplicitAPI):
3284
3579
  def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
3285
3580
  """
3286
3581
  fetches information on multiple closed orders made by the user
3287
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_gethistoricalorders
3582
+
3583
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorders
3584
+
3288
3585
  :param str symbol: unified market symbol of the orders
3289
3586
  :param int [since]: timestamp in ms of the earliest order, default is None
3290
3587
  :param int [limit]: the maximum number of closed order structures to retrieve
@@ -3303,7 +3600,9 @@ class coinbase(Exchange, ImplicitAPI):
3303
3600
  def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3304
3601
  """
3305
3602
  fetches information on multiple canceled orders made by the user
3306
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_gethistoricalorders
3603
+
3604
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorders
3605
+
3307
3606
  :param str symbol: unified market symbol of the orders
3308
3607
  :param int [since]: timestamp in ms of the earliest order, default is None
3309
3608
  :param int [limit]: the maximum number of canceled order structures to retrieve
@@ -3315,7 +3614,9 @@ class coinbase(Exchange, ImplicitAPI):
3315
3614
  def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
3316
3615
  """
3317
3616
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
3318
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getpubliccandles
3617
+
3618
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpubliccandles
3619
+
3319
3620
  :param str symbol: unified symbol of the market to fetch OHLCV data for
3320
3621
  :param str timeframe: the length of time each candle represents
3321
3622
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -3403,7 +3704,9 @@ class coinbase(Exchange, ImplicitAPI):
3403
3704
  def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
3404
3705
  """
3405
3706
  get the list of most recent trades for a particular symbol
3406
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getpublicmarkettrades
3707
+
3708
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpublicmarkettrades
3709
+
3407
3710
  :param str symbol: unified market symbol of the trades
3408
3711
  :param int [since]: not used by coinbase fetchTrades
3409
3712
  :param int [limit]: the maximum number of trade structures to fetch
@@ -3455,7 +3758,9 @@ class coinbase(Exchange, ImplicitAPI):
3455
3758
  def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3456
3759
  """
3457
3760
  fetch all trades made by the user
3458
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getfills
3761
+
3762
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfills
3763
+
3459
3764
  :param str symbol: unified market symbol of the trades
3460
3765
  :param int [since]: timestamp in ms of the earliest order, default is None
3461
3766
  :param int [limit]: the maximum number of trade structures to fetch
@@ -3468,7 +3773,7 @@ class coinbase(Exchange, ImplicitAPI):
3468
3773
  paginate = False
3469
3774
  paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
3470
3775
  if paginate:
3471
- return self.fetch_paginated_call_cursor('fetchMyTrades', symbol, since, limit, params, 'cursor', 'cursor', None, 100)
3776
+ return self.fetch_paginated_call_cursor('fetchMyTrades', symbol, since, limit, params, 'cursor', 'cursor', None, 250)
3472
3777
  market = None
3473
3778
  if symbol is not None:
3474
3779
  market = self.market(symbol)
@@ -3518,7 +3823,9 @@ class coinbase(Exchange, ImplicitAPI):
3518
3823
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
3519
3824
  """
3520
3825
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
3521
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getpublicproductbook
3826
+
3827
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpublicproductbook
3828
+
3522
3829
  :param str symbol: unified symbol of the market to fetch the order book for
3523
3830
  :param int [limit]: the maximum amount of order book entries to return
3524
3831
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -3567,7 +3874,9 @@ class coinbase(Exchange, ImplicitAPI):
3567
3874
  def fetch_bids_asks(self, symbols: Strings = None, params={}):
3568
3875
  """
3569
3876
  fetches the bid and ask price and volume for multiple markets
3570
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getbestbidask
3877
+
3878
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getbestbidask
3879
+
3571
3880
  :param str[] [symbols]: unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
3572
3881
  :param dict [params]: extra parameters specific to the exchange API endpoint
3573
3882
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -3603,10 +3912,12 @@ class coinbase(Exchange, ImplicitAPI):
3603
3912
  tickers = self.safe_list(response, 'pricebooks', [])
3604
3913
  return self.parse_tickers(tickers, symbols)
3605
3914
 
3606
- def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
3915
+ def withdraw(self, code: str, amount: float, address: str, tag: Str = None, params={}) -> Transaction:
3607
3916
  """
3608
3917
  make a withdrawal
3609
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-transactions#send-money
3918
+
3919
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-transactions#send-money
3920
+
3610
3921
  :param str code: unified currency code
3611
3922
  :param float amount: the amount to withdraw
3612
3923
  :param str address: the address to withdraw to
@@ -3691,10 +4002,12 @@ class coinbase(Exchange, ImplicitAPI):
3691
4002
  data = self.safe_dict(response, 'data', {})
3692
4003
  return self.parse_transaction(data, currency)
3693
4004
 
3694
- def fetch_deposit_addresses_by_network(self, code: str, params={}):
4005
+ def fetch_deposit_addresses_by_network(self, code: str, params={}) -> List[DepositAddress]:
3695
4006
  """
3696
4007
  fetch the deposit address for a currency associated with self account
3697
- :see: https://docs.cloud.coinbase.com/exchange/reference/exchangerestapi_postcoinbaseaccountaddresses
4008
+
4009
+ https://docs.cloud.coinbase.com/exchange/reference/exchangerestapi_postcoinbaseaccountaddresses
4010
+
3698
4011
  :param str code: unified currency code
3699
4012
  :param dict [params]: extra parameters specific to the exchange API endpoint
3700
4013
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
@@ -3702,7 +4015,7 @@ class coinbase(Exchange, ImplicitAPI):
3702
4015
  self.load_markets()
3703
4016
  currency = self.currency(code)
3704
4017
  request = None
3705
- request, params = self.prepare_account_request_with_currency_code(currency['code'])
4018
+ request, params = self.prepare_account_request_with_currency_code(currency['code'], None, params)
3706
4019
  response = self.v2PrivateGetAccountsAccountIdAddresses(self.extend(request, params))
3707
4020
  #
3708
4021
  # {
@@ -3763,7 +4076,7 @@ class coinbase(Exchange, ImplicitAPI):
3763
4076
  addressStructures = self.parse_deposit_addresses(data, None, False)
3764
4077
  return self.index_by(addressStructures, 'network')
3765
4078
 
3766
- def parse_deposit_address(self, depositAddress, currency: Currency = None):
4079
+ def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
3767
4080
  #
3768
4081
  # {
3769
4082
  # id: '64ceb5f1-5fa2-5310-a4ff-9fd46271003d',
@@ -3812,21 +4125,25 @@ class coinbase(Exchange, ImplicitAPI):
3812
4125
  networkId = self.safe_string(depositAddress, 'network')
3813
4126
  code = self.safe_currency_code(None, currency)
3814
4127
  addressLabel = self.safe_string(depositAddress, 'address_label')
3815
- splitAddressLabel = addressLabel.split(' ')
3816
- marketId = self.safe_string(splitAddressLabel, 0)
4128
+ currencyId = None
4129
+ if addressLabel is not None:
4130
+ splitAddressLabel = addressLabel.split(' ')
4131
+ currencyId = self.safe_string(splitAddressLabel, 0)
3817
4132
  addressInfo = self.safe_dict(depositAddress, 'address_info')
3818
4133
  return {
3819
4134
  'info': depositAddress,
3820
- 'currency': self.safe_currency_code(marketId, currency),
4135
+ 'currency': self.safe_currency_code(currencyId, currency),
4136
+ 'network': self.network_id_to_code(networkId, code),
3821
4137
  'address': address,
3822
4138
  'tag': self.safe_string(addressInfo, 'destination_tag'),
3823
- 'network': self.network_id_to_code(networkId, code),
3824
4139
  }
3825
4140
 
3826
4141
  def deposit(self, code: str, amount: float, id: str, params={}):
3827
4142
  """
3828
4143
  make a deposit
3829
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-deposits#deposit-funds
4144
+
4145
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-deposits#deposit-funds
4146
+
3830
4147
  :param str code: unified currency code
3831
4148
  :param float amount: the amount to deposit
3832
4149
  :param str id: the payment method id to be used for the deposit, can be retrieved from v2PrivateGetPaymentMethods
@@ -3848,6 +4165,7 @@ class coinbase(Exchange, ImplicitAPI):
3848
4165
  'amount': self.number_to_string(amount),
3849
4166
  'currency': code.upper(), # need to use code in case depositing USD etc.
3850
4167
  'payment_method': id,
4168
+ 'commit': True, # otheriwse the deposit does not go through
3851
4169
  }
3852
4170
  response = self.v2PrivatePostAccountsAccountIdDeposits(self.extend(request, params))
3853
4171
  #
@@ -3886,13 +4204,16 @@ class coinbase(Exchange, ImplicitAPI):
3886
4204
  # }
3887
4205
  # }
3888
4206
  #
3889
- data = self.safe_dict(response, 'data', {})
4207
+ # https://github.com/ccxt/ccxt/issues/25484
4208
+ data = self.safe_dict_2(response, 'data', 'transfer', {})
3890
4209
  return self.parse_transaction(data)
3891
4210
 
3892
4211
  def fetch_deposit(self, id: str, code: Str = None, params={}):
3893
4212
  """
3894
4213
  fetch information on a deposit, fiat only, for crypto transactions use fetchLedger
3895
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-deposits#show-deposit
4214
+
4215
+ https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-deposits#show-deposit
4216
+
3896
4217
  :param str id: deposit id
3897
4218
  :param str [code]: unified currency code
3898
4219
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -3949,13 +4270,100 @@ class coinbase(Exchange, ImplicitAPI):
3949
4270
  # }
3950
4271
  # }
3951
4272
  #
3952
- data = self.safe_dict(response, 'data', {})
4273
+ # https://github.com/ccxt/ccxt/issues/25484
4274
+ data = self.safe_dict_2(response, 'data', 'transfer', {})
3953
4275
  return self.parse_transaction(data)
3954
4276
 
4277
+ def fetch_deposit_method_ids(self, params={}):
4278
+ """
4279
+ fetch the deposit id for a fiat currency associated with self account
4280
+
4281
+ https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpaymentmethods
4282
+
4283
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4284
+ :returns dict: an array of `deposit id structures <https://docs.ccxt.com/#/?id=deposit-id-structure>`
4285
+ """
4286
+ self.load_markets()
4287
+ response = self.v3PrivateGetBrokeragePaymentMethods(params)
4288
+ #
4289
+ # {
4290
+ # "payment_methods": [
4291
+ # {
4292
+ # "id": "21b39a5d-f7b46876fb2e",
4293
+ # "type": "COINBASE_FIAT_ACCOUNT",
4294
+ # "name": "CAD Wallet",
4295
+ # "currency": "CAD",
4296
+ # "verified": True,
4297
+ # "allow_buy": False,
4298
+ # "allow_sell": True,
4299
+ # "allow_deposit": False,
4300
+ # "allow_withdraw": False,
4301
+ # "created_at": "2023-06-29T19:58:46Z",
4302
+ # "updated_at": "2023-10-30T20:25:01Z"
4303
+ # }
4304
+ # ]
4305
+ # }
4306
+ #
4307
+ result = self.safe_list(response, 'payment_methods', [])
4308
+ return self.parse_deposit_method_ids(result)
4309
+
4310
+ def fetch_deposit_method_id(self, id: str, params={}):
4311
+ """
4312
+ fetch the deposit id for a fiat currency associated with self account
4313
+
4314
+ https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpaymentmethod
4315
+
4316
+ :param str id: the deposit payment method id
4317
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4318
+ :returns dict: a `deposit id structure <https://docs.ccxt.com/#/?id=deposit-id-structure>`
4319
+ """
4320
+ self.load_markets()
4321
+ request: dict = {
4322
+ 'payment_method_id': id,
4323
+ }
4324
+ response = self.v3PrivateGetBrokeragePaymentMethodsPaymentMethodId(self.extend(request, params))
4325
+ #
4326
+ # {
4327
+ # "payment_method": {
4328
+ # "id": "21b39a5d-f7b46876fb2e",
4329
+ # "type": "COINBASE_FIAT_ACCOUNT",
4330
+ # "name": "CAD Wallet",
4331
+ # "currency": "CAD",
4332
+ # "verified": True,
4333
+ # "allow_buy": False,
4334
+ # "allow_sell": True,
4335
+ # "allow_deposit": False,
4336
+ # "allow_withdraw": False,
4337
+ # "created_at": "2023-06-29T19:58:46Z",
4338
+ # "updated_at": "2023-10-30T20:25:01Z"
4339
+ # }
4340
+ # }
4341
+ #
4342
+ result = self.safe_dict(response, 'payment_method', {})
4343
+ return self.parse_deposit_method_id(result)
4344
+
4345
+ def parse_deposit_method_ids(self, ids, params={}):
4346
+ result = []
4347
+ for i in range(0, len(ids)):
4348
+ id = self.extend(self.parse_deposit_method_id(ids[i]), params)
4349
+ result.append(id)
4350
+ return result
4351
+
4352
+ def parse_deposit_method_id(self, depositId):
4353
+ return {
4354
+ 'info': depositId,
4355
+ 'id': self.safe_string(depositId, 'id'),
4356
+ 'currency': self.safe_string(depositId, 'currency'),
4357
+ 'verified': self.safe_bool(depositId, 'verified'),
4358
+ 'tag': self.safe_string(depositId, 'name'),
4359
+ }
4360
+
3955
4361
  def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
3956
4362
  """
3957
4363
  fetch a quote for converting from one currency to another
3958
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_createconvertquote
4364
+
4365
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_createconvertquote
4366
+
3959
4367
  :param str fromCode: the currency that you want to sell and convert from
3960
4368
  :param str toCode: the currency that you want to buy and convert into
3961
4369
  :param float [amount]: how much you want to trade in units of the from currency
@@ -3978,7 +4386,9 @@ class coinbase(Exchange, ImplicitAPI):
3978
4386
  def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
3979
4387
  """
3980
4388
  convert from one currency to another
3981
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_commitconverttrade
4389
+
4390
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_commitconverttrade
4391
+
3982
4392
  :param str id: the id of the trade that you want to make
3983
4393
  :param str fromCode: the currency that you want to sell and convert from
3984
4394
  :param str toCode: the currency that you want to buy and convert into
@@ -3999,7 +4409,9 @@ class coinbase(Exchange, ImplicitAPI):
3999
4409
  def fetch_convert_trade(self, id: str, code: Str = None, params={}) -> Conversion:
4000
4410
  """
4001
4411
  fetch the data for a conversion trade
4002
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getconverttrade
4412
+
4413
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getconverttrade
4414
+
4003
4415
  :param str id: the id of the trade that you want to commit
4004
4416
  :param str code: the unified currency code that was converted from
4005
4417
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -4046,18 +4458,18 @@ class coinbase(Exchange, ImplicitAPI):
4046
4458
  def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
4047
4459
  """
4048
4460
  *futures only* closes open positions for a market
4049
- :see: https://coinbase-api.github.io/docs/#/en-us/swapV2/trade-api.html#One-Click%20Close%20All%20Positions
4461
+
4462
+ https://docs.cdp.coinbase.com/coinbase-app/trade/reference/retailbrokerageapi_closeposition
4463
+
4050
4464
  :param str symbol: Unified CCXT market symbol
4051
4465
  :param str [side]: not used by coinbase
4052
4466
  :param dict [params]: extra parameters specific to the coinbase api endpoint
4053
- * @param {str} params.clientOrderId *mandatory* the client order id of the position to close
4467
+ @param {str} params.clientOrderId *mandatory* the client order id of the position to close
4054
4468
  :param float [params.size]: the size of the position to close, optional
4055
4469
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4056
4470
  """
4057
4471
  self.load_markets()
4058
4472
  market = self.market(symbol)
4059
- if not market['future']:
4060
- raise NotSupported(self.id + ' closePosition() only supported for futures markets')
4061
4473
  clientOrderId = self.safe_string_2(params, 'client_order_id', 'clientOrderId')
4062
4474
  params = self.omit(params, 'clientOrderId')
4063
4475
  request: dict = {
@@ -4070,11 +4482,13 @@ class coinbase(Exchange, ImplicitAPI):
4070
4482
  order = self.safe_dict(response, 'success_response', {})
4071
4483
  return self.parse_order(order)
4072
4484
 
4073
- def fetch_positions(self, symbols: Strings = None, params={}):
4485
+ def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
4074
4486
  """
4075
4487
  fetch all open positions
4076
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getfcmpositions
4077
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getintxpositions
4488
+
4489
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfcmpositions
4490
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getintxpositions
4491
+
4078
4492
  :param str[] [symbols]: list of unified market symbols
4079
4493
  :param dict [params]: extra parameters specific to the exchange API endpoint
4080
4494
  :param str [params.portfolio]: the portfolio UUID to fetch positions for
@@ -4105,8 +4519,10 @@ class coinbase(Exchange, ImplicitAPI):
4105
4519
  def fetch_position(self, symbol: str, params={}):
4106
4520
  """
4107
4521
  fetch data on a single open contract trade position
4108
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getintxposition
4109
- :see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getfcmposition
4522
+
4523
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getintxposition
4524
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfcmposition
4525
+
4110
4526
  :param str symbol: unified market symbol of the market the position is held in, default is None
4111
4527
  :param dict [params]: extra parameters specific to the exchange API endpoint
4112
4528
  :param str [params.product_id]: *futures only* the product id of the position to fetch, required for futures markets only
@@ -4274,7 +4690,9 @@ class coinbase(Exchange, ImplicitAPI):
4274
4690
 
4275
4691
  def fetch_trading_fees(self, params={}) -> TradingFees:
4276
4692
  """
4277
- :see: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_gettransactionsummary/
4693
+
4694
+ https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_gettransactionsummary/
4695
+
4278
4696
  fetch the trading fees for multiple markets
4279
4697
  :param dict [params]: extra parameters specific to the exchange API endpoint
4280
4698
  :param str [params.type]: 'spot' or 'swap'
@@ -4329,6 +4747,70 @@ class coinbase(Exchange, ImplicitAPI):
4329
4747
  }
4330
4748
  return result
4331
4749
 
4750
+ def fetch_portfolio_details(self, portfolioUuid: str, params={}) -> List[Any]:
4751
+ """
4752
+ Fetch details for a specific portfolio by UUID
4753
+
4754
+ https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getportfolios
4755
+
4756
+ :param str portfolioUuid: The unique identifier of the portfolio to fetch
4757
+ :param Dict [params]: Extra parameters specific to the exchange API endpoint
4758
+ :returns any[]: An account structure <https://docs.ccxt.com/#/?id=account-structure>
4759
+ """
4760
+ self.load_markets()
4761
+ request = {
4762
+ 'portfolio_uuid': portfolioUuid,
4763
+ }
4764
+ response = self.v3PrivateGetBrokeragePortfoliosPortfolioUuid(self.extend(request, params))
4765
+ result = self.parse_portfolio_details(response)
4766
+ return result
4767
+
4768
+ def parse_portfolio_details(self, portfolioData: dict):
4769
+ breakdown = portfolioData['breakdown']
4770
+ portfolioInfo = self.safe_dict(breakdown, 'portfolio', {})
4771
+ portfolioName = self.safe_string(portfolioInfo, 'name', 'Unknown')
4772
+ portfolioUuid = self.safe_string(portfolioInfo, 'uuid', '')
4773
+ spotPositions = self.safe_list(breakdown, 'spot_positions', [])
4774
+ parsedPositions = []
4775
+ for i in range(0, len(spotPositions)):
4776
+ position: dict = spotPositions[i]
4777
+ currencyCode = self.safe_string(position, 'asset', 'Unknown')
4778
+ availableBalanceStr = self.safe_string(position, 'available_to_trade_fiat', '0')
4779
+ availableBalance = self.parse_number(availableBalanceStr)
4780
+ totalBalanceFiatStr = self.safe_string(position, 'total_balance_fiat', '0')
4781
+ totalBalanceFiat = self.parse_number(totalBalanceFiatStr)
4782
+ holdAmount = totalBalanceFiat - availableBalance
4783
+ costBasisDict = self.safe_dict(position, 'cost_basis', {})
4784
+ costBasisStr = self.safe_string(costBasisDict, 'value', '0')
4785
+ averageEntryPriceDict = self.safe_dict(position, 'average_entry_price', {})
4786
+ averageEntryPriceStr = self.safe_string(averageEntryPriceDict, 'value', '0')
4787
+ positionData: dict = {
4788
+ 'currency': currencyCode,
4789
+ 'available_balance': availableBalance,
4790
+ 'hold_amount': holdAmount > holdAmount if 0 else 0,
4791
+ 'wallet_name': portfolioName,
4792
+ 'account_id': portfolioUuid,
4793
+ 'account_uuid': self.safe_string(position, 'account_uuid', ''),
4794
+ 'total_balance_fiat': totalBalanceFiat,
4795
+ 'total_balance_crypto': self.parse_number(self.safe_string(position, 'total_balance_crypto', '0')),
4796
+ 'available_to_trade_fiat': self.parse_number(self.safe_string(position, 'available_to_trade_fiat', '0')),
4797
+ 'available_to_trade_crypto': self.parse_number(self.safe_string(position, 'available_to_trade_crypto', '0')),
4798
+ 'available_to_transfer_fiat': self.parse_number(self.safe_string(position, 'available_to_transfer_fiat', '0')),
4799
+ 'available_to_transfer_crypto': self.parse_number(self.safe_string(position, 'available_to_trade_crypto', '0')),
4800
+ 'allocation': self.parse_number(self.safe_string(position, 'allocation', '0')),
4801
+ 'cost_basis': self.parse_number(costBasisStr),
4802
+ 'cost_basis_currency': self.safe_string(costBasisDict, 'currency', 'USD'),
4803
+ 'is_cash': self.safe_bool(position, 'is_cash', False),
4804
+ 'average_entry_price': self.parse_number(averageEntryPriceStr),
4805
+ 'average_entry_price_currency': self.safe_string(averageEntryPriceDict, 'currency', 'USD'),
4806
+ 'asset_uuid': self.safe_string(position, 'asset_uuid', ''),
4807
+ 'unrealized_pnl': self.parse_number(self.safe_string(position, 'unrealized_pnl', '0')),
4808
+ 'asset_color': self.safe_string(position, 'asset_color', ''),
4809
+ 'account_type': self.safe_string(position, 'account_type', ''),
4810
+ }
4811
+ parsedPositions.append(positionData)
4812
+ return parsedPositions
4813
+
4332
4814
  def create_auth_token(self, seconds: Int, method: Str = None, url: Str = None):
4333
4815
  # it may not work for v2
4334
4816
  uri = None
@@ -4353,6 +4835,9 @@ class coinbase(Exchange, ImplicitAPI):
4353
4835
  token = self.jwt(request, self.encode(self.secret), 'sha256', False, {'kid': self.apiKey, 'nonce': nonce, 'alg': 'ES256'})
4354
4836
  return token
4355
4837
 
4838
+ def nonce(self):
4839
+ return self.milliseconds() - self.options['timeDifference']
4840
+
4356
4841
  def sign(self, path, api=[], method='GET', params={}, headers=None, body=None):
4357
4842
  version = api[0]
4358
4843
  signed = api[1] == 'private'
@@ -4385,7 +4870,7 @@ class coinbase(Exchange, ImplicitAPI):
4385
4870
  if query:
4386
4871
  payload += '?' + self.urlencode(query)
4387
4872
  # v3: 'GET' doesn't need payload in the signature. inside url is enough
4388
- # https://docs.cloud.coinbase.com/advanced-trade-api/docs/auth#example-request
4873
+ # https://docs.cloud.coinbase.com/advanced-trade/docs/auth#example-request
4389
4874
  # v2: 'GET' require payload in the signature
4390
4875
  # https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-key-authentication
4391
4876
  isCloudAPiKey = (self.apiKey.find('organizations/') >= 0) or (self.secret.startswith('-----BEGIN'))
@@ -4414,7 +4899,9 @@ class coinbase(Exchange, ImplicitAPI):
4414
4899
  # token = self.jwt(request, self.encode(self.secret), 'sha256', False, {'kid': self.apiKey, 'nonce': nonce, 'alg': 'ES256'})
4415
4900
  authorizationString = 'Bearer ' + token
4416
4901
  else:
4417
- timestampString = str(self.seconds())
4902
+ nonce = self.nonce()
4903
+ timestamp = self.parse_to_int(nonce / 1000)
4904
+ timestampString = str(timestamp)
4418
4905
  auth = timestampString + method + savedPath + payload
4419
4906
  signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
4420
4907
  headers = {
@@ -4450,13 +4937,38 @@ class coinbase(Exchange, ImplicitAPI):
4450
4937
  # }
4451
4938
  # ]
4452
4939
  # }
4940
+ # or
4941
+ # {
4942
+ # "success": False,
4943
+ # "error_response": {
4944
+ # "error": "UNKNOWN_FAILURE_REASON",
4945
+ # "message": "",
4946
+ # "error_details": "",
4947
+ # "preview_failure_reason": "PREVIEW_STOP_PRICE_ABOVE_LAST_TRADE_PRICE"
4948
+ # },
4949
+ # "order_configuration": {
4950
+ # "stop_limit_stop_limit_gtc": {
4951
+ # "base_size": "0.0001",
4952
+ # "limit_price": "2000",
4953
+ # "stop_price": "2005",
4954
+ # "stop_direction": "STOP_DIRECTION_STOP_DOWN",
4955
+ # "reduce_only": False
4956
+ # }
4957
+ # }
4958
+ # }
4453
4959
  #
4454
4960
  errorCode = self.safe_string(response, 'error')
4455
4961
  if errorCode is not None:
4456
- errorMessage = self.safe_string(response, 'error_description')
4962
+ errorMessage = self.safe_string_2(response, 'error_description', 'error')
4457
4963
  self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
4458
4964
  self.throw_broadly_matched_exception(self.exceptions['broad'], errorMessage, feedback)
4459
4965
  raise ExchangeError(feedback)
4966
+ errorResponse = self.safe_dict(response, 'error_response')
4967
+ if errorResponse is not None:
4968
+ errorMessageInner = self.safe_string_2(errorResponse, 'preview_failure_reason', 'preview_failure_reason')
4969
+ self.throw_exactly_matched_exception(self.exceptions['exact'], errorMessageInner, feedback)
4970
+ self.throw_broadly_matched_exception(self.exceptions['broad'], errorMessageInner, feedback)
4971
+ raise ExchangeError(feedback)
4460
4972
  errors = self.safe_list(response, 'errors')
4461
4973
  if errors is not None:
4462
4974
  if isinstance(errors, list):