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.
- ccxt/__init__.py +39 -35
- ccxt/abantether.py +8 -8
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/apex.py +31 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +106 -48
- ccxt/abstract/binancecoinm.py +106 -48
- ccxt/abstract/binanceus.py +141 -83
- ccxt/abstract/binanceusdm.py +106 -48
- ccxt/abstract/bingx.py +50 -1
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +67 -0
- ccxt/abstract/bitmart.py +19 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitrue.py +68 -68
- ccxt/abstract/bitstamp.py +1 -0
- ccxt/abstract/blofin.py +30 -0
- ccxt/abstract/btcbox.py +2 -0
- ccxt/abstract/bybit.py +28 -13
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbaseexchange.py +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/cryptocom.py +16 -0
- ccxt/abstract/cryptomus.py +20 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/derive.py +117 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/foxbit.py +26 -0
- ccxt/abstract/gate.py +19 -0
- ccxt/abstract/gateio.py +19 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hibachi.py +26 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +1 -0
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +10 -0
- ccxt/abstract/kucoinfutures.py +18 -0
- ccxt/abstract/lbank.py +2 -1
- ccxt/abstract/luno.py +1 -0
- ccxt/abstract/mexc.py +2 -0
- ccxt/abstract/modetrade.py +119 -0
- ccxt/abstract/myokx.py +349 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +25 -0
- ccxt/abstract/okxus.py +349 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/paradex.py +23 -0
- ccxt/abstract/phemex.py +2 -0
- ccxt/abstract/poloniex.py +36 -0
- ccxt/abstract/tradeogre.py +3 -1
- ccxt/abstract/upbit.py +51 -34
- ccxt/abstract/whitebit.py +16 -0
- ccxt/abstract/woo.py +64 -6
- ccxt/abstract/xt.py +10 -5
- ccxt/afratether.py +8 -8
- ccxt/alpaca.py +828 -51
- ccxt/apex.py +1875 -0
- ccxt/arzinja.py +7 -7
- ccxt/arzplus.py +9 -9
- ccxt/ascendex.py +501 -306
- ccxt/async_support/__init__.py +39 -35
- ccxt/async_support/abantether.py +8 -8
- ccxt/async_support/afratether.py +10 -10
- ccxt/async_support/alpaca.py +828 -51
- ccxt/async_support/apex.py +1875 -0
- ccxt/async_support/arzinja.py +10 -10
- ccxt/async_support/arzplus.py +12 -12
- ccxt/async_support/ascendex.py +502 -306
- ccxt/async_support/base/exchange.py +303 -89
- ccxt/async_support/base/ws/cache.py +9 -3
- ccxt/async_support/base/ws/client.py +173 -38
- ccxt/async_support/base/ws/future.py +25 -37
- ccxt/async_support/bequant.py +5 -3
- ccxt/async_support/bigone.py +279 -144
- ccxt/async_support/binance.py +2347 -1158
- ccxt/async_support/binancecoinm.py +9 -3
- ccxt/async_support/binanceus.py +17 -3
- ccxt/async_support/binanceusdm.py +9 -4
- ccxt/async_support/bingx.py +2962 -920
- ccxt/async_support/bit2c.py +147 -27
- ccxt/async_support/bitbank.py +151 -23
- ccxt/async_support/bitbns.py +104 -30
- ccxt/async_support/bitfinex.py +3291 -1113
- ccxt/async_support/bitflyer.py +202 -27
- ccxt/async_support/bitget.py +3683 -1538
- ccxt/async_support/bithumb.py +195 -38
- ccxt/async_support/bitimen.py +12 -12
- ccxt/async_support/bitir.py +38 -38
- ccxt/async_support/bitmart.py +1288 -350
- ccxt/async_support/bitmex.py +260 -75
- ccxt/async_support/bitopro.py +262 -62
- ccxt/async_support/bitpin.py +17 -16
- ccxt/async_support/bitrue.py +459 -290
- ccxt/async_support/bitso.py +199 -54
- ccxt/async_support/bitstamp.py +230 -96
- ccxt/async_support/bitteam.py +167 -25
- ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
- ccxt/async_support/bitvavo.py +213 -49
- ccxt/async_support/blockchaincom.py +160 -46
- ccxt/async_support/blofin.py +502 -120
- ccxt/async_support/btcalpha.py +169 -31
- ccxt/async_support/btcbox.py +292 -23
- ccxt/async_support/btcmarkets.py +211 -58
- ccxt/async_support/btcturk.py +161 -38
- ccxt/async_support/bybit.py +1775 -1030
- ccxt/async_support/cex.py +1440 -1303
- ccxt/async_support/coinbase.py +724 -212
- ccxt/async_support/coinbaseadvanced.py +2 -1
- ccxt/async_support/coinbaseexchange.py +388 -89
- ccxt/async_support/coinbaseinternational.py +412 -57
- ccxt/async_support/coincatch.py +177 -78
- ccxt/async_support/coincheck.py +135 -19
- ccxt/async_support/coinex.py +606 -232
- ccxt/async_support/coinmate.py +189 -63
- ccxt/async_support/coinmetro.py +195 -54
- ccxt/async_support/coinone.py +158 -51
- ccxt/async_support/coinsph.py +336 -61
- ccxt/async_support/coinspot.py +151 -52
- ccxt/async_support/cryptocom.py +661 -111
- ccxt/async_support/cryptomus.py +1137 -0
- ccxt/async_support/defx.py +2071 -0
- ccxt/async_support/delta.py +299 -99
- ccxt/async_support/deribit.py +348 -126
- ccxt/async_support/derive.py +2572 -0
- ccxt/async_support/digifinex.py +430 -214
- ccxt/async_support/ellipx.py +2029 -0
- ccxt/async_support/eterex.py +10 -10
- ccxt/async_support/excoino.py +31 -31
- ccxt/async_support/exir.py +14 -14
- ccxt/async_support/exmo.py +344 -131
- ccxt/async_support/exnovin.py +10 -10
- ccxt/async_support/farhadexchange.py +12 -12
- ccxt/async_support/fmfwio.py +2 -1
- ccxt/async_support/foxbit.py +1935 -0
- ccxt/async_support/gate.py +1351 -529
- ccxt/async_support/gateio.py +2 -1
- ccxt/async_support/gemini.py +144 -39
- ccxt/async_support/hashkey.py +152 -109
- ccxt/async_support/hibachi.py +2080 -0
- ccxt/async_support/hitbtc.py +395 -167
- ccxt/async_support/hitobit.py +12 -12
- ccxt/async_support/hollaex.py +307 -119
- ccxt/async_support/htx.py +851 -383
- ccxt/async_support/huobi.py +2 -1
- ccxt/async_support/hyperliquid.py +1848 -536
- ccxt/async_support/independentreserve.py +288 -15
- ccxt/async_support/indodax.py +190 -33
- ccxt/async_support/jibitex.py +12 -12
- ccxt/async_support/kraken.py +795 -351
- ccxt/async_support/krakenfutures.py +214 -62
- ccxt/async_support/kucoin.py +715 -396
- ccxt/async_support/kucoinfutures.py +652 -89
- ccxt/async_support/latoken.py +217 -113
- ccxt/async_support/lbank.py +425 -97
- ccxt/async_support/luno.py +382 -35
- ccxt/async_support/mercado.py +113 -6
- ccxt/async_support/mexc.py +874 -437
- ccxt/async_support/modetrade.py +2818 -0
- ccxt/async_support/myokx.py +54 -0
- ccxt/async_support/ndax.py +221 -64
- ccxt/async_support/nobitex.py +32 -38
- ccxt/async_support/novadax.py +190 -34
- ccxt/async_support/oceanex.py +217 -28
- ccxt/async_support/okcoin.py +253 -145
- ccxt/async_support/okexchange.py +11 -11
- ccxt/async_support/okx.py +1088 -351
- ccxt/async_support/okxus.py +54 -0
- ccxt/async_support/ompfinex.py +32 -27
- ccxt/async_support/onetrading.py +213 -392
- ccxt/async_support/oxfun.py +245 -166
- ccxt/async_support/p2b.py +151 -29
- ccxt/async_support/paradex.py +562 -49
- ccxt/async_support/paymium.py +82 -19
- ccxt/async_support/phemex.py +713 -172
- ccxt/async_support/poloniex.py +1602 -283
- ccxt/async_support/probit.py +224 -95
- ccxt/async_support/ramzinex.py +34 -30
- ccxt/async_support/sarmayex.py +9 -9
- ccxt/async_support/sarrafex.py +13 -13
- ccxt/async_support/tabdeal.py +15 -14
- ccxt/async_support/tetherland.py +9 -9
- ccxt/async_support/timex.py +210 -51
- ccxt/async_support/tokocrypto.py +167 -47
- ccxt/async_support/tradeogre.py +266 -31
- ccxt/async_support/twox.py +9 -9
- ccxt/async_support/ubitex.py +12 -12
- ccxt/async_support/upbit.py +568 -165
- ccxt/async_support/vertex.py +160 -32
- ccxt/async_support/wallex.py +12 -12
- ccxt/async_support/wavesexchange.py +165 -30
- ccxt/async_support/whitebit.py +975 -127
- ccxt/async_support/woo.py +1918 -1016
- ccxt/async_support/woofipro.py +433 -141
- ccxt/async_support/xt.py +649 -193
- ccxt/async_support/yobit.py +195 -70
- ccxt/async_support/zaif.py +91 -15
- ccxt/async_support/zonda.py +151 -36
- ccxt/base/decimal_to_precision.py +14 -10
- ccxt/base/errors.py +49 -18
- ccxt/base/exchange.py +1556 -450
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +114 -6
- ccxt/bequant.py +5 -3
- ccxt/bigone.py +279 -144
- ccxt/binance.py +2347 -1158
- ccxt/binancecoinm.py +9 -3
- ccxt/binanceus.py +17 -3
- ccxt/binanceusdm.py +9 -4
- ccxt/bingx.py +2962 -920
- ccxt/bit2c.py +147 -27
- ccxt/bitbank.py +151 -23
- ccxt/bitbns.py +104 -30
- ccxt/bitfinex.py +3290 -1113
- ccxt/bitflyer.py +202 -27
- ccxt/bitget.py +3683 -1538
- ccxt/bithumb.py +194 -38
- ccxt/bitimen.py +9 -9
- ccxt/bitir.py +35 -35
- ccxt/bitmart.py +1288 -350
- ccxt/bitmex.py +260 -75
- ccxt/bitopro.py +262 -62
- ccxt/bitpin.py +15 -14
- ccxt/bitrue.py +459 -290
- ccxt/bitso.py +199 -54
- ccxt/bitstamp.py +230 -96
- ccxt/bitteam.py +167 -25
- ccxt/{huobijp.py → bittrade.py} +158 -30
- ccxt/bitvavo.py +213 -49
- ccxt/blockchaincom.py +160 -46
- ccxt/blofin.py +502 -120
- ccxt/btcalpha.py +169 -31
- ccxt/btcbox.py +291 -23
- ccxt/btcmarkets.py +211 -58
- ccxt/btcturk.py +161 -38
- ccxt/bybit.py +1775 -1030
- ccxt/cex.py +1439 -1303
- ccxt/coinbase.py +724 -212
- ccxt/coinbaseadvanced.py +2 -1
- ccxt/coinbaseexchange.py +388 -89
- ccxt/coinbaseinternational.py +412 -57
- ccxt/coincatch.py +177 -78
- ccxt/coincheck.py +135 -19
- ccxt/coinex.py +606 -232
- ccxt/coinmate.py +189 -63
- ccxt/coinmetro.py +194 -54
- ccxt/coinone.py +158 -51
- ccxt/coinsph.py +336 -61
- ccxt/coinspot.py +151 -52
- ccxt/cryptocom.py +661 -111
- ccxt/cryptomus.py +1137 -0
- ccxt/defx.py +2070 -0
- ccxt/delta.py +299 -99
- ccxt/deribit.py +348 -126
- ccxt/derive.py +2571 -0
- ccxt/digifinex.py +430 -214
- ccxt/ellipx.py +2029 -0
- ccxt/eterex.py +7 -7
- ccxt/excoino.py +29 -29
- ccxt/exir.py +11 -11
- ccxt/exmo.py +343 -131
- ccxt/exnovin.py +8 -8
- ccxt/farhadexchange.py +10 -10
- ccxt/fmfwio.py +2 -1
- ccxt/foxbit.py +1935 -0
- ccxt/gate.py +1351 -529
- ccxt/gateio.py +2 -1
- ccxt/gemini.py +144 -39
- ccxt/hashkey.py +152 -109
- ccxt/hibachi.py +2079 -0
- ccxt/hitbtc.py +395 -167
- ccxt/hitobit.py +9 -9
- ccxt/hollaex.py +307 -119
- ccxt/htx.py +851 -383
- ccxt/huobi.py +2 -1
- ccxt/hyperliquid.py +1848 -536
- ccxt/independentreserve.py +287 -15
- ccxt/indodax.py +190 -33
- ccxt/jibitex.py +9 -9
- ccxt/kraken.py +794 -351
- ccxt/krakenfutures.py +214 -62
- ccxt/kucoin.py +715 -396
- ccxt/kucoinfutures.py +652 -89
- ccxt/latoken.py +217 -113
- ccxt/lbank.py +425 -97
- ccxt/luno.py +382 -35
- ccxt/mercado.py +113 -6
- ccxt/mexc.py +873 -437
- ccxt/modetrade.py +2818 -0
- ccxt/myokx.py +54 -0
- ccxt/ndax.py +221 -64
- ccxt/nobitex.py +30 -36
- ccxt/novadax.py +190 -34
- ccxt/oceanex.py +217 -28
- ccxt/okcoin.py +253 -145
- ccxt/okexchange.py +9 -9
- ccxt/okx.py +1088 -351
- ccxt/okxus.py +54 -0
- ccxt/ompfinex.py +29 -24
- ccxt/onetrading.py +213 -392
- ccxt/oxfun.py +245 -166
- ccxt/p2b.py +151 -29
- ccxt/paradex.py +562 -49
- ccxt/paymium.py +82 -19
- ccxt/phemex.py +712 -172
- ccxt/poloniex.py +1601 -283
- ccxt/pro/__init__.py +76 -17
- ccxt/pro/alpaca.py +21 -6
- ccxt/pro/apex.py +984 -0
- ccxt/pro/ascendex.py +58 -10
- ccxt/pro/bequant.py +6 -1
- ccxt/pro/binance.py +728 -156
- ccxt/pro/binancecoinm.py +6 -2
- ccxt/pro/binanceus.py +8 -4
- ccxt/pro/binanceusdm.py +7 -2
- ccxt/pro/bingx.py +333 -142
- ccxt/pro/bitfinex.py +727 -262
- ccxt/pro/bitget.py +570 -79
- ccxt/pro/bithumb.py +20 -6
- ccxt/pro/bitmart.py +216 -87
- ccxt/pro/bitmex.py +47 -9
- ccxt/pro/bitopro.py +26 -14
- ccxt/pro/bitrue.py +22 -22
- ccxt/pro/bitstamp.py +54 -21
- ccxt/pro/{huobijp.py → bittrade.py} +7 -6
- ccxt/pro/bitvavo.py +191 -67
- ccxt/pro/blockchaincom.py +21 -8
- ccxt/pro/blofin.py +9 -1
- ccxt/pro/bybit.py +632 -245
- ccxt/pro/cex.py +59 -24
- ccxt/pro/coinbase.py +102 -73
- ccxt/pro/coinbaseadvanced.py +2 -1
- ccxt/pro/coinbaseexchange.py +8 -8
- ccxt/pro/coinbaseinternational.py +181 -25
- ccxt/pro/coincatch.py +6 -7
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +967 -665
- ccxt/pro/coinone.py +16 -9
- ccxt/pro/cryptocom.py +448 -45
- ccxt/pro/defx.py +831 -0
- ccxt/pro/deribit.py +150 -14
- ccxt/pro/derive.py +704 -0
- ccxt/pro/exmo.py +239 -6
- ccxt/pro/gate.py +623 -65
- ccxt/pro/gateio.py +2 -1
- ccxt/pro/gemini.py +27 -11
- ccxt/pro/hashkey.py +2 -2
- ccxt/pro/hitbtc.py +196 -91
- ccxt/pro/hollaex.py +23 -7
- ccxt/pro/htx.py +51 -14
- ccxt/pro/huobi.py +2 -1
- ccxt/pro/hyperliquid.py +591 -27
- ccxt/pro/independentreserve.py +9 -6
- ccxt/pro/kraken.py +640 -320
- ccxt/pro/krakenfutures.py +62 -35
- ccxt/pro/kucoin.py +267 -46
- ccxt/pro/kucoinfutures.py +165 -21
- ccxt/pro/lbank.py +102 -21
- ccxt/pro/luno.py +12 -8
- ccxt/pro/mexc.py +877 -111
- ccxt/pro/modetrade.py +1271 -0
- ccxt/pro/myokx.py +38 -0
- ccxt/pro/ndax.py +15 -2
- ccxt/pro/okcoin.py +23 -4
- ccxt/pro/okx.py +573 -98
- ccxt/pro/okxus.py +38 -0
- ccxt/pro/onetrading.py +30 -13
- ccxt/pro/oxfun.py +131 -27
- ccxt/pro/p2b.py +88 -22
- ccxt/pro/paradex.py +3 -3
- ccxt/pro/phemex.py +75 -21
- ccxt/pro/poloniex.py +124 -41
- ccxt/pro/probit.py +87 -80
- ccxt/pro/tradeogre.py +272 -0
- ccxt/pro/upbit.py +152 -12
- ccxt/pro/vertex.py +8 -3
- ccxt/pro/whitebit.py +58 -5
- ccxt/pro/woo.py +228 -37
- ccxt/pro/woofipro.py +106 -18
- ccxt/pro/xt.py +111 -5
- ccxt/probit.py +224 -95
- ccxt/protobuf/__init__.py +0 -0
- ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
- ccxt/protobuf/mexc/__init__.py +0 -0
- ccxt/ramzinex.py +32 -28
- ccxt/sarmayex.py +7 -7
- ccxt/sarrafex.py +10 -10
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/tabdeal.py +13 -12
- ccxt/test/tests_async.py +261 -57
- ccxt/test/tests_helpers.py +1 -3
- ccxt/test/tests_init.py +4 -3
- ccxt/test/tests_sync.py +261 -57
- ccxt/tetherland.py +7 -7
- ccxt/timex.py +210 -51
- ccxt/tokocrypto.py +167 -47
- ccxt/tradeogre.py +266 -31
- ccxt/twox.py +7 -7
- ccxt/ubitex.py +9 -9
- ccxt/upbit.py +568 -165
- ccxt/vertex.py +160 -32
- ccxt/wallex.py +9 -9
- ccxt/wavesexchange.py +165 -30
- ccxt/whitebit.py +975 -127
- ccxt/woo.py +1917 -1016
- ccxt/woofipro.py +432 -141
- ccxt/xt.py +649 -193
- ccxt/yobit.py +194 -70
- ccxt/zaif.py +91 -15
- ccxt/zonda.py +151 -36
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/METADATA +225 -73
- ccxt_ir-4.5.1.dist-info/RECORD +743 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/WHEEL +1 -1
- ccxt/__test__.py +0 -7
- ccxt/abstract/ace.py +0 -15
- ccxt/abstract/bitbay.py +0 -53
- ccxt/abstract/bitcoincom.py +0 -115
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/bitpanda.py +0 -35
- ccxt/abstract/bl3p.py +0 -19
- ccxt/abstract/coinlist.py +0 -54
- ccxt/abstract/currencycom.py +0 -68
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/abstract/idex.py +0 -26
- ccxt/abstract/kuna.py +0 -182
- ccxt/abstract/lykke.py +0 -29
- ccxt/abstract/poloniexfutures.py +0 -48
- ccxt/abstract/wazirx.py +0 -30
- ccxt/ace.py +0 -1012
- ccxt/async_support/ace.py +0 -1012
- ccxt/async_support/base/ws/aiohttp_client.py +0 -125
- ccxt/async_support/base/ws/fast_client.py +0 -96
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitcoincom.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3552
- ccxt/async_support/bitpanda.py +0 -16
- ccxt/async_support/bl3p.py +0 -485
- ccxt/async_support/coinlist.py +0 -2243
- ccxt/async_support/currencycom.py +0 -1950
- ccxt/async_support/hitbtc3.py +0 -16
- ccxt/async_support/idex.py +0 -1766
- ccxt/async_support/kuna.py +0 -1841
- ccxt/async_support/lykke.py +0 -1270
- ccxt/async_support/poloniexfutures.py +0 -1717
- ccxt/async_support/wazirx.py +0 -1224
- ccxt/bitbay.py +0 -17
- ccxt/bitcoincom.py +0 -17
- ccxt/bitfinex2.py +0 -3552
- ccxt/bitpanda.py +0 -16
- ccxt/bl3p.py +0 -485
- ccxt/coinlist.py +0 -2243
- ccxt/currencycom.py +0 -1950
- ccxt/hitbtc3.py +0 -16
- ccxt/idex.py +0 -1766
- ccxt/kuna.py +0 -1841
- ccxt/lykke.py +0 -1270
- ccxt/poloniexfutures.py +0 -1717
- ccxt/pro/bitcoincom.py +0 -34
- ccxt/pro/bitfinex2.py +0 -1083
- ccxt/pro/bitpanda.py +0 -15
- ccxt/pro/currencycom.py +0 -536
- ccxt/pro/idex.py +0 -672
- ccxt/pro/poloniexfutures.py +0 -990
- ccxt/pro/wazirx.py +0 -749
- ccxt/test/base/__init__.py +0 -29
- ccxt/test/base/test_account.py +0 -26
- ccxt/test/base/test_balance.py +0 -56
- ccxt/test/base/test_borrow_interest.py +0 -35
- ccxt/test/base/test_borrow_rate.py +0 -32
- ccxt/test/base/test_calculate_fee.py +0 -51
- ccxt/test/base/test_crypto.py +0 -127
- ccxt/test/base/test_currency.py +0 -76
- ccxt/test/base/test_datetime.py +0 -109
- ccxt/test/base/test_decimal_to_precision.py +0 -392
- ccxt/test/base/test_deep_extend.py +0 -68
- ccxt/test/base/test_deposit_withdrawal.py +0 -50
- ccxt/test/base/test_exchange_datetime_functions.py +0 -76
- ccxt/test/base/test_funding_rate_history.py +0 -29
- ccxt/test/base/test_last_price.py +0 -31
- ccxt/test/base/test_ledger_entry.py +0 -45
- ccxt/test/base/test_ledger_item.py +0 -48
- ccxt/test/base/test_leverage_tier.py +0 -33
- ccxt/test/base/test_liquidation.py +0 -50
- ccxt/test/base/test_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -193
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -33
- ccxt/test/base/test_open_interest.py +0 -32
- ccxt/test/base/test_order.py +0 -64
- ccxt/test/base/test_order_book.py +0 -69
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -353
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -92
- ccxt/test/base/test_trade.py +0 -47
- ccxt/test/base/test_trading_fee.py +0 -26
- ccxt/test/base/test_transaction.py +0 -39
- ccxt/test/test_async.py +0 -1649
- ccxt/test/test_sync.py +0 -1648
- ccxt/wazirx.py +0 -1224
- ccxt_ir-4.3.46.0.3.dist-info/RECORD +0 -773
- /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info/licenses}/LICENSE.txt +0 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/top_level.txt +0 -0
ccxt/async_support/coinbase.py
CHANGED
|
@@ -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,
|
|
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':
|
|
35
|
+
'certified': False,
|
|
35
36
|
# rate-limits:
|
|
36
|
-
# ADVANCED API: https://docs.cloud.coinbase.com/advanced-trade
|
|
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
|
|
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.
|
|
282
|
-
'maker': self.parse_number('0.
|
|
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':
|
|
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
|
-
|
|
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
|
-
|
|
425
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
851
|
+
@ignore
|
|
713
852
|
fetch sells
|
|
714
|
-
|
|
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
|
-
|
|
871
|
+
@ignore
|
|
731
872
|
fetch buys
|
|
732
|
-
|
|
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
|
-
|
|
756
|
-
|
|
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
|
-
|
|
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
|
-
|
|
769
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
921
|
-
|
|
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':
|
|
929
|
-
'address':
|
|
930
|
-
'addressTo':
|
|
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':
|
|
936
|
-
'amount': self.
|
|
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
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
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,
|
|
1255
|
-
perpetualFees = self.safe_dict(contractPromises,
|
|
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
|
-
|
|
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':
|
|
1350
|
-
'maker':
|
|
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
|
-
|
|
1626
|
-
|
|
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
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
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
|
-
#
|
|
1645
|
-
#
|
|
1646
|
-
#
|
|
1647
|
-
#
|
|
1648
|
-
#
|
|
1649
|
-
#
|
|
1650
|
-
#
|
|
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
|
-
#
|
|
1657
|
-
#
|
|
1658
|
-
#
|
|
1659
|
-
#
|
|
1660
|
-
#
|
|
1661
|
-
#
|
|
1662
|
-
#
|
|
1663
|
-
#
|
|
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
|
-
|
|
1681
|
-
|
|
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':
|
|
1685
|
-
'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
|
-
|
|
1714
|
-
|
|
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
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
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
|
-
#
|
|
1937
|
-
#
|
|
1938
|
-
#
|
|
1939
|
-
#
|
|
1940
|
-
#
|
|
1941
|
-
#
|
|
1942
|
-
#
|
|
1943
|
-
#
|
|
1944
|
-
#
|
|
1945
|
-
#
|
|
1946
|
-
#
|
|
1947
|
-
#
|
|
1948
|
-
#
|
|
1949
|
-
#
|
|
1950
|
-
#
|
|
1951
|
-
#
|
|
1952
|
-
#
|
|
1953
|
-
#
|
|
1954
|
-
#
|
|
1955
|
-
#
|
|
1956
|
-
#
|
|
1957
|
-
#
|
|
1958
|
-
#
|
|
1959
|
-
#
|
|
1960
|
-
#
|
|
1961
|
-
#
|
|
1962
|
-
#
|
|
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
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
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':
|
|
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':
|
|
2019
|
-
'quoteVolume':
|
|
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
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
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
|
|
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'] =
|
|
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-
|
|
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
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
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
|
|
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 [
|
|
2179
|
-
:returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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':
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3817
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4078
|
-
|
|
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
|
-
|
|
4110
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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):
|