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