ccxt-ir 4.3.46.0.3__py2.py3-none-any.whl → 4.5.0__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 +7 -7
- 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 +9 -9
- 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 +31 -37
- 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 +25 -24
- 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 +30 -27
- ccxt/async_support/sarmayex.py +9 -9
- ccxt/async_support/sarrafex.py +13 -13
- ccxt/async_support/tabdeal.py +14 -13
- 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 +29 -35
- 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 +22 -21
- 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 +28 -25
- 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 +12 -11
- 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.0.dist-info}/METADATA +225 -73
- ccxt_ir-4.5.0.dist-info/RECORD +743 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.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.0.dist-info/licenses}/LICENSE.txt +0 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info}/top_level.txt +0 -0
ccxt/kraken.py
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.kraken import ImplicitAPI
|
|
8
8
|
import hashlib
|
|
9
|
-
from ccxt.base.types import Balances, Currencies, Currency, IndexType, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
|
|
9
|
+
from ccxt.base.types import Any, Balances, Currencies, Currency, DepositAddress, IndexType, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
|
|
10
10
|
from typing import List
|
|
11
11
|
from ccxt.base.errors import ExchangeError
|
|
12
12
|
from ccxt.base.errors import AuthenticationError
|
|
@@ -19,13 +19,13 @@ from ccxt.base.errors import InsufficientFunds
|
|
|
19
19
|
from ccxt.base.errors import InvalidAddress
|
|
20
20
|
from ccxt.base.errors import InvalidOrder
|
|
21
21
|
from ccxt.base.errors import OrderNotFound
|
|
22
|
-
from ccxt.base.errors import CancelPending
|
|
23
22
|
from ccxt.base.errors import NotSupported
|
|
24
23
|
from ccxt.base.errors import DDoSProtection
|
|
25
24
|
from ccxt.base.errors import RateLimitExceeded
|
|
26
25
|
from ccxt.base.errors import ExchangeNotAvailable
|
|
27
26
|
from ccxt.base.errors import OnMaintenance
|
|
28
27
|
from ccxt.base.errors import InvalidNonce
|
|
28
|
+
from ccxt.base.errors import CancelPending
|
|
29
29
|
from ccxt.base.decimal_to_precision import TRUNCATE
|
|
30
30
|
from ccxt.base.decimal_to_precision import TICK_SIZE
|
|
31
31
|
from ccxt.base.precise import Precise
|
|
@@ -33,7 +33,7 @@ from ccxt.base.precise import Precise
|
|
|
33
33
|
|
|
34
34
|
class kraken(Exchange, ImplicitAPI):
|
|
35
35
|
|
|
36
|
-
def describe(self):
|
|
36
|
+
def describe(self) -> Any:
|
|
37
37
|
return self.deep_extend(super(kraken, self).describe(), {
|
|
38
38
|
'id': 'kraken',
|
|
39
39
|
'name': 'Kraken',
|
|
@@ -66,6 +66,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
66
66
|
'createStopMarketOrder': True,
|
|
67
67
|
'createStopOrder': True,
|
|
68
68
|
'createTrailingAmountOrder': True,
|
|
69
|
+
'createTrailingPercentOrder': True,
|
|
69
70
|
'editOrder': True,
|
|
70
71
|
'fetchBalance': True,
|
|
71
72
|
'fetchBorrowInterest': False,
|
|
@@ -76,6 +77,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
76
77
|
'fetchCrossBorrowRates': False,
|
|
77
78
|
'fetchCurrencies': True,
|
|
78
79
|
'fetchDepositAddress': True,
|
|
80
|
+
'fetchDepositAddresses': False,
|
|
81
|
+
'fetchDepositAddressesByNetwork': False,
|
|
79
82
|
'fetchDeposits': True,
|
|
80
83
|
'fetchFundingHistory': False,
|
|
81
84
|
'fetchFundingRate': False,
|
|
@@ -98,6 +101,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
98
101
|
'fetchOrderTrades': 'emulated',
|
|
99
102
|
'fetchPositions': True,
|
|
100
103
|
'fetchPremiumIndexOHLCV': False,
|
|
104
|
+
'fetchStatus': True,
|
|
101
105
|
'fetchTicker': True,
|
|
102
106
|
'fetchTickers': True,
|
|
103
107
|
'fetchTime': True,
|
|
@@ -193,6 +197,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
193
197
|
'AddOrder': 0,
|
|
194
198
|
'AddOrderBatch': 0,
|
|
195
199
|
'AddExport': 3,
|
|
200
|
+
'AmendOrder': 0,
|
|
196
201
|
'Balance': 3,
|
|
197
202
|
'CancelAll': 3,
|
|
198
203
|
'CancelAllOrdersAfter': 3,
|
|
@@ -238,16 +243,18 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
238
243
|
},
|
|
239
244
|
},
|
|
240
245
|
'commonCurrencies': {
|
|
246
|
+
# about X & Z prefixes and .S & .M suffixes, see comment under fetchCurrencies
|
|
241
247
|
'LUNA': 'LUNC',
|
|
242
248
|
'LUNA2': 'LUNA',
|
|
243
249
|
'REPV2': 'REP',
|
|
244
250
|
'REP': 'REPV1',
|
|
245
251
|
'UST': 'USTC',
|
|
246
252
|
'XBT': 'BTC',
|
|
247
|
-
'XBT.M': 'BTC.M', # https://support.kraken.com/hc/en-us/articles/360039879471-What-is-Asset-S-and-Asset-M-
|
|
248
253
|
'XDG': 'DOGE',
|
|
249
254
|
},
|
|
250
255
|
'options': {
|
|
256
|
+
'timeDifference': 0, # the difference between system clock and Binance clock
|
|
257
|
+
'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
|
|
251
258
|
'marketsByAltname': {},
|
|
252
259
|
'delistedMarketsById': {},
|
|
253
260
|
# cannot withdraw/deposit these
|
|
@@ -257,100 +264,100 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
257
264
|
'TRX': 'TRC20',
|
|
258
265
|
},
|
|
259
266
|
'depositMethods': {
|
|
260
|
-
'1INCH': '1inch(1INCH)',
|
|
267
|
+
'1INCH': '1inch' + ' ' + '(1INCH)',
|
|
261
268
|
'AAVE': 'Aave',
|
|
262
269
|
'ADA': 'ADA',
|
|
263
270
|
'ALGO': 'Algorand',
|
|
264
|
-
'ANKR': 'ANKR(ANKR)',
|
|
265
|
-
'ANT': 'Aragon(ANT)',
|
|
271
|
+
'ANKR': 'ANKR' + ' ' + '(ANKR)',
|
|
272
|
+
'ANT': 'Aragon' + ' ' + '(ANT)',
|
|
266
273
|
'ATOM': 'Cosmos',
|
|
267
|
-
'AXS': 'Axie Infinity Shards(AXS)',
|
|
268
|
-
'BADGER': 'Bager DAO(BADGER)',
|
|
269
|
-
'BAL': 'Balancer(BAL)',
|
|
270
|
-
'BAND': 'Band Protocol(BAND)',
|
|
274
|
+
'AXS': 'Axie Infinity Shards' + ' ' + '(AXS)',
|
|
275
|
+
'BADGER': 'Bager DAO' + ' ' + '(BADGER)',
|
|
276
|
+
'BAL': 'Balancer' + ' ' + '(BAL)',
|
|
277
|
+
'BAND': 'Band Protocol' + ' ' + '(BAND)',
|
|
271
278
|
'BAT': 'BAT',
|
|
272
279
|
'BCH': 'Bitcoin Cash',
|
|
273
|
-
'BNC': 'Bifrost(BNC)',
|
|
274
|
-
'BNT': 'Bancor(BNT)',
|
|
280
|
+
'BNC': 'Bifrost' + ' ' + '(BNC)',
|
|
281
|
+
'BNT': 'Bancor' + ' ' + '(BNT)',
|
|
275
282
|
'BTC': 'Bitcoin',
|
|
276
|
-
'CHZ': 'Chiliz(CHZ)',
|
|
277
|
-
'COMP': 'Compound(COMP)',
|
|
278
|
-
'CQT': '\tCovalent Query Token(CQT)',
|
|
279
|
-
'CRV': 'Curve DAO Token(CRV)',
|
|
280
|
-
'CTSI': 'Cartesi(CTSI)',
|
|
283
|
+
'CHZ': 'Chiliz' + ' ' + '(CHZ)',
|
|
284
|
+
'COMP': 'Compound' + ' ' + '(COMP)',
|
|
285
|
+
'CQT': '\tCovalent Query Token' + ' ' + '(CQT)',
|
|
286
|
+
'CRV': 'Curve DAO Token' + ' ' + '(CRV)',
|
|
287
|
+
'CTSI': 'Cartesi' + ' ' + '(CTSI)',
|
|
281
288
|
'DAI': 'Dai',
|
|
282
289
|
'DASH': 'Dash',
|
|
283
290
|
'DOGE': 'Dogecoin',
|
|
284
291
|
'DOT': 'Polkadot',
|
|
285
|
-
'DYDX': 'dYdX(DYDX)',
|
|
286
|
-
'ENJ': 'Enjin Coin(ENJ)',
|
|
292
|
+
'DYDX': 'dYdX' + ' ' + '(DYDX)',
|
|
293
|
+
'ENJ': 'Enjin Coin' + ' ' + '(ENJ)',
|
|
287
294
|
'EOS': 'EOS',
|
|
288
|
-
'ETC': 'Ether Classic(Hex)',
|
|
289
|
-
'ETH': 'Ether(Hex)',
|
|
295
|
+
'ETC': 'Ether Classic' + ' ' + '(Hex)',
|
|
296
|
+
'ETH': 'Ether' + ' ' + '(Hex)',
|
|
290
297
|
'EWT': 'Energy Web Token',
|
|
291
298
|
'FEE': 'Kraken Fee Credit',
|
|
292
299
|
'FIL': 'Filecoin',
|
|
293
300
|
'FLOW': 'Flow',
|
|
294
|
-
'GHST': 'Aavegotchi(GHST)',
|
|
301
|
+
'GHST': 'Aavegotchi' + ' ' + '(GHST)',
|
|
295
302
|
'GNO': 'GNO',
|
|
296
303
|
'GRT': 'GRT',
|
|
297
304
|
'ICX': 'Icon',
|
|
298
|
-
'INJ': 'Injective Protocol(INJ)',
|
|
299
|
-
'KAR': 'Karura(KAR)',
|
|
305
|
+
'INJ': 'Injective Protocol' + ' ' + '(INJ)',
|
|
306
|
+
'KAR': 'Karura' + ' ' + '(KAR)',
|
|
300
307
|
'KAVA': 'Kava',
|
|
301
|
-
'KEEP': 'Keep Token(KEEP)',
|
|
302
|
-
'KNC': 'Kyber Network(KNC)',
|
|
308
|
+
'KEEP': 'Keep Token' + ' ' + '(KEEP)',
|
|
309
|
+
'KNC': 'Kyber Network' + ' ' + '(KNC)',
|
|
303
310
|
'KSM': 'Kusama',
|
|
304
311
|
'LINK': 'Link',
|
|
305
|
-
'LPT': 'Livepeer Token(LPT)',
|
|
306
|
-
'LRC': 'Loopring(LRC)',
|
|
312
|
+
'LPT': 'Livepeer Token' + ' ' + '(LPT)',
|
|
313
|
+
'LRC': 'Loopring' + ' ' + '(LRC)',
|
|
307
314
|
'LSK': 'Lisk',
|
|
308
315
|
'LTC': 'Litecoin',
|
|
309
316
|
'MANA': 'MANA',
|
|
310
|
-
'MATIC': 'Polygon(MATIC)',
|
|
317
|
+
'MATIC': 'Polygon' + ' ' + '(MATIC)',
|
|
311
318
|
'MINA': 'Mina', # inspected from webui
|
|
312
|
-
'MIR': 'Mirror Protocol(MIR)',
|
|
313
|
-
'MKR': 'Maker(MKR)',
|
|
319
|
+
'MIR': 'Mirror Protocol' + ' ' + '(MIR)',
|
|
320
|
+
'MKR': 'Maker' + ' ' + '(MKR)',
|
|
314
321
|
'MLN': 'MLN',
|
|
315
|
-
'MOVR': 'Moonriver(MOVR)',
|
|
322
|
+
'MOVR': 'Moonriver' + ' ' + '(MOVR)',
|
|
316
323
|
'NANO': 'NANO',
|
|
317
324
|
'OCEAN': 'OCEAN',
|
|
318
|
-
'OGN': 'Origin Protocol(OGN)',
|
|
325
|
+
'OGN': 'Origin Protocol' + ' ' + '(OGN)',
|
|
319
326
|
'OMG': 'OMG',
|
|
320
|
-
'OXT': 'Orchid(OXT)',
|
|
321
|
-
'OXY': 'Oxygen(OXY)',
|
|
322
|
-
'PAXG': 'PAX(Gold)',
|
|
323
|
-
'PERP': 'Perpetual Protocol(PERP)',
|
|
324
|
-
'PHA': 'Phala(PHA)',
|
|
327
|
+
'OXT': 'Orchid' + ' ' + '(OXT)',
|
|
328
|
+
'OXY': 'Oxygen' + ' ' + '(OXY)',
|
|
329
|
+
'PAXG': 'PAX' + ' ' + '(Gold)',
|
|
330
|
+
'PERP': 'Perpetual Protocol' + ' ' + '(PERP)',
|
|
331
|
+
'PHA': 'Phala' + ' ' + '(PHA)',
|
|
325
332
|
'QTUM': 'QTUM',
|
|
326
|
-
'RARI': 'Rarible(RARI)',
|
|
327
|
-
'RAY': 'Raydium(RAY)',
|
|
328
|
-
'REN': 'Ren Protocol(REN)',
|
|
333
|
+
'RARI': 'Rarible' + ' ' + '(RARI)',
|
|
334
|
+
'RAY': 'Raydium' + ' ' + '(RAY)',
|
|
335
|
+
'REN': 'Ren Protocol' + ' ' + '(REN)',
|
|
329
336
|
'REP': 'REPv2',
|
|
330
337
|
'REPV1': 'REP',
|
|
331
|
-
'SAND': 'The Sandbox(SAND)',
|
|
338
|
+
'SAND': 'The Sandbox' + ' ' + '(SAND)',
|
|
332
339
|
'SC': 'Siacoin',
|
|
333
|
-
'SDN': 'Shiden(SDN)',
|
|
340
|
+
'SDN': 'Shiden' + ' ' + '(SDN)',
|
|
334
341
|
'SOL': 'Solana', # their deposit method api doesn't work for SOL - was guessed
|
|
335
|
-
'SNX': 'Synthetix Network(SNX)',
|
|
342
|
+
'SNX': 'Synthetix Network' + ' ' + '(SNX)',
|
|
336
343
|
'SRM': 'Serum', # inspected from webui
|
|
337
|
-
'STORJ': 'Storj(STORJ)',
|
|
338
|
-
'SUSHI': 'Sushiswap(SUSHI)',
|
|
344
|
+
'STORJ': 'Storj' + ' ' + '(STORJ)',
|
|
345
|
+
'SUSHI': 'Sushiswap' + ' ' + '(SUSHI)',
|
|
339
346
|
'TBTC': 'tBTC',
|
|
340
347
|
'TRX': 'Tron',
|
|
341
348
|
'UNI': 'UNI',
|
|
342
349
|
'USDC': 'USDC',
|
|
343
|
-
'USDT': 'Tether USD(ERC20)',
|
|
344
|
-
'USDT-TRC20': 'Tether USD(TRC20)',
|
|
350
|
+
'USDT': 'Tether USD' + ' ' + '(ERC20)',
|
|
351
|
+
'USDT-TRC20': 'Tether USD' + ' ' + '(TRC20)',
|
|
345
352
|
'WAVES': 'Waves',
|
|
346
|
-
'WBTC': 'Wrapped Bitcoin(WBTC)',
|
|
353
|
+
'WBTC': 'Wrapped Bitcoin' + ' ' + '(WBTC)',
|
|
347
354
|
'XLM': 'Stellar XLM',
|
|
348
355
|
'XMR': 'Monero',
|
|
349
356
|
'XRP': 'Ripple XRP',
|
|
350
357
|
'XTZ': 'XTZ',
|
|
351
358
|
'YFI': 'YFI',
|
|
352
|
-
'ZEC': 'Zcash(Transparent)',
|
|
353
|
-
'ZRX': '0x(ZRX)',
|
|
359
|
+
'ZEC': 'Zcash' + ' ' + '(Transparent)',
|
|
360
|
+
'ZRX': '0x' + ' ' + '(ZRX)',
|
|
354
361
|
},
|
|
355
362
|
'withdrawMethods': { # keeping it here because deposit and withdraw return different networks codes
|
|
356
363
|
'Lightning': 'Lightning',
|
|
@@ -438,31 +445,115 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
438
445
|
'Celestia': 'TIA',
|
|
439
446
|
},
|
|
440
447
|
},
|
|
448
|
+
'features': {
|
|
449
|
+
'spot': {
|
|
450
|
+
'sandbox': False,
|
|
451
|
+
'createOrder': {
|
|
452
|
+
'marginMode': False,
|
|
453
|
+
'triggerPrice': False, # todo
|
|
454
|
+
'triggerPriceType': None,
|
|
455
|
+
'triggerDirection': False,
|
|
456
|
+
'stopLossPrice': True,
|
|
457
|
+
'takeProfitPrice': True,
|
|
458
|
+
'attachedStopLossTakeProfit': None,
|
|
459
|
+
'timeInForce': {
|
|
460
|
+
'IOC': True,
|
|
461
|
+
'FOK': True,
|
|
462
|
+
'PO': True,
|
|
463
|
+
'GTD': False,
|
|
464
|
+
},
|
|
465
|
+
'hedged': False,
|
|
466
|
+
'trailing': True,
|
|
467
|
+
'leverage': False,
|
|
468
|
+
'marketBuyByCost': True,
|
|
469
|
+
'marketBuyRequiresPrice': False,
|
|
470
|
+
'selfTradePrevention': True, # todo implement
|
|
471
|
+
'iceberg': True, # todo implement
|
|
472
|
+
},
|
|
473
|
+
'createOrders': None,
|
|
474
|
+
'fetchMyTrades': {
|
|
475
|
+
'marginMode': False,
|
|
476
|
+
'limit': None,
|
|
477
|
+
'daysBack': None,
|
|
478
|
+
'untilDays': None,
|
|
479
|
+
'symbolRequired': False,
|
|
480
|
+
},
|
|
481
|
+
'fetchOrder': {
|
|
482
|
+
'marginMode': False,
|
|
483
|
+
'trigger': False,
|
|
484
|
+
'trailing': False,
|
|
485
|
+
'symbolRequired': False,
|
|
486
|
+
},
|
|
487
|
+
'fetchOpenOrders': {
|
|
488
|
+
'marginMode': False,
|
|
489
|
+
'limit': None,
|
|
490
|
+
'trigger': False,
|
|
491
|
+
'trailing': False,
|
|
492
|
+
'symbolRequired': False,
|
|
493
|
+
},
|
|
494
|
+
'fetchOrders': None,
|
|
495
|
+
'fetchClosedOrders': {
|
|
496
|
+
'marginMode': False,
|
|
497
|
+
'limit': None,
|
|
498
|
+
'daysBack': None,
|
|
499
|
+
'daysBackCanceled': None,
|
|
500
|
+
'untilDays': 100000,
|
|
501
|
+
'trigger': False,
|
|
502
|
+
'trailing': False,
|
|
503
|
+
'symbolRequired': False,
|
|
504
|
+
},
|
|
505
|
+
'fetchOHLCV': {
|
|
506
|
+
'limit': 720,
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
'swap': {
|
|
510
|
+
'linear': None,
|
|
511
|
+
'inverse': None,
|
|
512
|
+
},
|
|
513
|
+
'future': {
|
|
514
|
+
'linear': None,
|
|
515
|
+
'inverse': None,
|
|
516
|
+
},
|
|
517
|
+
},
|
|
441
518
|
'precisionMode': TICK_SIZE,
|
|
442
519
|
'exceptions': {
|
|
443
|
-
'
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
520
|
+
'exact': {
|
|
521
|
+
'EQuery:Invalid asset pair': BadSymbol, # {"error":["EQuery:Invalid asset pair"]}
|
|
522
|
+
'EAPI:Invalid key': AuthenticationError,
|
|
523
|
+
'EFunding:Unknown withdraw key': InvalidAddress, # {"error":["EFunding:Unknown withdraw key"]}
|
|
524
|
+
'EFunding:Invalid amount': InsufficientFunds,
|
|
525
|
+
'EService:Unavailable': ExchangeNotAvailable,
|
|
526
|
+
'EDatabase:Internal error': ExchangeNotAvailable,
|
|
527
|
+
'EService:Busy': ExchangeNotAvailable,
|
|
528
|
+
'EQuery:Unknown asset': BadSymbol, # {"error":["EQuery:Unknown asset"]}
|
|
529
|
+
'EAPI:Rate limit exceeded': DDoSProtection,
|
|
530
|
+
'EOrder:Rate limit exceeded': DDoSProtection,
|
|
531
|
+
'EGeneral:Internal error': ExchangeNotAvailable,
|
|
532
|
+
'EGeneral:Temporary lockout': DDoSProtection,
|
|
533
|
+
'EGeneral:Permission denied': PermissionDenied,
|
|
534
|
+
'EGeneral:Invalid arguments:price': InvalidOrder,
|
|
535
|
+
'EOrder:Unknown order': InvalidOrder,
|
|
536
|
+
'EOrder:Invalid price:Invalid price argument': InvalidOrder,
|
|
537
|
+
'EOrder:Order minimum not met': InvalidOrder,
|
|
538
|
+
'EOrder:Insufficient funds': InsufficientFunds,
|
|
539
|
+
'EGeneral:Invalid arguments': BadRequest,
|
|
540
|
+
'ESession:Invalid session': AuthenticationError,
|
|
541
|
+
'EAPI:Invalid nonce': InvalidNonce,
|
|
542
|
+
'EFunding:No funding method': BadRequest, # {"error":"EFunding:No funding method"}
|
|
543
|
+
'EFunding:Unknown asset': BadSymbol, # {"error":["EFunding:Unknown asset"]}
|
|
544
|
+
'EService:Market in post_only mode': OnMaintenance, # {"error":["EService:Market in post_only mode"]}
|
|
545
|
+
'EGeneral:Too many requests': DDoSProtection, # {"error":["EGeneral:Too many requests"]}
|
|
546
|
+
'ETrade:User Locked': AccountSuspended, # {"error":["ETrade:User Locked"]}
|
|
547
|
+
},
|
|
548
|
+
'broad': {
|
|
549
|
+
':Invalid order': InvalidOrder,
|
|
550
|
+
':Invalid arguments:volume': InvalidOrder,
|
|
551
|
+
':Invalid arguments:viqc': InvalidOrder,
|
|
552
|
+
':Invalid nonce': InvalidNonce,
|
|
553
|
+
':IInsufficient funds': InsufficientFunds,
|
|
554
|
+
':Cancel pending': CancelPending,
|
|
555
|
+
':Rate limit exceeded': RateLimitExceeded,
|
|
556
|
+
},
|
|
466
557
|
},
|
|
467
558
|
})
|
|
468
559
|
|
|
@@ -472,11 +563,18 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
472
563
|
def fetch_markets(self, params={}) -> List[Market]:
|
|
473
564
|
"""
|
|
474
565
|
retrieves data on all markets for kraken
|
|
475
|
-
|
|
566
|
+
|
|
567
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTradableAssetPairs
|
|
568
|
+
|
|
476
569
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
477
570
|
:returns dict[]: an array of objects representing market data
|
|
478
571
|
"""
|
|
479
|
-
|
|
572
|
+
promises = []
|
|
573
|
+
promises.append(self.publicGetAssetPairs(params))
|
|
574
|
+
if self.options['adjustForTimeDifference']:
|
|
575
|
+
promises.append(self.load_time_difference())
|
|
576
|
+
responses = promises
|
|
577
|
+
assetsResponse = responses[0]
|
|
480
578
|
#
|
|
481
579
|
# {
|
|
482
580
|
# "error": [],
|
|
@@ -524,7 +622,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
524
622
|
# }
|
|
525
623
|
# }
|
|
526
624
|
#
|
|
527
|
-
markets = self.
|
|
625
|
+
markets = self.safe_dict(assetsResponse, 'result', {})
|
|
626
|
+
cachedCurrencies = self.safe_dict(self.options, 'cachedCurrencies', {})
|
|
528
627
|
keys = list(markets.keys())
|
|
529
628
|
result = []
|
|
530
629
|
for i in range(0, len(keys)):
|
|
@@ -534,39 +633,45 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
534
633
|
quoteId = self.safe_string(market, 'quote')
|
|
535
634
|
base = self.safe_currency_code(baseId)
|
|
536
635
|
quote = self.safe_currency_code(quoteId)
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
makerFees = self.safe_value(market, 'fees_maker', [])
|
|
540
|
-
firstMakerFee = self.safe_value(makerFees, 0, [])
|
|
636
|
+
makerFees = self.safe_list(market, 'fees_maker', [])
|
|
637
|
+
firstMakerFee = self.safe_list(makerFees, 0, [])
|
|
541
638
|
firstMakerFeeRate = self.safe_string(firstMakerFee, 1)
|
|
542
639
|
maker = None
|
|
543
640
|
if firstMakerFeeRate is not None:
|
|
544
641
|
maker = self.parse_number(Precise.string_div(firstMakerFeeRate, '100'))
|
|
545
|
-
takerFees = self.
|
|
546
|
-
firstTakerFee = self.
|
|
642
|
+
takerFees = self.safe_list(market, 'fees', [])
|
|
643
|
+
firstTakerFee = self.safe_list(takerFees, 0, [])
|
|
547
644
|
firstTakerFeeRate = self.safe_string(firstTakerFee, 1)
|
|
548
645
|
taker = None
|
|
549
646
|
if firstTakerFeeRate is not None:
|
|
550
647
|
taker = self.parse_number(Precise.string_div(firstTakerFeeRate, '100'))
|
|
551
|
-
leverageBuy = self.
|
|
648
|
+
leverageBuy = self.safe_list(market, 'leverage_buy', [])
|
|
552
649
|
leverageBuyLength = len(leverageBuy)
|
|
553
650
|
precisionPrice = self.parse_number(self.parse_precision(self.safe_string(market, 'pair_decimals')))
|
|
651
|
+
precisionAmount = self.parse_number(self.parse_precision(self.safe_string(market, 'lot_decimals')))
|
|
652
|
+
spot = True
|
|
653
|
+
# fix https://github.com/freqtrade/freqtrade/issues/11765#issuecomment-2894224103
|
|
654
|
+
if spot and (base in cachedCurrencies):
|
|
655
|
+
currency = cachedCurrencies[base]
|
|
656
|
+
currencyPrecision = self.safe_number(currency, 'precision')
|
|
657
|
+
# if currency precision is greater(e.g. 0.01) than market precision(e.g. 0.001)
|
|
658
|
+
if currencyPrecision > precisionAmount:
|
|
659
|
+
precisionAmount = currencyPrecision
|
|
554
660
|
status = self.safe_string(market, 'status')
|
|
555
661
|
isActive = status == 'online'
|
|
556
662
|
result.append({
|
|
557
663
|
'id': id,
|
|
558
664
|
'wsId': self.safe_string(market, 'wsname'),
|
|
559
|
-
'symbol':
|
|
665
|
+
'symbol': base + '/' + quote,
|
|
560
666
|
'base': base,
|
|
561
667
|
'quote': quote,
|
|
562
668
|
'settle': None,
|
|
563
669
|
'baseId': baseId,
|
|
564
670
|
'quoteId': quoteId,
|
|
565
671
|
'settleId': None,
|
|
566
|
-
'darkpool': darkpool,
|
|
567
672
|
'altname': market['altname'],
|
|
568
673
|
'type': 'spot',
|
|
569
|
-
'spot':
|
|
674
|
+
'spot': spot,
|
|
570
675
|
'margin': (leverageBuyLength > 0),
|
|
571
676
|
'swap': False,
|
|
572
677
|
'future': False,
|
|
@@ -583,7 +688,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
583
688
|
'strike': None,
|
|
584
689
|
'optionType': None,
|
|
585
690
|
'precision': {
|
|
586
|
-
'amount':
|
|
691
|
+
'amount': precisionAmount,
|
|
587
692
|
'price': precisionPrice,
|
|
588
693
|
},
|
|
589
694
|
'limits': {
|
|
@@ -596,7 +701,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
596
701
|
'max': None,
|
|
597
702
|
},
|
|
598
703
|
'price': {
|
|
599
|
-
'min':
|
|
704
|
+
'min': None,
|
|
600
705
|
'max': None,
|
|
601
706
|
},
|
|
602
707
|
'cost': {
|
|
@@ -607,7 +712,6 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
607
712
|
'created': None,
|
|
608
713
|
'info': market,
|
|
609
714
|
})
|
|
610
|
-
result = self.append_inactive_markets(result)
|
|
611
715
|
self.options['marketsByAltname'] = self.index_by(result, 'altname')
|
|
612
716
|
return result
|
|
613
717
|
|
|
@@ -615,40 +719,42 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
615
719
|
if currencyId is not None:
|
|
616
720
|
if len(currencyId) > 3:
|
|
617
721
|
if (currencyId.find('X') == 0) or (currencyId.find('Z') == 0):
|
|
618
|
-
if not (currencyId.find('.') > 0):
|
|
722
|
+
if not (currencyId.find('.') > 0) and (currencyId != 'ZEUS'):
|
|
619
723
|
currencyId = currencyId[1:]
|
|
620
724
|
return super(kraken, self).safe_currency(currencyId, currency)
|
|
621
725
|
|
|
622
|
-
def
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
726
|
+
def fetch_status(self, params={}):
|
|
727
|
+
"""
|
|
728
|
+
the latest known information on the availability of the exchange API
|
|
729
|
+
|
|
730
|
+
https://docs.kraken.com/api/docs/rest-api/get-system-status/
|
|
731
|
+
|
|
732
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
733
|
+
:returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
|
|
734
|
+
"""
|
|
735
|
+
response = self.publicGetSystemStatus(params)
|
|
736
|
+
#
|
|
737
|
+
# {
|
|
738
|
+
# error: [],
|
|
739
|
+
# result: {status: 'online', timestamp: '2024-07-22T16:34:44Z'}
|
|
740
|
+
# }
|
|
741
|
+
#
|
|
742
|
+
result = self.safe_dict(response, 'result')
|
|
743
|
+
statusRaw = self.safe_string(result, 'status')
|
|
744
|
+
return {
|
|
745
|
+
'status': 'ok' if (statusRaw == 'online') else 'maintenance',
|
|
746
|
+
'updated': None,
|
|
747
|
+
'eta': None,
|
|
748
|
+
'url': None,
|
|
749
|
+
'info': response,
|
|
640
750
|
}
|
|
641
|
-
markets = [
|
|
642
|
-
# {'id': 'XXLMZEUR', 'symbol': 'XLM/EUR', 'base': 'XLM', 'quote': 'EUR', 'altname': 'XLMEUR'},
|
|
643
|
-
]
|
|
644
|
-
for i in range(0, len(markets)):
|
|
645
|
-
result.append(self.extend(defaults, markets[i]))
|
|
646
|
-
return result
|
|
647
751
|
|
|
648
752
|
def fetch_currencies(self, params={}) -> Currencies:
|
|
649
753
|
"""
|
|
650
754
|
fetches all available currencies on an exchange
|
|
651
|
-
|
|
755
|
+
|
|
756
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getAssetInfo
|
|
757
|
+
|
|
652
758
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
653
759
|
:returns dict: an associative dictionary of currencies
|
|
654
760
|
"""
|
|
@@ -657,9 +763,48 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
657
763
|
# {
|
|
658
764
|
# "error": [],
|
|
659
765
|
# "result": {
|
|
660
|
-
# "
|
|
766
|
+
# "ATOM": {
|
|
767
|
+
# "aclass": "currency",
|
|
768
|
+
# "altname": "ATOM",
|
|
769
|
+
# "collateral_value": "0.7",
|
|
770
|
+
# "decimals": 8,
|
|
771
|
+
# "display_decimals": 6,
|
|
772
|
+
# "margin_rate": 0.02,
|
|
773
|
+
# "status": "enabled",
|
|
774
|
+
# },
|
|
775
|
+
# "ATOM.S": {
|
|
661
776
|
# "aclass": "currency",
|
|
662
|
-
# "altname": "
|
|
777
|
+
# "altname": "ATOM.S",
|
|
778
|
+
# "decimals": 8,
|
|
779
|
+
# "display_decimals": 6,
|
|
780
|
+
# "status": "enabled",
|
|
781
|
+
# },
|
|
782
|
+
# "XXBT": {
|
|
783
|
+
# "aclass": "currency",
|
|
784
|
+
# "altname": "XBT",
|
|
785
|
+
# "decimals": 10,
|
|
786
|
+
# "display_decimals": 5,
|
|
787
|
+
# "margin_rate": 0.01,
|
|
788
|
+
# "status": "enabled",
|
|
789
|
+
# },
|
|
790
|
+
# "XETH": {
|
|
791
|
+
# "aclass": "currency",
|
|
792
|
+
# "altname": "ETH",
|
|
793
|
+
# "decimals": 10,
|
|
794
|
+
# "display_decimals": 5
|
|
795
|
+
# "margin_rate": 0.02,
|
|
796
|
+
# "status": "enabled",
|
|
797
|
+
# },
|
|
798
|
+
# "XBT.M": {
|
|
799
|
+
# "aclass": "currency",
|
|
800
|
+
# "altname": "XBT.M",
|
|
801
|
+
# "decimals": 10,
|
|
802
|
+
# "display_decimals": 5
|
|
803
|
+
# "status": "enabled",
|
|
804
|
+
# },
|
|
805
|
+
# "ETH.M": {
|
|
806
|
+
# "aclass": "currency",
|
|
807
|
+
# "altname": "ETH.M",
|
|
663
808
|
# "decimals": 10,
|
|
664
809
|
# "display_decimals": 5
|
|
665
810
|
# "status": "enabled",
|
|
@@ -678,23 +823,42 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
678
823
|
# see: https://support.kraken.com/hc/en-us/articles/201893608-What-are-the-withdrawal-fees-
|
|
679
824
|
# to add support for multiple withdrawal/deposit methods and
|
|
680
825
|
# differentiated fees for each particular method
|
|
826
|
+
#
|
|
827
|
+
# Notes about abbreviations:
|
|
828
|
+
# Z and X prefixes: https://support.kraken.com/hc/en-us/articles/360001206766-Bitcoin-currency-code-XBT-vs-BTC
|
|
829
|
+
# S and M suffixes: https://support.kraken.com/hc/en-us/articles/360039879471-What-is-Asset-S-and-Asset-M-
|
|
830
|
+
#
|
|
681
831
|
code = self.safe_currency_code(id)
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
832
|
+
# the below can not be reliable done in `safeCurrencyCode`, so we have to do it here
|
|
833
|
+
if id.find('.') < 0:
|
|
834
|
+
altName = self.safe_string(currency, 'altname')
|
|
835
|
+
# handle cases like below:
|
|
836
|
+
#
|
|
837
|
+
# id | altname
|
|
838
|
+
# ---------------
|
|
839
|
+
# XXBT | XBT
|
|
840
|
+
# ZUSD | USD
|
|
841
|
+
if id != altName and (id.startswith('X') or id.startswith('Z')):
|
|
842
|
+
code = self.safe_currency_code(altName)
|
|
843
|
+
# also, add map in commonCurrencies:
|
|
844
|
+
self.commonCurrencies[id] = code
|
|
845
|
+
else:
|
|
846
|
+
code = self.safe_currency_code(id)
|
|
847
|
+
isFiat = code.find('.HOLD') >= 0
|
|
848
|
+
result[code] = self.safe_currency_structure({
|
|
686
849
|
'id': id,
|
|
687
850
|
'code': code,
|
|
688
851
|
'info': currency,
|
|
689
852
|
'name': self.safe_string(currency, 'altname'),
|
|
690
|
-
'active':
|
|
853
|
+
'active': self.safe_string(currency, 'status') == 'enabled',
|
|
854
|
+
'type': 'fiat' if isFiat else 'crypto',
|
|
691
855
|
'deposit': None,
|
|
692
856
|
'withdraw': None,
|
|
693
857
|
'fee': None,
|
|
694
|
-
'precision':
|
|
858
|
+
'precision': self.parse_number(self.parse_precision(self.safe_string(currency, 'decimals'))),
|
|
695
859
|
'limits': {
|
|
696
860
|
'amount': {
|
|
697
|
-
'min':
|
|
861
|
+
'min': None,
|
|
698
862
|
'max': None,
|
|
699
863
|
},
|
|
700
864
|
'withdraw': {
|
|
@@ -703,13 +867,26 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
703
867
|
},
|
|
704
868
|
},
|
|
705
869
|
'networks': {},
|
|
706
|
-
}
|
|
870
|
+
})
|
|
707
871
|
return result
|
|
708
872
|
|
|
873
|
+
def safe_currency_code(self, currencyId: Str, currency: Currency = None) -> Str:
|
|
874
|
+
if currencyId is None:
|
|
875
|
+
return currencyId
|
|
876
|
+
if currencyId.find('.') > 0:
|
|
877
|
+
# if ID contains .M, .S or .F, then it can't contain X or Z prefix. in such case, ID equals to ALTNAME
|
|
878
|
+
parts = currencyId.split('.')
|
|
879
|
+
firstPart = self.safe_string(parts, 0)
|
|
880
|
+
secondPart = self.safe_string(parts, 1)
|
|
881
|
+
return super(kraken, self).safe_currency_code(firstPart, currency) + '.' + secondPart
|
|
882
|
+
return super(kraken, self).safe_currency_code(currencyId, currency)
|
|
883
|
+
|
|
709
884
|
def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
|
|
710
885
|
"""
|
|
711
886
|
fetch the trading fees for a market
|
|
712
|
-
|
|
887
|
+
|
|
888
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getTradeVolume
|
|
889
|
+
|
|
713
890
|
:param str symbol: unified market symbol
|
|
714
891
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
715
892
|
:returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
|
|
@@ -776,7 +953,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
776
953
|
def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
|
777
954
|
"""
|
|
778
955
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
779
|
-
|
|
956
|
+
|
|
957
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getOrderBook
|
|
958
|
+
|
|
780
959
|
:param str symbol: unified symbol of the market to fetch the order book for
|
|
781
960
|
:param int [limit]: the maximum amount of order book entries to return
|
|
782
961
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -784,8 +963,6 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
784
963
|
"""
|
|
785
964
|
self.load_markets()
|
|
786
965
|
market = self.market(symbol)
|
|
787
|
-
if market['darkpool']:
|
|
788
|
-
raise ExchangeError(self.id + ' fetchOrderBook() does not provide an order book for darkpool symbol ' + symbol)
|
|
789
966
|
request: dict = {
|
|
790
967
|
'pair': market['id'],
|
|
791
968
|
}
|
|
@@ -854,9 +1031,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
854
1031
|
'high': self.safe_string(high, 1),
|
|
855
1032
|
'low': self.safe_string(low, 1),
|
|
856
1033
|
'bid': self.safe_string(bid, 0),
|
|
857
|
-
'bidVolume':
|
|
1034
|
+
'bidVolume': self.safe_string(bid, 2),
|
|
858
1035
|
'ask': self.safe_string(ask, 0),
|
|
859
|
-
'askVolume':
|
|
1036
|
+
'askVolume': self.safe_string(ask, 2),
|
|
860
1037
|
'vwap': vwap,
|
|
861
1038
|
'open': self.safe_string(ticker, 'o'),
|
|
862
1039
|
'close': last,
|
|
@@ -873,7 +1050,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
873
1050
|
def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
|
874
1051
|
"""
|
|
875
1052
|
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
876
|
-
|
|
1053
|
+
|
|
1054
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTickerInformation
|
|
1055
|
+
|
|
877
1056
|
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
878
1057
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
879
1058
|
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
@@ -886,7 +1065,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
886
1065
|
for i in range(0, len(symbols)):
|
|
887
1066
|
symbol = symbols[i]
|
|
888
1067
|
market = self.markets[symbol]
|
|
889
|
-
if market['active']
|
|
1068
|
+
if market['active']:
|
|
890
1069
|
marketIds.append(market['id'])
|
|
891
1070
|
request['pair'] = ','.join(marketIds)
|
|
892
1071
|
response = self.publicGetTicker(self.extend(request, params))
|
|
@@ -904,15 +1083,14 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
904
1083
|
def fetch_ticker(self, symbol: str, params={}) -> Ticker:
|
|
905
1084
|
"""
|
|
906
1085
|
fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
907
|
-
|
|
1086
|
+
|
|
1087
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTickerInformation
|
|
1088
|
+
|
|
908
1089
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
|
909
1090
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
910
1091
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
911
1092
|
"""
|
|
912
1093
|
self.load_markets()
|
|
913
|
-
darkpool = symbol.find('.d') >= 0
|
|
914
|
-
if darkpool:
|
|
915
|
-
raise ExchangeError(self.id + ' fetchTicker() does not provide a ticker for darkpool symbol ' + symbol)
|
|
916
1094
|
market = self.market(symbol)
|
|
917
1095
|
request: dict = {
|
|
918
1096
|
'pair': market['id'],
|
|
@@ -946,7 +1124,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
946
1124
|
def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
|
947
1125
|
"""
|
|
948
1126
|
fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
949
|
-
|
|
1127
|
+
|
|
1128
|
+
https://docs.kraken.com/api/docs/rest-api/get-ohlc-data
|
|
1129
|
+
|
|
950
1130
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
|
951
1131
|
:param str timeframe: the length of time each candle represents
|
|
952
1132
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
|
@@ -1001,7 +1181,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1001
1181
|
}
|
|
1002
1182
|
return self.safe_string(types, type, type)
|
|
1003
1183
|
|
|
1004
|
-
def parse_ledger_entry(self, item: dict, currency: Currency = None):
|
|
1184
|
+
def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
|
|
1005
1185
|
#
|
|
1006
1186
|
# {
|
|
1007
1187
|
# 'LTFK7F-N2CUX-PNY4SX': {
|
|
@@ -1023,15 +1203,17 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1023
1203
|
referenceId = self.safe_string(item, 'refid')
|
|
1024
1204
|
referenceAccount = None
|
|
1025
1205
|
type = self.parse_ledger_entry_type(self.safe_string(item, 'type'))
|
|
1026
|
-
|
|
1206
|
+
currencyId = self.safe_string(item, 'asset')
|
|
1207
|
+
code = self.safe_currency_code(currencyId, currency)
|
|
1208
|
+
currency = self.safe_currency(currencyId, currency)
|
|
1027
1209
|
amount = self.safe_string(item, 'amount')
|
|
1028
1210
|
if Precise.string_lt(amount, '0'):
|
|
1029
1211
|
direction = 'out'
|
|
1030
1212
|
amount = Precise.string_abs(amount)
|
|
1031
1213
|
else:
|
|
1032
1214
|
direction = 'in'
|
|
1033
|
-
timestamp = self.
|
|
1034
|
-
return {
|
|
1215
|
+
timestamp = self.safe_integer_product(item, 'time', 1000)
|
|
1216
|
+
return self.safe_ledger_entry({
|
|
1035
1217
|
'info': item,
|
|
1036
1218
|
'id': id,
|
|
1037
1219
|
'direction': direction,
|
|
@@ -1050,18 +1232,21 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1050
1232
|
'cost': self.safe_number(item, 'fee'),
|
|
1051
1233
|
'currency': code,
|
|
1052
1234
|
},
|
|
1053
|
-
}
|
|
1235
|
+
}, currency)
|
|
1054
1236
|
|
|
1055
|
-
def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
|
|
1237
|
+
def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
|
|
1056
1238
|
"""
|
|
1057
|
-
fetch the history of changes, actions done by the user or operations that altered balance of the user
|
|
1058
|
-
|
|
1059
|
-
|
|
1239
|
+
fetch the history of changes, actions done by the user or operations that altered the balance of the user
|
|
1240
|
+
|
|
1241
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getLedgers
|
|
1242
|
+
|
|
1243
|
+
:param str [code]: unified currency code, default is None
|
|
1060
1244
|
:param int [since]: timestamp in ms of the earliest ledger entry, default is None
|
|
1061
|
-
:param int [limit]: max number of ledger
|
|
1245
|
+
:param int [limit]: max number of ledger entries to return, default is None
|
|
1062
1246
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1063
1247
|
:param int [params.until]: timestamp in ms of the latest ledger entry
|
|
1064
|
-
:
|
|
1248
|
+
:param int [params.end]: timestamp in seconds of the latest ledger entry
|
|
1249
|
+
:returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
|
|
1065
1250
|
"""
|
|
1066
1251
|
# https://www.kraken.com/features/api#get-ledgers-info
|
|
1067
1252
|
self.load_markets()
|
|
@@ -1072,7 +1257,11 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1072
1257
|
request['asset'] = currency['id']
|
|
1073
1258
|
if since is not None:
|
|
1074
1259
|
request['start'] = self.parse_to_int(since / 1000)
|
|
1075
|
-
|
|
1260
|
+
until = self.safe_string_n(params, ['until', 'till'])
|
|
1261
|
+
if until is not None:
|
|
1262
|
+
params = self.omit(params, ['until', 'till'])
|
|
1263
|
+
untilDivided = Precise.string_div(until, '1000')
|
|
1264
|
+
request['end'] = self.parse_to_int(Precise.string_add(untilDivided, '1'))
|
|
1076
1265
|
response = self.privatePostLedgers(self.extend(request, params))
|
|
1077
1266
|
# { error: [],
|
|
1078
1267
|
# "result": {ledger: {'LPUAIB-TS774-UKHP7X': { refid: "A2B4HBV-L4MDIE-JU4N3N",
|
|
@@ -1121,7 +1310,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1121
1310
|
items.append(value)
|
|
1122
1311
|
return self.parse_ledger(items)
|
|
1123
1312
|
|
|
1124
|
-
def fetch_ledger_entry(self, id: str, code: Str = None, params={}):
|
|
1313
|
+
def fetch_ledger_entry(self, id: str, code: Str = None, params={}) -> LedgerEntry:
|
|
1125
1314
|
items = self.fetch_ledger_entries_by_ids([id], code, params)
|
|
1126
1315
|
return items[0]
|
|
1127
1316
|
|
|
@@ -1156,7 +1345,40 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1156
1345
|
# "misc": ''
|
|
1157
1346
|
# }
|
|
1158
1347
|
#
|
|
1348
|
+
# fetchMyTrades
|
|
1349
|
+
#
|
|
1350
|
+
# {
|
|
1351
|
+
# "ordertxid": "OSJVN7-A2AE-63WZV",
|
|
1352
|
+
# "postxid": "TBP7O6-PNXI-CONU",
|
|
1353
|
+
# "pair": "XXBTZUSD",
|
|
1354
|
+
# "time": 1710429248.3052235,
|
|
1355
|
+
# "type": "sell",
|
|
1356
|
+
# "ordertype": "liquidation market",
|
|
1357
|
+
# "price": "72026.50000",
|
|
1358
|
+
# "cost": "7.20265",
|
|
1359
|
+
# "fee": "0.01873",
|
|
1360
|
+
# "vol": "0.00010000",
|
|
1361
|
+
# "margin": "1.44053",
|
|
1362
|
+
# "leverage": "5",
|
|
1363
|
+
# "misc": "closing",
|
|
1364
|
+
# "trade_id": 68230622,
|
|
1365
|
+
# "maker": False
|
|
1366
|
+
# }
|
|
1367
|
+
#
|
|
1368
|
+
# watchTrades
|
|
1369
|
+
#
|
|
1370
|
+
# {
|
|
1371
|
+
# "symbol": "BTC/USD",
|
|
1372
|
+
# "side": "buy",
|
|
1373
|
+
# "price": 109601.2,
|
|
1374
|
+
# "qty": 0.04561994,
|
|
1375
|
+
# "ord_type": "market",
|
|
1376
|
+
# "trade_id": 83449369,
|
|
1377
|
+
# "timestamp": "2025-05-27T11:24:03.847761Z"
|
|
1378
|
+
# }
|
|
1379
|
+
#
|
|
1159
1380
|
timestamp = None
|
|
1381
|
+
datetime = None
|
|
1160
1382
|
side = None
|
|
1161
1383
|
type = None
|
|
1162
1384
|
price = None
|
|
@@ -1199,19 +1421,35 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1199
1421
|
'cost': self.safe_string(trade, 'fee'),
|
|
1200
1422
|
'currency': currency,
|
|
1201
1423
|
}
|
|
1424
|
+
else:
|
|
1425
|
+
symbol = self.safe_string(trade, 'symbol')
|
|
1426
|
+
datetime = self.safe_string(trade, 'timestamp')
|
|
1427
|
+
id = self.safe_string(trade, 'trade_id')
|
|
1428
|
+
side = self.safe_string(trade, 'side')
|
|
1429
|
+
type = self.safe_string(trade, 'ord_type')
|
|
1430
|
+
price = self.safe_string(trade, 'price')
|
|
1431
|
+
amount = self.safe_string(trade, 'qty')
|
|
1202
1432
|
if market is not None:
|
|
1203
1433
|
symbol = market['symbol']
|
|
1204
1434
|
cost = self.safe_string(trade, 'cost')
|
|
1435
|
+
maker = self.safe_bool(trade, 'maker')
|
|
1436
|
+
takerOrMaker = None
|
|
1437
|
+
if maker is not None:
|
|
1438
|
+
takerOrMaker = 'maker' if maker else 'taker'
|
|
1439
|
+
if datetime is None:
|
|
1440
|
+
datetime = self.iso8601(timestamp)
|
|
1441
|
+
else:
|
|
1442
|
+
timestamp = self.parse8601(datetime)
|
|
1205
1443
|
return self.safe_trade({
|
|
1206
1444
|
'id': id,
|
|
1207
1445
|
'order': orderId,
|
|
1208
1446
|
'info': trade,
|
|
1209
1447
|
'timestamp': timestamp,
|
|
1210
|
-
'datetime':
|
|
1448
|
+
'datetime': datetime,
|
|
1211
1449
|
'symbol': symbol,
|
|
1212
1450
|
'type': type,
|
|
1213
1451
|
'side': side,
|
|
1214
|
-
'takerOrMaker':
|
|
1452
|
+
'takerOrMaker': takerOrMaker,
|
|
1215
1453
|
'price': price,
|
|
1216
1454
|
'amount': amount,
|
|
1217
1455
|
'cost': cost,
|
|
@@ -1221,7 +1459,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1221
1459
|
def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
1222
1460
|
"""
|
|
1223
1461
|
get the list of most recent trades for a particular symbol
|
|
1224
|
-
|
|
1462
|
+
|
|
1463
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getRecentTrades
|
|
1464
|
+
|
|
1225
1465
|
:param str symbol: unified symbol of the market to fetch trades for
|
|
1226
1466
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
|
1227
1467
|
:param int [limit]: the maximum amount of trades to fetch
|
|
@@ -1285,7 +1525,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1285
1525
|
def fetch_balance(self, params={}) -> Balances:
|
|
1286
1526
|
"""
|
|
1287
1527
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
|
1288
|
-
|
|
1528
|
+
|
|
1529
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getExtendedBalance
|
|
1530
|
+
|
|
1289
1531
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1290
1532
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
|
1291
1533
|
"""
|
|
@@ -1311,7 +1553,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1311
1553
|
def create_market_order_with_cost(self, symbol: str, side: OrderSide, cost: float, params={}):
|
|
1312
1554
|
"""
|
|
1313
1555
|
create a market order by providing the symbol, side and cost
|
|
1314
|
-
|
|
1556
|
+
|
|
1557
|
+
https://docs.kraken.com/rest/#tag/Spot-Trading/operation/addOrder
|
|
1558
|
+
|
|
1315
1559
|
:param str symbol: unified symbol of the market to create an order in(only USD markets are supported)
|
|
1316
1560
|
:param str side: 'buy' or 'sell'
|
|
1317
1561
|
:param float cost: how much you want to trade in units of the quote currency
|
|
@@ -1320,13 +1564,17 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1320
1564
|
"""
|
|
1321
1565
|
self.load_markets()
|
|
1322
1566
|
# only buy orders are supported by the endpoint
|
|
1323
|
-
|
|
1324
|
-
|
|
1567
|
+
req = {
|
|
1568
|
+
'cost': cost,
|
|
1569
|
+
}
|
|
1570
|
+
return self.create_order(symbol, 'market', side, cost, None, self.extend(req, params))
|
|
1325
1571
|
|
|
1326
1572
|
def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
|
|
1327
1573
|
"""
|
|
1328
1574
|
create a market buy order by providing the symbol, side and cost
|
|
1329
|
-
|
|
1575
|
+
|
|
1576
|
+
https://docs.kraken.com/rest/#tag/Spot-Trading/operation/addOrder
|
|
1577
|
+
|
|
1330
1578
|
:param str symbol: unified symbol of the market to create an order in
|
|
1331
1579
|
:param float cost: how much you want to trade in units of the quote currency
|
|
1332
1580
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -1337,20 +1585,24 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1337
1585
|
|
|
1338
1586
|
def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
|
1339
1587
|
"""
|
|
1340
|
-
:see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
|
|
1341
1588
|
create a trade order
|
|
1589
|
+
|
|
1590
|
+
https://docs.kraken.com/api/docs/rest-api/add-order
|
|
1591
|
+
|
|
1342
1592
|
:param str symbol: unified symbol of the market to create an order in
|
|
1343
1593
|
:param str type: 'market' or 'limit'
|
|
1344
1594
|
:param str side: 'buy' or 'sell'
|
|
1345
1595
|
:param float amount: how much of currency you want to trade in units of base currency
|
|
1346
|
-
:param float [price]: the price at which the order is to be
|
|
1596
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
1347
1597
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1348
1598
|
:param bool [params.postOnly]: if True, the order will only be posted to the order book and not executed immediately
|
|
1349
1599
|
:param bool [params.reduceOnly]: *margin only* indicates if self order is to reduce the size of a position
|
|
1350
1600
|
:param float [params.stopLossPrice]: *margin only* the price that a stop loss order is triggered at
|
|
1351
1601
|
:param float [params.takeProfitPrice]: *margin only* the price that a take profit order is triggered at
|
|
1352
1602
|
:param str [params.trailingAmount]: *margin only* the quote amount to trail away from the current market price
|
|
1603
|
+
:param str [params.trailingPercent]: *margin only* the percent to trail away from the current market price
|
|
1353
1604
|
:param str [params.trailingLimitAmount]: *margin only* the quote amount away from the trailingAmount
|
|
1605
|
+
:param str [params.trailingLimitPercent]: *margin only* the percent away from the trailingAmount
|
|
1354
1606
|
:param str [params.offset]: *margin only* '+' or '-' whether you want the trailingLimitAmount value to be positive or negative, default is negative '-'
|
|
1355
1607
|
:param str [params.trigger]: *margin only* the activation price type, 'last' or 'index', default is 'last'
|
|
1356
1608
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
@@ -1364,17 +1616,23 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1364
1616
|
'volume': self.amount_to_precision(symbol, amount),
|
|
1365
1617
|
}
|
|
1366
1618
|
orderRequest = self.order_request('createOrder', symbol, type, request, amount, price, params)
|
|
1619
|
+
flags = self.safe_string(orderRequest[0], 'oflags', '')
|
|
1620
|
+
isUsingCost = flags.find('viqc') > -1
|
|
1367
1621
|
response = self.privatePostAddOrder(self.extend(orderRequest[0], orderRequest[1]))
|
|
1368
1622
|
#
|
|
1369
1623
|
# {
|
|
1370
1624
|
# "error": [],
|
|
1371
1625
|
# "result": {
|
|
1372
|
-
# "descr": {order: 'buy 0.02100000 ETHUSDT @ limit 330.00'},
|
|
1626
|
+
# "descr": {order: 'buy 0.02100000 ETHUSDT @ limit 330.00'}, # see more examples in "parseOrder"
|
|
1373
1627
|
# "txid": ['OEKVV2-IH52O-TPL6GZ']
|
|
1374
1628
|
# }
|
|
1375
1629
|
# }
|
|
1376
1630
|
#
|
|
1377
1631
|
result = self.safe_dict(response, 'result')
|
|
1632
|
+
result['usingCost'] = isUsingCost
|
|
1633
|
+
# it's impossible to know if the order was created using cost or base currency
|
|
1634
|
+
# becuase kraken only returns something like self: {order: 'buy 10.00000000 LTCUSD @ market'}
|
|
1635
|
+
# self usingCost flag is used to help the parsing but omited from the order
|
|
1378
1636
|
return self.parse_order(result)
|
|
1379
1637
|
|
|
1380
1638
|
def find_market_by_altname_or_id(self, id):
|
|
@@ -1429,9 +1687,10 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1429
1687
|
|
|
1430
1688
|
def parse_order_type(self, status):
|
|
1431
1689
|
statuses: dict = {
|
|
1690
|
+
# we dont add "space" delimited orders here(eg. stop loss) because they need separate parsing
|
|
1432
1691
|
'take-profit': 'market',
|
|
1433
|
-
'stop-loss-limit': 'limit',
|
|
1434
1692
|
'stop-loss': 'market',
|
|
1693
|
+
'stop-loss-limit': 'limit',
|
|
1435
1694
|
'take-profit-limit': 'limit',
|
|
1436
1695
|
'trailing-stop-limit': 'limit',
|
|
1437
1696
|
}
|
|
@@ -1439,61 +1698,36 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1439
1698
|
|
|
1440
1699
|
def parse_order(self, order: dict, market: Market = None) -> Order:
|
|
1441
1700
|
#
|
|
1442
|
-
# createOrder
|
|
1701
|
+
# createOrder
|
|
1443
1702
|
#
|
|
1444
1703
|
# {
|
|
1445
|
-
# "descr": {
|
|
1704
|
+
# "descr": {
|
|
1705
|
+
# "order": "buy 0.02100000 ETHUSDT @ limit 330.00" # limit orders
|
|
1706
|
+
# "buy 0.12345678 ETHUSDT @ market" # market order
|
|
1707
|
+
# "sell 0.28002676 ETHUSDT @ stop loss 0.0123 -> limit 0.0.1222" # stop order
|
|
1708
|
+
# "sell 0.00100000 ETHUSDT @ stop loss 2677.00 -> limit 2577.00 with 5:1 leverage"
|
|
1709
|
+
# "buy 0.10000000 LTCUSDT @ take profit 75.00000 -> limit 74.00000"
|
|
1710
|
+
# "sell 10.00000000 XRPEUR @ trailing stop +50.0000%" # trailing stop
|
|
1711
|
+
# },
|
|
1446
1712
|
# "txid": ['OEKVV2-IH52O-TPL6GZ']
|
|
1447
1713
|
# }
|
|
1448
|
-
# {
|
|
1449
|
-
# "txid": ["TX_ID_HERE"],
|
|
1450
|
-
# "descr": {"order":"buy 0.12345678 ETHEUR @ market"},
|
|
1451
|
-
# }
|
|
1452
|
-
#
|
|
1453
1714
|
#
|
|
1454
|
-
#
|
|
1715
|
+
# editOrder
|
|
1455
1716
|
#
|
|
1456
1717
|
# {
|
|
1457
|
-
# "
|
|
1458
|
-
# "descr":{"order":"sell 167.28002676 ADAXBT @ stop loss 0.00003280 -> limit 0.00003212"}
|
|
1718
|
+
# "amend_id": "TJSMEH-AA67V-YUSQ6O"
|
|
1459
1719
|
# }
|
|
1460
1720
|
#
|
|
1461
|
-
#
|
|
1721
|
+
# ws - createOrder
|
|
1462
1722
|
# {
|
|
1463
|
-
# "
|
|
1464
|
-
# "descr":{"order":"sell 0.00100000 ETHUSD @ stop loss 2677.00 -> limit 2577.00 with 5:1 leverage"}
|
|
1723
|
+
# "order_id": "OXM2QD-EALR2-YBAVEU"
|
|
1465
1724
|
# }
|
|
1466
1725
|
#
|
|
1467
|
-
# editOrder
|
|
1468
|
-
#
|
|
1726
|
+
# ws - editOrder
|
|
1469
1727
|
# {
|
|
1470
|
-
# "
|
|
1471
|
-
# "
|
|
1472
|
-
# "originaltxid": "OXL6SS-UPNMC-26WBE7",
|
|
1473
|
-
# "volume": "0.00075000",
|
|
1474
|
-
# "price": "13500.0",
|
|
1475
|
-
# "orders_cancelled": 1,
|
|
1476
|
-
# "descr": {
|
|
1477
|
-
# "order": "buy 0.00075000 XBTUSDT @ limit 13500.0"
|
|
1478
|
-
# }
|
|
1728
|
+
# "amend_id": "TJSMEH-AA67V-YUSQ6O",
|
|
1729
|
+
# "order_id": "OXM2QD-EALR2-YBAVEU"
|
|
1479
1730
|
# }
|
|
1480
|
-
# ws - createOrder
|
|
1481
|
-
# {
|
|
1482
|
-
# "descr": 'sell 0.00010000 XBTUSDT @ market',
|
|
1483
|
-
# "event": 'addOrderStatus',
|
|
1484
|
-
# "reqid": 1,
|
|
1485
|
-
# "status": 'ok',
|
|
1486
|
-
# "txid": 'OAVXZH-XIE54-JCYYDG'
|
|
1487
|
-
# }
|
|
1488
|
-
# ws - editOrder
|
|
1489
|
-
# {
|
|
1490
|
-
# "descr": "order edited price = 9000.00000000",
|
|
1491
|
-
# "event": "editOrderStatus",
|
|
1492
|
-
# "originaltxid": "O65KZW-J4AW3-VFS74A",
|
|
1493
|
-
# "reqid": 3,
|
|
1494
|
-
# "status": "ok",
|
|
1495
|
-
# "txid": "OTI672-HJFAO-XOIPPK"
|
|
1496
|
-
# }
|
|
1497
1731
|
#
|
|
1498
1732
|
# {
|
|
1499
1733
|
# "error": [],
|
|
@@ -1530,6 +1764,39 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1530
1764
|
# }
|
|
1531
1765
|
# }
|
|
1532
1766
|
#
|
|
1767
|
+
# fetchOpenOrders
|
|
1768
|
+
#
|
|
1769
|
+
# {
|
|
1770
|
+
# "refid": null,
|
|
1771
|
+
# "userref": null,
|
|
1772
|
+
# "cl_ord_id": "1234",
|
|
1773
|
+
# "status": "open",
|
|
1774
|
+
# "opentm": 1733815269.370054,
|
|
1775
|
+
# "starttm": 0,
|
|
1776
|
+
# "expiretm": 0,
|
|
1777
|
+
# "descr": {
|
|
1778
|
+
# "pair": "XBTUSD",
|
|
1779
|
+
# "type": "buy",
|
|
1780
|
+
# "ordertype": "limit",
|
|
1781
|
+
# "price": "70000.0",
|
|
1782
|
+
# "price2": "0",
|
|
1783
|
+
# "leverage": "none",
|
|
1784
|
+
# "order": "buy 0.00010000 XBTUSD @ limit 70000.0",
|
|
1785
|
+
# "close": ""
|
|
1786
|
+
# },
|
|
1787
|
+
# "vol": "0.00010000",
|
|
1788
|
+
# "vol_exec": "0.00000000",
|
|
1789
|
+
# "cost": "0.00000",
|
|
1790
|
+
# "fee": "0.00000",
|
|
1791
|
+
# "price": "0.00000",
|
|
1792
|
+
# "stopprice": "0.00000",
|
|
1793
|
+
# "limitprice": "0.00000",
|
|
1794
|
+
# "misc": "",
|
|
1795
|
+
# "oflags": "fciq"
|
|
1796
|
+
# }
|
|
1797
|
+
#
|
|
1798
|
+
isUsingCost = self.safe_bool(order, 'usingCost', False)
|
|
1799
|
+
order = self.omit(order, 'usingCost')
|
|
1533
1800
|
description = self.safe_dict(order, 'descr', {})
|
|
1534
1801
|
orderDescriptionObj = self.safe_dict(order, 'descr') # can be null
|
|
1535
1802
|
orderDescription = None
|
|
@@ -1538,24 +1805,33 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1538
1805
|
else:
|
|
1539
1806
|
orderDescription = self.safe_string(order, 'descr')
|
|
1540
1807
|
side = None
|
|
1541
|
-
|
|
1808
|
+
rawType = None
|
|
1542
1809
|
marketId = None
|
|
1543
1810
|
price = None
|
|
1544
1811
|
amount = None
|
|
1545
|
-
|
|
1812
|
+
cost = None
|
|
1813
|
+
triggerPrice = None
|
|
1546
1814
|
if orderDescription is not None:
|
|
1547
1815
|
parts = orderDescription.split(' ')
|
|
1548
1816
|
side = self.safe_string(parts, 0)
|
|
1549
|
-
|
|
1817
|
+
if not isUsingCost:
|
|
1818
|
+
amount = self.safe_string(parts, 1)
|
|
1819
|
+
else:
|
|
1820
|
+
cost = self.safe_string(parts, 1)
|
|
1550
1821
|
marketId = self.safe_string(parts, 2)
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1822
|
+
part4 = self.safe_string(parts, 4)
|
|
1823
|
+
part5 = self.safe_string(parts, 5)
|
|
1824
|
+
if part4 == 'limit' or part4 == 'market':
|
|
1825
|
+
rawType = part4 # eg, limit, market
|
|
1826
|
+
else:
|
|
1827
|
+
rawType = part4 + ' ' + part5 # eg. stop loss, take profit, trailing stop
|
|
1828
|
+
if rawType == 'stop loss' or rawType == 'take profit':
|
|
1829
|
+
triggerPrice = self.safe_string(parts, 6)
|
|
1554
1830
|
price = self.safe_string(parts, 9)
|
|
1555
|
-
elif
|
|
1831
|
+
elif rawType == 'limit':
|
|
1556
1832
|
price = self.safe_string(parts, 5)
|
|
1557
1833
|
side = self.safe_string(description, 'type', side)
|
|
1558
|
-
|
|
1834
|
+
rawType = self.safe_string(description, 'ordertype', rawType) # orderType has dash, e.g. trailing-stop
|
|
1559
1835
|
marketId = self.safe_string(description, 'pair', marketId)
|
|
1560
1836
|
foundMarket = self.find_market_by_altname_or_id(marketId)
|
|
1561
1837
|
symbol = None
|
|
@@ -1571,13 +1847,12 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1571
1847
|
# kraken truncates the cost in the api response so we will ignore it and calculate it from average & filled
|
|
1572
1848
|
# cost = self.safe_string(order, 'cost')
|
|
1573
1849
|
price = self.safe_string(description, 'price', price)
|
|
1574
|
-
# when type =
|
|
1575
|
-
if (price is not None) and price.endswith('%'):
|
|
1850
|
+
# when type = trailing stop returns price = '+50.0000%'
|
|
1851
|
+
if (price is not None) and (price.endswith('%') or Precise.string_equals(price, '0.00000') or Precise.string_equals(price, '0')):
|
|
1576
1852
|
price = None # self is not the price we want
|
|
1577
|
-
if
|
|
1853
|
+
if price is None:
|
|
1578
1854
|
price = self.safe_string(description, 'price2')
|
|
1579
|
-
|
|
1580
|
-
price = self.safe_string(order, 'price', price)
|
|
1855
|
+
price = self.safe_string_2(order, 'limitprice', 'price', price)
|
|
1581
1856
|
flags = self.safe_string(order, 'oflags', '')
|
|
1582
1857
|
isPostOnly = flags.find('post') > -1
|
|
1583
1858
|
average = self.safe_number(order, 'price')
|
|
@@ -1594,11 +1869,12 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1594
1869
|
elif flags.find('fcib') >= 0:
|
|
1595
1870
|
fee['currency'] = market['base']
|
|
1596
1871
|
status = self.parse_order_status(self.safe_string(order, 'status'))
|
|
1597
|
-
id = self.
|
|
1872
|
+
id = self.safe_string_n(order, ['id', 'txid', 'order_id', 'amend_id'])
|
|
1598
1873
|
if (id is None) or (id.startswith('[')):
|
|
1599
1874
|
txid = self.safe_list(order, 'txid')
|
|
1600
1875
|
id = self.safe_string(txid, 0)
|
|
1601
|
-
|
|
1876
|
+
userref = self.safe_string(order, 'userref')
|
|
1877
|
+
clientOrderId = self.safe_string(order, 'cl_ord_id', userref)
|
|
1602
1878
|
rawTrades = self.safe_value(order, 'trades', [])
|
|
1603
1879
|
trades = []
|
|
1604
1880
|
for i in range(0, len(rawTrades)):
|
|
@@ -1607,15 +1883,32 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1607
1883
|
trades.append(self.safe_trade({'id': rawTrade, 'orderId': id, 'symbol': symbol, 'info': {}}))
|
|
1608
1884
|
else:
|
|
1609
1885
|
trades.append(rawTrade)
|
|
1610
|
-
|
|
1886
|
+
# in #24192 PR, self field is not something consistent/actual
|
|
1887
|
+
# triggerPrice = self.omit_zero(self.safe_string(order, 'stopprice', triggerPrice))
|
|
1611
1888
|
stopLossPrice = None
|
|
1612
1889
|
takeProfitPrice = None
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1890
|
+
# the dashed strings are not provided from fields(eg. fetch order)
|
|
1891
|
+
# while spaced strings from "order" sentence(when other fields not available)
|
|
1892
|
+
if rawType is not None:
|
|
1893
|
+
if rawType.startswith('take-profit'):
|
|
1894
|
+
takeProfitPrice = self.safe_string(description, 'price')
|
|
1895
|
+
price = self.omit_zero(self.safe_string(description, 'price2'))
|
|
1896
|
+
elif rawType.startswith('stop-loss'):
|
|
1897
|
+
stopLossPrice = self.safe_string(description, 'price')
|
|
1898
|
+
price = self.omit_zero(self.safe_string(description, 'price2'))
|
|
1899
|
+
elif rawType == 'take profit':
|
|
1900
|
+
takeProfitPrice = triggerPrice
|
|
1901
|
+
elif rawType == 'stop loss':
|
|
1902
|
+
stopLossPrice = triggerPrice
|
|
1903
|
+
finalType = self.parse_order_type(rawType)
|
|
1904
|
+
# unlike from endpoints which provide eg: "take-profit-limit"
|
|
1905
|
+
# for "space-delimited" orders we dont have market/limit suffixes, their format is
|
|
1906
|
+
# eg: `stop loss > limit 123`, so we need to parse them manually
|
|
1907
|
+
if self.in_array(finalType, ['stop loss', 'take profit']):
|
|
1908
|
+
finalType = 'market' if (price is None) else 'limit'
|
|
1909
|
+
amendId = self.safe_string(order, 'amend_id')
|
|
1910
|
+
if amendId is not None:
|
|
1911
|
+
isPostOnly = None
|
|
1619
1912
|
return self.safe_order({
|
|
1620
1913
|
'id': id,
|
|
1621
1914
|
'clientOrderId': clientOrderId,
|
|
@@ -1625,37 +1918,40 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1625
1918
|
'lastTradeTimestamp': None,
|
|
1626
1919
|
'status': status,
|
|
1627
1920
|
'symbol': symbol,
|
|
1628
|
-
'type':
|
|
1921
|
+
'type': finalType,
|
|
1629
1922
|
'timeInForce': None,
|
|
1630
1923
|
'postOnly': isPostOnly,
|
|
1631
1924
|
'side': side,
|
|
1632
1925
|
'price': price,
|
|
1633
|
-
'
|
|
1634
|
-
'triggerPrice': stopPrice,
|
|
1926
|
+
'triggerPrice': triggerPrice,
|
|
1635
1927
|
'takeProfitPrice': takeProfitPrice,
|
|
1636
1928
|
'stopLossPrice': stopLossPrice,
|
|
1637
|
-
'cost':
|
|
1929
|
+
'cost': cost,
|
|
1638
1930
|
'amount': amount,
|
|
1639
1931
|
'filled': filled,
|
|
1640
1932
|
'average': average,
|
|
1641
1933
|
'remaining': None,
|
|
1934
|
+
'reduceOnly': self.safe_bool_2(order, 'reduceOnly', 'reduce_only'),
|
|
1642
1935
|
'fee': fee,
|
|
1643
1936
|
'trades': trades,
|
|
1644
1937
|
}, market)
|
|
1645
1938
|
|
|
1646
1939
|
def order_request(self, method: str, symbol: str, type: str, request: dict, amount: Num, price: Num = None, params={}):
|
|
1647
|
-
clientOrderId = self.
|
|
1648
|
-
params = self.omit(params, ['
|
|
1940
|
+
clientOrderId = self.safe_string(params, 'clientOrderId')
|
|
1941
|
+
params = self.omit(params, ['clientOrderId'])
|
|
1649
1942
|
if clientOrderId is not None:
|
|
1650
|
-
request['
|
|
1943
|
+
request['cl_ord_id'] = clientOrderId
|
|
1651
1944
|
stopLossTriggerPrice = self.safe_string(params, 'stopLossPrice')
|
|
1652
1945
|
takeProfitTriggerPrice = self.safe_string(params, 'takeProfitPrice')
|
|
1653
1946
|
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
|
1654
1947
|
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
|
1655
1948
|
isStopLossOrTakeProfitTrigger = isStopLossTriggerOrder or isTakeProfitTriggerOrder
|
|
1656
1949
|
trailingAmount = self.safe_string(params, 'trailingAmount')
|
|
1950
|
+
trailingPercent = self.safe_string(params, 'trailingPercent')
|
|
1657
1951
|
trailingLimitAmount = self.safe_string(params, 'trailingLimitAmount')
|
|
1952
|
+
trailingLimitPercent = self.safe_string(params, 'trailingLimitPercent')
|
|
1658
1953
|
isTrailingAmountOrder = trailingAmount is not None
|
|
1954
|
+
isTrailingPercentOrder = trailingPercent is not None
|
|
1659
1955
|
isLimitOrder = type.endswith('limit') # supporting limit, stop-loss-limit, take-profit-limit, etc
|
|
1660
1956
|
isMarketOrder = type == 'market'
|
|
1661
1957
|
cost = self.safe_string(params, 'cost')
|
|
@@ -1669,7 +1965,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1669
1965
|
request['volume'] = self.cost_to_precision(symbol, cost)
|
|
1670
1966
|
extendedOflags = flags + ',viqc' if (flags is not None) else 'viqc'
|
|
1671
1967
|
request['oflags'] = extendedOflags
|
|
1672
|
-
elif isLimitOrder and not isTrailingAmountOrder:
|
|
1968
|
+
elif isLimitOrder and not isTrailingAmountOrder and not isTrailingPercentOrder:
|
|
1673
1969
|
request['price'] = self.price_to_precision(symbol, price)
|
|
1674
1970
|
reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only')
|
|
1675
1971
|
if isStopLossOrTakeProfitTrigger:
|
|
@@ -1687,19 +1983,30 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1687
1983
|
request['ordertype'] = 'take-profit'
|
|
1688
1984
|
if isLimitOrder:
|
|
1689
1985
|
request['price2'] = self.price_to_precision(symbol, price)
|
|
1690
|
-
elif isTrailingAmountOrder:
|
|
1986
|
+
elif isTrailingAmountOrder or isTrailingPercentOrder:
|
|
1987
|
+
trailingPercentString = None
|
|
1988
|
+
if trailingPercent is not None:
|
|
1989
|
+
trailingPercentString = ('+' + trailingPercent) if (trailingPercent.endswith('%')) else ('+' + trailingPercent + '%')
|
|
1990
|
+
trailingAmountString = '+' + trailingAmount if (trailingAmount is not None) else None # must use + for self
|
|
1991
|
+
offset = self.safe_string(params, 'offset', '-') # can use + or - for self
|
|
1992
|
+
trailingLimitAmountString = offset + self.number_to_string(trailingLimitAmount) if (trailingLimitAmount is not None) else None
|
|
1691
1993
|
trailingActivationPriceType = self.safe_string(params, 'trigger', 'last')
|
|
1692
|
-
trailingAmountString = '+' + trailingAmount
|
|
1693
1994
|
request['trigger'] = trailingActivationPriceType
|
|
1694
|
-
if isLimitOrder or (trailingLimitAmount is not None):
|
|
1695
|
-
offset = self.safe_string(params, 'offset', '-')
|
|
1696
|
-
trailingLimitAmountString = offset + self.number_to_string(trailingLimitAmount)
|
|
1697
|
-
request['price'] = trailingAmountString
|
|
1698
|
-
request['price2'] = trailingLimitAmountString
|
|
1995
|
+
if isLimitOrder or (trailingLimitAmount is not None) or (trailingLimitPercent is not None):
|
|
1699
1996
|
request['ordertype'] = 'trailing-stop-limit'
|
|
1997
|
+
if trailingLimitPercent is not None:
|
|
1998
|
+
trailingLimitPercentString = (offset + trailingLimitPercent) if (trailingLimitPercent.endswith('%')) else (offset + trailingLimitPercent + '%')
|
|
1999
|
+
request['price'] = trailingPercentString
|
|
2000
|
+
request['price2'] = trailingLimitPercentString
|
|
2001
|
+
elif trailingLimitAmount is not None:
|
|
2002
|
+
request['price'] = trailingAmountString
|
|
2003
|
+
request['price2'] = trailingLimitAmountString
|
|
1700
2004
|
else:
|
|
1701
|
-
request['price'] = trailingAmountString
|
|
1702
2005
|
request['ordertype'] = 'trailing-stop'
|
|
2006
|
+
if trailingPercent is not None:
|
|
2007
|
+
request['price'] = trailingPercentString
|
|
2008
|
+
else:
|
|
2009
|
+
request['price'] = trailingAmountString
|
|
1703
2010
|
if reduceOnly:
|
|
1704
2011
|
if method == 'createOrderWs':
|
|
1705
2012
|
request['reduce_only'] = True # ws request can't have stringified bool
|
|
@@ -1724,26 +2031,33 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1724
2031
|
if postOnly:
|
|
1725
2032
|
extendedPostFlags = flags + ',post' if (flags is not None) else 'post'
|
|
1726
2033
|
request['oflags'] = extendedPostFlags
|
|
1727
|
-
|
|
2034
|
+
if (flags is not None) and not ('oflags' in request):
|
|
2035
|
+
request['oflags'] = flags
|
|
2036
|
+
params = self.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'trailingLimitAmount', 'trailingLimitPercent', 'offset'])
|
|
1728
2037
|
return [request, params]
|
|
1729
2038
|
|
|
1730
2039
|
def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
|
1731
2040
|
"""
|
|
1732
2041
|
edit a trade order
|
|
1733
|
-
|
|
2042
|
+
|
|
2043
|
+
https://docs.kraken.com/api/docs/rest-api/amend-order
|
|
2044
|
+
|
|
1734
2045
|
:param str id: order id
|
|
1735
2046
|
:param str symbol: unified symbol of the market to create an order in
|
|
1736
2047
|
:param str type: 'market' or 'limit'
|
|
1737
2048
|
:param str side: 'buy' or 'sell'
|
|
1738
|
-
:param float amount: how much of the currency you want to trade in units of the base currency
|
|
1739
|
-
:param float [price]: the price at which the order is to be
|
|
2049
|
+
:param float [amount]: how much of the currency you want to trade in units of the base currency
|
|
2050
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
1740
2051
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1741
|
-
:param float [params.stopLossPrice]:
|
|
1742
|
-
:param float [params.takeProfitPrice]:
|
|
1743
|
-
:param str [params.trailingAmount]:
|
|
1744
|
-
:param str [params.
|
|
1745
|
-
:param str [params.
|
|
1746
|
-
:param str [params.
|
|
2052
|
+
:param float [params.stopLossPrice]: the price that a stop loss order is triggered at
|
|
2053
|
+
:param float [params.takeProfitPrice]: the price that a take profit order is triggered at
|
|
2054
|
+
:param str [params.trailingAmount]: the quote amount to trail away from the current market price
|
|
2055
|
+
:param str [params.trailingPercent]: the percent to trail away from the current market price
|
|
2056
|
+
:param str [params.trailingLimitAmount]: the quote amount away from the trailingAmount
|
|
2057
|
+
:param str [params.trailingLimitPercent]: the percent away from the trailingAmount
|
|
2058
|
+
:param str [params.offset]: '+' or '-' whether you want the trailingLimitAmount value to be positive or negative
|
|
2059
|
+
:param boolean [params.postOnly]: if True, the order will only be posted to the order book and not executed immediately
|
|
2060
|
+
:param str [params.clientOrderId]: the orders client order id
|
|
1747
2061
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
1748
2062
|
"""
|
|
1749
2063
|
self.load_markets()
|
|
@@ -1752,35 +2066,49 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1752
2066
|
raise NotSupported(self.id + ' editOrder() does not support ' + market['type'] + ' orders, only spot orders are accepted')
|
|
1753
2067
|
request: dict = {
|
|
1754
2068
|
'txid': id,
|
|
1755
|
-
'pair': market['id'],
|
|
1756
2069
|
}
|
|
2070
|
+
clientOrderId = self.safe_string_2(params, 'clientOrderId', 'cl_ord_id')
|
|
2071
|
+
if clientOrderId is not None:
|
|
2072
|
+
request['cl_ord_id'] = clientOrderId
|
|
2073
|
+
params = self.omit(params, ['clientOrderId', 'cl_ord_id'])
|
|
2074
|
+
request = self.omit(request, 'txid')
|
|
2075
|
+
isMarket = (type == 'market')
|
|
2076
|
+
postOnly = None
|
|
2077
|
+
postOnly, params = self.handle_post_only(isMarket, False, params)
|
|
2078
|
+
if postOnly:
|
|
2079
|
+
request['post_only'] = 'true' # not using hasattr(self, boolean) case, because the urlencodedNested transforms it into 'True' string
|
|
1757
2080
|
if amount is not None:
|
|
1758
|
-
request['
|
|
1759
|
-
|
|
1760
|
-
|
|
2081
|
+
request['order_qty'] = self.amount_to_precision(symbol, amount)
|
|
2082
|
+
if price is not None:
|
|
2083
|
+
request['limit_price'] = self.price_to_precision(symbol, price)
|
|
2084
|
+
allTriggerPrices = self.safe_string_n(params, ['stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'trailingLimitAmount', 'trailingLimitPercent'])
|
|
2085
|
+
if allTriggerPrices is not None:
|
|
2086
|
+
offset = self.safe_string(params, 'offset')
|
|
2087
|
+
params = self.omit(params, ['stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'trailingLimitAmount', 'trailingLimitPercent', 'offset'])
|
|
2088
|
+
if offset is not None:
|
|
2089
|
+
allTriggerPrices = offset + allTriggerPrices
|
|
2090
|
+
request['trigger_price'] = allTriggerPrices
|
|
2091
|
+
else:
|
|
2092
|
+
request['trigger_price'] = self.price_to_precision(symbol, allTriggerPrices)
|
|
2093
|
+
response = self.privatePostAmendOrder(self.extend(request, params))
|
|
1761
2094
|
#
|
|
1762
2095
|
# {
|
|
1763
2096
|
# "error": [],
|
|
1764
2097
|
# "result": {
|
|
1765
|
-
# "
|
|
1766
|
-
# "txid": "OAW2BO-7RWEK-PZY5UO",
|
|
1767
|
-
# "originaltxid": "OXL6SS-UPNMC-26WBE7",
|
|
1768
|
-
# "volume": "0.00075000",
|
|
1769
|
-
# "price": "13500.0",
|
|
1770
|
-
# "orders_cancelled": 1,
|
|
1771
|
-
# "descr": {
|
|
1772
|
-
# "order": "buy 0.00075000 XBTUSDT @ limit 13500.0"
|
|
1773
|
-
# }
|
|
2098
|
+
# "amend_id": "TJSMEH-AA67V-YUSQ6O"
|
|
1774
2099
|
# }
|
|
1775
2100
|
# }
|
|
1776
2101
|
#
|
|
1777
|
-
|
|
1778
|
-
return self.parse_order(
|
|
2102
|
+
result = self.safe_dict(response, 'result', {})
|
|
2103
|
+
return self.parse_order(result, market)
|
|
1779
2104
|
|
|
1780
2105
|
def fetch_order(self, id: str, symbol: Str = None, params={}):
|
|
1781
2106
|
"""
|
|
1782
2107
|
fetches information on an order made by the user
|
|
1783
|
-
|
|
2108
|
+
|
|
2109
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getOrdersInfo
|
|
2110
|
+
|
|
2111
|
+
:param str id: order id
|
|
1784
2112
|
:param str symbol: not used by kraken fetchOrder
|
|
1785
2113
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1786
2114
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
@@ -1789,15 +2117,13 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1789
2117
|
clientOrderId = self.safe_value_2(params, 'userref', 'clientOrderId')
|
|
1790
2118
|
request: dict = {
|
|
1791
2119
|
'trades': True, # whether or not to include trades in output(optional, default False)
|
|
1792
|
-
|
|
2120
|
+
'txid': id, # do not comma separate a list of ids - use fetchOrdersByIds instead
|
|
1793
2121
|
# 'userref': 'optional', # restrict results to given user reference id(optional)
|
|
1794
2122
|
}
|
|
1795
2123
|
query = params
|
|
1796
2124
|
if clientOrderId is not None:
|
|
1797
2125
|
request['userref'] = clientOrderId
|
|
1798
2126
|
query = self.omit(params, ['userref', 'clientOrderId'])
|
|
1799
|
-
else:
|
|
1800
|
-
request['txid'] = id
|
|
1801
2127
|
response = self.privatePostQueryOrders(self.extend(request, query))
|
|
1802
2128
|
#
|
|
1803
2129
|
# {
|
|
@@ -1844,7 +2170,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1844
2170
|
def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
|
1845
2171
|
"""
|
|
1846
2172
|
fetch all the trades made from a single order
|
|
1847
|
-
|
|
2173
|
+
|
|
2174
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getTradesInfo
|
|
2175
|
+
|
|
1848
2176
|
:param str id: order id
|
|
1849
2177
|
:param str symbol: unified market symbol
|
|
1850
2178
|
:param int [since]: the earliest time in ms to fetch trades for
|
|
@@ -1915,8 +2243,11 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1915
2243
|
def fetch_orders_by_ids(self, ids, symbol: Str = None, params={}):
|
|
1916
2244
|
"""
|
|
1917
2245
|
fetch orders by the list of order id
|
|
1918
|
-
|
|
1919
|
-
|
|
2246
|
+
|
|
2247
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getClosedOrders
|
|
2248
|
+
|
|
2249
|
+
:param str[] [ids]: list of order id
|
|
2250
|
+
:param str [symbol]: unified ccxt market symbol
|
|
1920
2251
|
:param dict [params]: extra parameters specific to the kraken api endpoint
|
|
1921
2252
|
:returns dict[]: a list of `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
1922
2253
|
"""
|
|
@@ -1938,11 +2269,15 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1938
2269
|
def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
|
1939
2270
|
"""
|
|
1940
2271
|
fetch all trades made by the user
|
|
1941
|
-
|
|
2272
|
+
|
|
2273
|
+
https://docs.kraken.com/api/docs/rest-api/get-trade-history
|
|
2274
|
+
|
|
1942
2275
|
:param str symbol: unified market symbol
|
|
1943
2276
|
:param int [since]: the earliest time in ms to fetch trades for
|
|
1944
2277
|
:param int [limit]: the maximum number of trades structures to retrieve
|
|
1945
2278
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2279
|
+
:param int [params.until]: timestamp in ms of the latest trade entry
|
|
2280
|
+
:param int [params.end]: timestamp in seconds of the latest trade entry
|
|
1946
2281
|
:returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
|
1947
2282
|
"""
|
|
1948
2283
|
self.load_markets()
|
|
@@ -1955,6 +2290,11 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1955
2290
|
}
|
|
1956
2291
|
if since is not None:
|
|
1957
2292
|
request['start'] = self.parse_to_int(since / 1000)
|
|
2293
|
+
until = self.safe_string_n(params, ['until', 'till'])
|
|
2294
|
+
if until is not None:
|
|
2295
|
+
params = self.omit(params, ['until', 'till'])
|
|
2296
|
+
untilDivided = Precise.string_div(until, '1000')
|
|
2297
|
+
request['end'] = self.parse_to_int(Precise.string_add(untilDivided, '1'))
|
|
1958
2298
|
response = self.privatePostTradesHistory(self.extend(request, params))
|
|
1959
2299
|
#
|
|
1960
2300
|
# {
|
|
@@ -1973,7 +2313,10 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1973
2313
|
# "fee": "0.000026",
|
|
1974
2314
|
# "vol": "16.00000000",
|
|
1975
2315
|
# "margin": "0.000000",
|
|
2316
|
+
# "leverage": "5",
|
|
1976
2317
|
# "misc": ""
|
|
2318
|
+
# "trade_id": 68230622,
|
|
2319
|
+
# "maker": False
|
|
1977
2320
|
# },
|
|
1978
2321
|
# ...
|
|
1979
2322
|
# },
|
|
@@ -1993,19 +2336,28 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
1993
2336
|
def cancel_order(self, id: str, symbol: Str = None, params={}):
|
|
1994
2337
|
"""
|
|
1995
2338
|
cancels an open order
|
|
1996
|
-
|
|
2339
|
+
|
|
2340
|
+
https://docs.kraken.com/api/docs/rest-api/cancel-order
|
|
2341
|
+
|
|
1997
2342
|
:param str id: order id
|
|
1998
|
-
:param str symbol: unified symbol of the market the order was made in
|
|
2343
|
+
:param str [symbol]: unified symbol of the market the order was made in
|
|
1999
2344
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2000
|
-
:
|
|
2345
|
+
:param str [params.clientOrderId]: the orders client order id
|
|
2346
|
+
:param int [params.userref]: the orders user reference id
|
|
2347
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
2001
2348
|
"""
|
|
2002
2349
|
self.load_markets()
|
|
2003
2350
|
response = None
|
|
2004
|
-
|
|
2351
|
+
requestId = self.safe_value(params, 'userref', id) # string or integer
|
|
2352
|
+
params = self.omit(params, 'userref')
|
|
2005
2353
|
request: dict = {
|
|
2006
|
-
'txid':
|
|
2354
|
+
'txid': requestId, # order id or userref
|
|
2007
2355
|
}
|
|
2008
|
-
|
|
2356
|
+
clientOrderId = self.safe_string_2(params, 'clientOrderId', 'cl_ord_id')
|
|
2357
|
+
if clientOrderId is not None:
|
|
2358
|
+
request['cl_ord_id'] = clientOrderId
|
|
2359
|
+
params = self.omit(params, ['clientOrderId', 'cl_ord_id'])
|
|
2360
|
+
request = self.omit(request, 'txid')
|
|
2009
2361
|
try:
|
|
2010
2362
|
response = self.privatePostCancelOrder(self.extend(request, params))
|
|
2011
2363
|
#
|
|
@@ -2028,7 +2380,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2028
2380
|
def cancel_orders(self, ids, symbol: Str = None, params={}):
|
|
2029
2381
|
"""
|
|
2030
2382
|
cancel multiple orders
|
|
2031
|
-
|
|
2383
|
+
|
|
2384
|
+
https://docs.kraken.com/rest/#tag/Spot-Trading/operation/cancelOrderBatch
|
|
2385
|
+
|
|
2032
2386
|
:param str[] ids: open orders transaction ID(txid) or user reference(userref)
|
|
2033
2387
|
:param str symbol: unified market symbol
|
|
2034
2388
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -2055,7 +2409,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2055
2409
|
def cancel_all_orders(self, symbol: Str = None, params={}):
|
|
2056
2410
|
"""
|
|
2057
2411
|
cancel all open orders
|
|
2058
|
-
|
|
2412
|
+
|
|
2413
|
+
https://docs.kraken.com/rest/#tag/Spot-Trading/operation/cancelAllOrders
|
|
2414
|
+
|
|
2059
2415
|
:param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
|
|
2060
2416
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2061
2417
|
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
@@ -2079,13 +2435,15 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2079
2435
|
def cancel_all_orders_after(self, timeout: Int, params={}):
|
|
2080
2436
|
"""
|
|
2081
2437
|
dead man's switch, cancel all orders after the given timeout
|
|
2082
|
-
|
|
2438
|
+
|
|
2439
|
+
https://docs.kraken.com/rest/#tag/Spot-Trading/operation/cancelAllOrdersAfter
|
|
2440
|
+
|
|
2083
2441
|
:param number timeout: time in milliseconds, 0 represents cancel the timer
|
|
2084
2442
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2085
2443
|
:returns dict: the api result
|
|
2086
2444
|
"""
|
|
2087
2445
|
if timeout > 86400000:
|
|
2088
|
-
raise BadRequest(self.id + 'cancelAllOrdersAfter timeout should be less than 86400000 milliseconds')
|
|
2446
|
+
raise BadRequest(self.id + ' cancelAllOrdersAfter timeout should be less than 86400000 milliseconds')
|
|
2089
2447
|
self.load_markets()
|
|
2090
2448
|
request: dict = {
|
|
2091
2449
|
'timeout': (self.parse_to_int(timeout / 1000)) if (timeout > 0) else 0,
|
|
@@ -2105,52 +2463,109 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2105
2463
|
def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
2106
2464
|
"""
|
|
2107
2465
|
fetch all unfilled currently open orders
|
|
2108
|
-
|
|
2109
|
-
|
|
2466
|
+
|
|
2467
|
+
https://docs.kraken.com/api/docs/rest-api/get-open-orders
|
|
2468
|
+
|
|
2469
|
+
:param str [symbol]: unified market symbol
|
|
2110
2470
|
:param int [since]: the earliest time in ms to fetch open orders for
|
|
2111
2471
|
:param int [limit]: the maximum number of open orders structures to retrieve
|
|
2112
2472
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2473
|
+
:param str [params.clientOrderId]: the orders client order id
|
|
2474
|
+
:param int [params.userref]: the orders user reference id
|
|
2113
2475
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
2114
2476
|
"""
|
|
2115
2477
|
self.load_markets()
|
|
2116
2478
|
request: dict = {}
|
|
2117
2479
|
if since is not None:
|
|
2118
2480
|
request['start'] = self.parse_to_int(since / 1000)
|
|
2119
|
-
|
|
2120
|
-
|
|
2481
|
+
userref = self.safe_integer(params, 'userref')
|
|
2482
|
+
if userref is not None:
|
|
2483
|
+
request['userref'] = userref
|
|
2484
|
+
params = self.omit(params, 'userref')
|
|
2485
|
+
clientOrderId = self.safe_string(params, 'clientOrderId')
|
|
2121
2486
|
if clientOrderId is not None:
|
|
2122
|
-
request['
|
|
2123
|
-
|
|
2124
|
-
response = self.privatePostOpenOrders(self.extend(request,
|
|
2487
|
+
request['cl_ord_id'] = clientOrderId
|
|
2488
|
+
params = self.omit(params, 'clientOrderId')
|
|
2489
|
+
response = self.privatePostOpenOrders(self.extend(request, params))
|
|
2490
|
+
#
|
|
2491
|
+
# {
|
|
2492
|
+
# "error": [],
|
|
2493
|
+
# "result": {
|
|
2494
|
+
# "open": {
|
|
2495
|
+
# "O45M52-BFD5S-YXKQOU": {
|
|
2496
|
+
# "refid": null,
|
|
2497
|
+
# "userref": null,
|
|
2498
|
+
# "cl_ord_id": "1234",
|
|
2499
|
+
# "status": "open",
|
|
2500
|
+
# "opentm": 1733815269.370054,
|
|
2501
|
+
# "starttm": 0,
|
|
2502
|
+
# "expiretm": 0,
|
|
2503
|
+
# "descr": {
|
|
2504
|
+
# "pair": "XBTUSD",
|
|
2505
|
+
# "type": "buy",
|
|
2506
|
+
# "ordertype": "limit",
|
|
2507
|
+
# "price": "70000.0",
|
|
2508
|
+
# "price2": "0",
|
|
2509
|
+
# "leverage": "none",
|
|
2510
|
+
# "order": "buy 0.00010000 XBTUSD @ limit 70000.0",
|
|
2511
|
+
# "close": ""
|
|
2512
|
+
# },
|
|
2513
|
+
# "vol": "0.00010000",
|
|
2514
|
+
# "vol_exec": "0.00000000",
|
|
2515
|
+
# "cost": "0.00000",
|
|
2516
|
+
# "fee": "0.00000",
|
|
2517
|
+
# "price": "0.00000",
|
|
2518
|
+
# "stopprice": "0.00000",
|
|
2519
|
+
# "limitprice": "0.00000",
|
|
2520
|
+
# "misc": "",
|
|
2521
|
+
# "oflags": "fciq"
|
|
2522
|
+
# }
|
|
2523
|
+
# }
|
|
2524
|
+
# }
|
|
2525
|
+
# }
|
|
2526
|
+
#
|
|
2125
2527
|
market = None
|
|
2126
2528
|
if symbol is not None:
|
|
2127
2529
|
market = self.market(symbol)
|
|
2128
2530
|
result = self.safe_dict(response, 'result', {})
|
|
2129
|
-
|
|
2531
|
+
open = self.safe_dict(result, 'open', {})
|
|
2532
|
+
orders = []
|
|
2533
|
+
orderIds = list(open.keys())
|
|
2534
|
+
for i in range(0, len(orderIds)):
|
|
2535
|
+
id = orderIds[i]
|
|
2536
|
+
item = open[id]
|
|
2537
|
+
orders.append(self.extend({'id': id}, item))
|
|
2130
2538
|
return self.parse_orders(orders, market, since, limit)
|
|
2131
2539
|
|
|
2132
2540
|
def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
2133
2541
|
"""
|
|
2134
2542
|
fetches information on multiple closed orders made by the user
|
|
2135
|
-
|
|
2136
|
-
|
|
2543
|
+
|
|
2544
|
+
https://docs.kraken.com/api/docs/rest-api/get-closed-orders
|
|
2545
|
+
|
|
2546
|
+
:param str [symbol]: unified market symbol of the market orders were made in
|
|
2137
2547
|
:param int [since]: the earliest time in ms to fetch orders for
|
|
2138
2548
|
:param int [limit]: the maximum number of order structures to retrieve
|
|
2139
2549
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2140
2550
|
:param int [params.until]: timestamp in ms of the latest entry
|
|
2551
|
+
:param str [params.clientOrderId]: the orders client order id
|
|
2552
|
+
:param int [params.userref]: the orders user reference id
|
|
2141
2553
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
2142
2554
|
"""
|
|
2143
2555
|
self.load_markets()
|
|
2144
2556
|
request: dict = {}
|
|
2145
2557
|
if since is not None:
|
|
2146
2558
|
request['start'] = self.parse_to_int(since / 1000)
|
|
2147
|
-
|
|
2148
|
-
|
|
2559
|
+
userref = self.safe_integer(params, 'userref')
|
|
2560
|
+
if userref is not None:
|
|
2561
|
+
request['userref'] = userref
|
|
2562
|
+
params = self.omit(params, 'userref')
|
|
2563
|
+
clientOrderId = self.safe_string(params, 'clientOrderId')
|
|
2149
2564
|
if clientOrderId is not None:
|
|
2150
|
-
request['
|
|
2151
|
-
|
|
2565
|
+
request['cl_ord_id'] = clientOrderId
|
|
2566
|
+
params = self.omit(params, 'clientOrderId')
|
|
2152
2567
|
request, params = self.handle_until_option('end', request, params)
|
|
2153
|
-
response = self.privatePostClosedOrders(self.extend(request,
|
|
2568
|
+
response = self.privatePostClosedOrders(self.extend(request, params))
|
|
2154
2569
|
#
|
|
2155
2570
|
# {
|
|
2156
2571
|
# "error":[],
|
|
@@ -2194,7 +2609,13 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2194
2609
|
if symbol is not None:
|
|
2195
2610
|
market = self.market(symbol)
|
|
2196
2611
|
result = self.safe_dict(response, 'result', {})
|
|
2197
|
-
|
|
2612
|
+
closed = self.safe_dict(result, 'closed', {})
|
|
2613
|
+
orders = []
|
|
2614
|
+
orderIds = list(closed.keys())
|
|
2615
|
+
for i in range(0, len(orderIds)):
|
|
2616
|
+
id = orderIds[i]
|
|
2617
|
+
item = closed[id]
|
|
2618
|
+
orders.append(self.extend({'id': id}, item))
|
|
2198
2619
|
return self.parse_orders(orders, market, since, limit)
|
|
2199
2620
|
|
|
2200
2621
|
def parse_transaction_status(self, status: Str):
|
|
@@ -2331,23 +2752,31 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2331
2752
|
def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
|
2332
2753
|
"""
|
|
2333
2754
|
fetch all deposits made to an account
|
|
2334
|
-
|
|
2755
|
+
|
|
2756
|
+
https://docs.kraken.com/rest/#tag/Funding/operation/getStatusRecentDeposits
|
|
2757
|
+
|
|
2335
2758
|
:param str code: unified currency code
|
|
2336
2759
|
:param int [since]: the earliest time in ms to fetch deposits for
|
|
2337
2760
|
:param int [limit]: the maximum number of deposits structures to retrieve
|
|
2338
2761
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2762
|
+
:param int [params.until]: timestamp in ms of the latest transaction entry
|
|
2763
|
+
:param int [params.end]: timestamp in seconds of the latest transaction entry
|
|
2339
2764
|
:returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
|
|
2340
2765
|
"""
|
|
2341
2766
|
# https://www.kraken.com/en-us/help/api#deposit-status
|
|
2342
|
-
if code is None:
|
|
2343
|
-
raise ArgumentsRequired(self.id + ' fetchDeposits() requires a currency code argument')
|
|
2344
2767
|
self.load_markets()
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2768
|
+
request: dict = {}
|
|
2769
|
+
if code is not None:
|
|
2770
|
+
currency = self.currency(code)
|
|
2771
|
+
request['asset'] = currency['id']
|
|
2349
2772
|
if since is not None:
|
|
2350
|
-
|
|
2773
|
+
sinceString = self.number_to_string(since)
|
|
2774
|
+
request['start'] = Precise.string_div(sinceString, '1000')
|
|
2775
|
+
until = self.safe_string_n(params, ['until', 'till'])
|
|
2776
|
+
if until is not None:
|
|
2777
|
+
params = self.omit(params, ['until', 'till'])
|
|
2778
|
+
untilDivided = Precise.string_div(until, '1000')
|
|
2779
|
+
request['end'] = Precise.string_add(untilDivided, '1')
|
|
2351
2780
|
response = self.privatePostDepositStatus(self.extend(request, params))
|
|
2352
2781
|
#
|
|
2353
2782
|
# { error: [],
|
|
@@ -2364,10 +2793,12 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2364
2793
|
#
|
|
2365
2794
|
return self.parse_transactions_by_type('deposit', response['result'], code, since, limit)
|
|
2366
2795
|
|
|
2367
|
-
def fetch_time(self, params={}):
|
|
2796
|
+
def fetch_time(self, params={}) -> Int:
|
|
2368
2797
|
"""
|
|
2369
2798
|
fetches the current integer timestamp in milliseconds from the exchange server
|
|
2370
|
-
|
|
2799
|
+
|
|
2800
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getServerTime
|
|
2801
|
+
|
|
2371
2802
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2372
2803
|
:returns int: the current integer timestamp in milliseconds from the exchange server
|
|
2373
2804
|
"""
|
|
@@ -2388,13 +2819,16 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2388
2819
|
def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
|
2389
2820
|
"""
|
|
2390
2821
|
fetch all withdrawals made from an account
|
|
2391
|
-
|
|
2822
|
+
|
|
2823
|
+
https://docs.kraken.com/rest/#tag/Funding/operation/getStatusRecentWithdrawals
|
|
2824
|
+
|
|
2392
2825
|
:param str code: unified currency code
|
|
2393
2826
|
:param int [since]: the earliest time in ms to fetch withdrawals for
|
|
2394
2827
|
:param int [limit]: the maximum number of withdrawals structures to retrieve
|
|
2395
2828
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2396
|
-
:param
|
|
2397
|
-
:param
|
|
2829
|
+
:param int [params.until]: timestamp in ms of the latest transaction entry
|
|
2830
|
+
:param int [params.end]: timestamp in seconds of the latest transaction entry
|
|
2831
|
+
:param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times
|
|
2398
2832
|
:returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
|
|
2399
2833
|
"""
|
|
2400
2834
|
self.load_markets()
|
|
@@ -2408,7 +2842,13 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2408
2842
|
currency = self.currency(code)
|
|
2409
2843
|
request['asset'] = currency['id']
|
|
2410
2844
|
if since is not None:
|
|
2411
|
-
|
|
2845
|
+
sinceString = self.number_to_string(since)
|
|
2846
|
+
request['start'] = Precise.string_div(sinceString, '1000')
|
|
2847
|
+
until = self.safe_string_n(params, ['until', 'till'])
|
|
2848
|
+
if until is not None:
|
|
2849
|
+
params = self.omit(params, ['until', 'till'])
|
|
2850
|
+
untilDivided = Precise.string_div(until, '1000')
|
|
2851
|
+
request['end'] = Precise.string_add(untilDivided, '1')
|
|
2412
2852
|
response = self.privatePostWithdrawStatus(self.extend(request, params))
|
|
2413
2853
|
#
|
|
2414
2854
|
# with no pagination
|
|
@@ -2466,10 +2906,12 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2466
2906
|
data[dataLength - 1] = last
|
|
2467
2907
|
return data
|
|
2468
2908
|
|
|
2469
|
-
def create_deposit_address(self, code: str, params={}):
|
|
2909
|
+
def create_deposit_address(self, code: str, params={}) -> DepositAddress:
|
|
2470
2910
|
"""
|
|
2471
2911
|
create a currency deposit address
|
|
2472
|
-
|
|
2912
|
+
|
|
2913
|
+
https://docs.kraken.com/rest/#tag/Funding/operation/getDepositAddresses
|
|
2914
|
+
|
|
2473
2915
|
:param str code: unified currency code of the currency for the deposit address
|
|
2474
2916
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2475
2917
|
:returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
|
|
@@ -2482,7 +2924,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2482
2924
|
def fetch_deposit_methods(self, code: str, params={}):
|
|
2483
2925
|
"""
|
|
2484
2926
|
fetch deposit methods for a currency associated with self account
|
|
2485
|
-
|
|
2927
|
+
|
|
2928
|
+
https://docs.kraken.com/rest/#tag/Funding/operation/getDepositMethods
|
|
2929
|
+
|
|
2486
2930
|
:param str code: unified currency code
|
|
2487
2931
|
:param dict [params]: extra parameters specific to the kraken api endpoint
|
|
2488
2932
|
:returns dict: of deposit methods
|
|
@@ -2518,10 +2962,12 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2518
2962
|
#
|
|
2519
2963
|
return self.safe_value(response, 'result')
|
|
2520
2964
|
|
|
2521
|
-
def fetch_deposit_address(self, code: str, params={}):
|
|
2965
|
+
def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
|
|
2522
2966
|
"""
|
|
2523
2967
|
fetch the deposit address for a currency associated with self account
|
|
2524
|
-
|
|
2968
|
+
|
|
2969
|
+
https://docs.kraken.com/rest/#tag/Funding/operation/getDepositAddresses
|
|
2970
|
+
|
|
2525
2971
|
:param str code: unified currency code
|
|
2526
2972
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2527
2973
|
:returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
|
|
@@ -2571,7 +3017,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2571
3017
|
raise InvalidAddress(self.id + ' privatePostDepositAddresses() returned no addresses for ' + code)
|
|
2572
3018
|
return self.parse_deposit_address(firstResult, currency)
|
|
2573
3019
|
|
|
2574
|
-
def parse_deposit_address(self, depositAddress, currency: Currency = None):
|
|
3020
|
+
def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
|
|
2575
3021
|
#
|
|
2576
3022
|
# {
|
|
2577
3023
|
# "address":"0x77b5051f97efa9cc52c9ad5b023a53fc15c200d3",
|
|
@@ -2584,17 +3030,19 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2584
3030
|
code = currency['code']
|
|
2585
3031
|
self.check_address(address)
|
|
2586
3032
|
return {
|
|
3033
|
+
'info': depositAddress,
|
|
2587
3034
|
'currency': code,
|
|
3035
|
+
'network': None,
|
|
2588
3036
|
'address': address,
|
|
2589
3037
|
'tag': tag,
|
|
2590
|
-
'network': None,
|
|
2591
|
-
'info': depositAddress,
|
|
2592
3038
|
}
|
|
2593
3039
|
|
|
2594
|
-
def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
|
|
3040
|
+
def withdraw(self, code: str, amount: float, address: str, tag: Str = None, params={}) -> Transaction:
|
|
2595
3041
|
"""
|
|
2596
3042
|
make a withdrawal
|
|
2597
|
-
|
|
3043
|
+
|
|
3044
|
+
https://docs.kraken.com/rest/#tag/Funding/operation/withdrawFunds
|
|
3045
|
+
|
|
2598
3046
|
:param str code: unified currency code
|
|
2599
3047
|
:param float amount: the amount to withdraw
|
|
2600
3048
|
:param str address: the address to withdraw to
|
|
@@ -2625,10 +3073,12 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2625
3073
|
return self.parse_transaction(result, currency)
|
|
2626
3074
|
raise ExchangeError(self.id + " withdraw() requires a 'key' parameter(withdrawal key name, up on your account)")
|
|
2627
3075
|
|
|
2628
|
-
def fetch_positions(self, symbols: Strings = None, params={}):
|
|
3076
|
+
def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
|
|
2629
3077
|
"""
|
|
2630
3078
|
fetch all open positions
|
|
2631
|
-
|
|
3079
|
+
|
|
3080
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getOpenPositions
|
|
3081
|
+
|
|
2632
3082
|
:param str[] [symbols]: not used by kraken fetchPositions()
|
|
2633
3083
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2634
3084
|
:returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
|
@@ -2749,7 +3199,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2749
3199
|
def transfer_out(self, code: str, amount, params={}):
|
|
2750
3200
|
"""
|
|
2751
3201
|
transfer from spot wallet to futures wallet
|
|
2752
|
-
|
|
3202
|
+
|
|
3203
|
+
https://docs.kraken.com/rest/#tag/User-Funding/operation/walletTransfer
|
|
3204
|
+
|
|
2753
3205
|
:param str code: Unified currency code
|
|
2754
3206
|
:param float amount: Size of the transfer
|
|
2755
3207
|
:param dict [params]: Exchange specific parameters
|
|
@@ -2759,7 +3211,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2759
3211
|
|
|
2760
3212
|
def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
|
2761
3213
|
"""
|
|
2762
|
-
|
|
3214
|
+
|
|
3215
|
+
https://docs.kraken.com/rest/#tag/User-Funding/operation/walletTransfer
|
|
3216
|
+
|
|
2763
3217
|
transfers currencies between sub-accounts(only spot->swap direction is supported)
|
|
2764
3218
|
:param str code: Unified currency code
|
|
2765
3219
|
:param float amount: Size of the transfer
|
|
@@ -2830,11 +3284,15 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2830
3284
|
# urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
|
|
2831
3285
|
url += '?' + self.urlencode_nested(params)
|
|
2832
3286
|
elif api == 'private':
|
|
3287
|
+
price = self.safe_string(params, 'price')
|
|
3288
|
+
isTriggerPercent = False
|
|
3289
|
+
if price is not None:
|
|
3290
|
+
isTriggerPercent = True if (price.endswith('%')) else False
|
|
2833
3291
|
isCancelOrderBatch = (path == 'CancelOrderBatch')
|
|
2834
3292
|
self.check_required_credentials()
|
|
2835
3293
|
nonce = str(self.nonce())
|
|
2836
3294
|
# urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
|
|
2837
|
-
if isCancelOrderBatch:
|
|
3295
|
+
if isCancelOrderBatch or isTriggerPercent:
|
|
2838
3296
|
body = self.json(self.extend({'nonce': nonce}, params))
|
|
2839
3297
|
else:
|
|
2840
3298
|
body = self.urlencode_nested(self.extend({'nonce': nonce}, params))
|
|
@@ -2847,9 +3305,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2847
3305
|
headers = {
|
|
2848
3306
|
'API-Key': self.apiKey,
|
|
2849
3307
|
'API-Sign': signature,
|
|
2850
|
-
# 'Content-Type': 'application/x-www-form-urlencoded',
|
|
2851
3308
|
}
|
|
2852
|
-
if isCancelOrderBatch:
|
|
3309
|
+
if isCancelOrderBatch or isTriggerPercent:
|
|
2853
3310
|
headers['Content-Type'] = 'application/json'
|
|
2854
3311
|
else:
|
|
2855
3312
|
headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
|
@@ -2859,26 +3316,11 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2859
3316
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
|
2860
3317
|
|
|
2861
3318
|
def nonce(self):
|
|
2862
|
-
return self.milliseconds()
|
|
3319
|
+
return self.milliseconds() - self.options['timeDifference']
|
|
2863
3320
|
|
|
2864
3321
|
def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
|
2865
3322
|
if code == 520:
|
|
2866
3323
|
raise ExchangeNotAvailable(self.id + ' ' + str(code) + ' ' + reason)
|
|
2867
|
-
# todo: rewrite self for "broad" exceptions matching
|
|
2868
|
-
if body.find('Invalid order') >= 0:
|
|
2869
|
-
raise InvalidOrder(self.id + ' ' + body)
|
|
2870
|
-
if body.find('Invalid nonce') >= 0:
|
|
2871
|
-
raise InvalidNonce(self.id + ' ' + body)
|
|
2872
|
-
if body.find('Insufficient funds') >= 0:
|
|
2873
|
-
raise InsufficientFunds(self.id + ' ' + body)
|
|
2874
|
-
if body.find('Cancel pending') >= 0:
|
|
2875
|
-
raise CancelPending(self.id + ' ' + body)
|
|
2876
|
-
if body.find('Invalid arguments:volume') >= 0:
|
|
2877
|
-
raise InvalidOrder(self.id + ' ' + body)
|
|
2878
|
-
if body.find('Invalid arguments:viqc') >= 0:
|
|
2879
|
-
raise InvalidOrder(self.id + ' ' + body)
|
|
2880
|
-
if body.find('Rate limit exceeded') >= 0:
|
|
2881
|
-
raise RateLimitExceeded(self.id + ' ' + body)
|
|
2882
3324
|
if response is None:
|
|
2883
3325
|
return None
|
|
2884
3326
|
if body[0] == '{':
|
|
@@ -2889,6 +3331,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
|
2889
3331
|
message = self.id + ' ' + body
|
|
2890
3332
|
for i in range(0, len(response['error'])):
|
|
2891
3333
|
error = response['error'][i]
|
|
2892
|
-
self.throw_exactly_matched_exception(self.exceptions, error, message)
|
|
3334
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], error, message)
|
|
3335
|
+
self.throw_broadly_matched_exception(self.exceptions['broad'], error, message)
|
|
2893
3336
|
raise ExchangeError(message)
|
|
2894
3337
|
return None
|