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