ccxt 4.2.76__py2.py3-none-any.whl → 4.4.48__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 +36 -14
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +112 -48
- ccxt/abstract/binancecoinm.py +112 -48
- ccxt/abstract/binanceus.py +147 -83
- ccxt/abstract/binanceusdm.py +112 -48
- ccxt/abstract/bingx.py +133 -78
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitfinex1.py +69 -0
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +8 -1
- ccxt/abstract/bitmart.py +13 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitpanda.py +0 -12
- ccxt/abstract/bitrue.py +3 -3
- ccxt/abstract/bitstamp.py +26 -3
- ccxt/abstract/blofin.py +24 -0
- ccxt/abstract/btcbox.py +1 -0
- ccxt/abstract/bybit.py +29 -14
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbase.py +6 -0
- ccxt/abstract/coinbaseadvanced.py +94 -0
- ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/coincatch.py +94 -0
- ccxt/abstract/coinex.py +233 -123
- ccxt/abstract/coinmetro.py +1 -0
- ccxt/abstract/cryptocom.py +14 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/gate.py +20 -0
- ccxt/abstract/gateio.py +20 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hashkey.py +67 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +4 -3
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +25 -0
- ccxt/abstract/kucoinfutures.py +35 -0
- ccxt/abstract/luno.py +2 -0
- ccxt/abstract/mexc.py +4 -0
- ccxt/abstract/myokx.py +340 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +30 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/oxfun.py +34 -0
- ccxt/abstract/paradex.py +40 -0
- ccxt/abstract/phemex.py +1 -0
- ccxt/abstract/upbit.py +4 -0
- ccxt/abstract/vertex.py +19 -0
- ccxt/abstract/whitebit.py +31 -1
- ccxt/abstract/woo.py +6 -2
- ccxt/abstract/woofipro.py +119 -0
- ccxt/abstract/xt.py +153 -0
- ccxt/abstract/zonda.py +6 -0
- ccxt/ace.py +164 -60
- ccxt/alpaca.py +727 -63
- ccxt/ascendex.py +395 -249
- ccxt/async_support/__init__.py +36 -14
- ccxt/async_support/ace.py +164 -60
- ccxt/async_support/alpaca.py +727 -63
- ccxt/async_support/ascendex.py +396 -249
- ccxt/async_support/base/exchange.py +531 -155
- ccxt/async_support/base/ws/aiohttp_client.py +28 -5
- ccxt/async_support/base/ws/cache.py +3 -2
- ccxt/async_support/base/ws/client.py +26 -5
- ccxt/async_support/base/ws/fast_client.py +4 -3
- ccxt/async_support/base/ws/functions.py +1 -1
- ccxt/async_support/base/ws/future.py +40 -31
- ccxt/async_support/base/ws/order_book_side.py +3 -0
- ccxt/async_support/bequant.py +1 -1
- ccxt/async_support/bigone.py +329 -202
- ccxt/async_support/binance.py +3513 -1511
- ccxt/async_support/binancecoinm.py +2 -1
- ccxt/async_support/binanceus.py +12 -1
- ccxt/async_support/binanceusdm.py +3 -1
- ccxt/async_support/bingx.py +3105 -881
- ccxt/async_support/bit2c.py +119 -38
- ccxt/async_support/bitbank.py +215 -76
- ccxt/async_support/bitbns.py +124 -53
- ccxt/async_support/bitfinex.py +3236 -1078
- ccxt/async_support/bitfinex1.py +1711 -0
- ccxt/async_support/bitflyer.py +239 -50
- ccxt/async_support/bitget.py +1513 -563
- ccxt/async_support/bithumb.py +201 -67
- ccxt/async_support/bitmart.py +1320 -435
- ccxt/async_support/bitmex.py +308 -111
- ccxt/async_support/bitopro.py +256 -96
- ccxt/async_support/bitrue.py +365 -233
- ccxt/async_support/bitso.py +201 -89
- ccxt/async_support/bitstamp.py +438 -269
- ccxt/async_support/bitteam.py +179 -73
- ccxt/async_support/bitvavo.py +180 -70
- ccxt/async_support/bl3p.py +92 -25
- ccxt/async_support/blockchaincom.py +193 -79
- ccxt/async_support/blofin.py +403 -150
- ccxt/async_support/btcalpha.py +161 -55
- ccxt/async_support/btcbox.py +250 -34
- ccxt/async_support/btcmarkets.py +232 -85
- ccxt/async_support/btcturk.py +159 -60
- ccxt/async_support/bybit.py +2326 -1255
- ccxt/async_support/cex.py +1409 -1329
- ccxt/async_support/coinbase.py +1455 -288
- ccxt/async_support/coinbaseadvanced.py +17 -0
- ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/async_support/coinbaseinternational.py +428 -88
- ccxt/async_support/coincatch.py +5152 -0
- ccxt/async_support/coincheck.py +121 -38
- ccxt/async_support/coinex.py +4020 -3339
- ccxt/async_support/coinlist.py +273 -116
- ccxt/async_support/coinmate.py +204 -97
- ccxt/async_support/coinmetro.py +203 -110
- ccxt/async_support/coinone.py +142 -68
- ccxt/async_support/coinsph.py +206 -89
- ccxt/async_support/coinspot.py +137 -62
- ccxt/async_support/cryptocom.py +515 -185
- ccxt/async_support/currencycom.py +203 -85
- ccxt/async_support/defx.py +2066 -0
- ccxt/async_support/delta.py +467 -158
- ccxt/async_support/deribit.py +558 -324
- ccxt/async_support/digifinex.py +340 -223
- ccxt/async_support/ellipx.py +1826 -0
- ccxt/async_support/exmo.py +259 -128
- ccxt/async_support/gate.py +1473 -464
- ccxt/async_support/gemini.py +206 -84
- ccxt/async_support/hashkey.py +4164 -0
- ccxt/async_support/hitbtc.py +334 -178
- ccxt/async_support/hollaex.py +134 -83
- ccxt/async_support/htx.py +1095 -563
- ccxt/async_support/huobijp.py +105 -56
- ccxt/async_support/hyperliquid.py +1634 -269
- ccxt/async_support/idex.py +148 -95
- ccxt/async_support/independentreserve.py +236 -31
- ccxt/async_support/indodax.py +165 -62
- ccxt/async_support/kraken.py +871 -354
- ccxt/async_support/krakenfutures.py +324 -100
- ccxt/async_support/kucoin.py +1050 -355
- ccxt/async_support/kucoinfutures.py +1004 -149
- ccxt/async_support/kuna.py +138 -106
- ccxt/async_support/latoken.py +135 -79
- ccxt/async_support/lbank.py +290 -113
- ccxt/async_support/luno.py +112 -62
- ccxt/async_support/lykke.py +104 -55
- ccxt/async_support/mercado.py +36 -29
- ccxt/async_support/mexc.py +995 -429
- ccxt/async_support/myokx.py +43 -0
- ccxt/async_support/ndax.py +163 -82
- ccxt/async_support/novadax.py +121 -75
- ccxt/async_support/oceanex.py +175 -59
- ccxt/async_support/okcoin.py +222 -163
- ccxt/async_support/okx.py +1777 -455
- ccxt/async_support/onetrading.py +132 -414
- ccxt/async_support/oxfun.py +2832 -0
- ccxt/async_support/p2b.py +79 -51
- ccxt/async_support/paradex.py +2017 -0
- ccxt/async_support/paymium.py +56 -32
- ccxt/async_support/phemex.py +572 -196
- ccxt/async_support/poloniex.py +218 -95
- ccxt/async_support/poloniexfutures.py +260 -92
- ccxt/async_support/probit.py +143 -110
- ccxt/async_support/timex.py +123 -70
- ccxt/async_support/tokocrypto.py +129 -93
- ccxt/async_support/tradeogre.py +39 -25
- ccxt/async_support/upbit.py +322 -113
- ccxt/async_support/vertex.py +2983 -0
- ccxt/async_support/wavesexchange.py +227 -173
- ccxt/async_support/wazirx.py +145 -65
- ccxt/async_support/whitebit.py +533 -138
- ccxt/async_support/woo.py +1155 -295
- ccxt/async_support/woofipro.py +2716 -0
- ccxt/async_support/xt.py +4628 -0
- ccxt/async_support/yobit.py +160 -92
- ccxt/async_support/zaif.py +80 -33
- ccxt/async_support/zonda.py +140 -69
- ccxt/base/errors.py +51 -20
- ccxt/base/exchange.py +1729 -482
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +223 -4
- ccxt/bequant.py +1 -1
- ccxt/bigone.py +329 -202
- ccxt/binance.py +3513 -1511
- ccxt/binancecoinm.py +2 -1
- ccxt/binanceus.py +12 -1
- ccxt/binanceusdm.py +3 -1
- ccxt/bingx.py +3105 -881
- ccxt/bit2c.py +119 -38
- ccxt/bitbank.py +215 -76
- ccxt/bitbns.py +124 -53
- ccxt/bitfinex.py +3235 -1078
- ccxt/bitfinex1.py +1710 -0
- ccxt/bitflyer.py +239 -50
- ccxt/bitget.py +1513 -563
- ccxt/bithumb.py +200 -67
- ccxt/bitmart.py +1320 -435
- ccxt/bitmex.py +308 -111
- ccxt/bitopro.py +256 -96
- ccxt/bitrue.py +365 -233
- ccxt/bitso.py +201 -89
- ccxt/bitstamp.py +438 -269
- ccxt/bitteam.py +179 -73
- ccxt/bitvavo.py +180 -70
- ccxt/bl3p.py +92 -25
- ccxt/blockchaincom.py +193 -79
- ccxt/blofin.py +403 -150
- ccxt/btcalpha.py +161 -55
- ccxt/btcbox.py +250 -34
- ccxt/btcmarkets.py +232 -85
- ccxt/btcturk.py +159 -60
- ccxt/bybit.py +2326 -1255
- ccxt/cex.py +1408 -1329
- ccxt/coinbase.py +1455 -288
- ccxt/coinbaseadvanced.py +17 -0
- ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/coinbaseinternational.py +428 -88
- ccxt/coincatch.py +5152 -0
- ccxt/coincheck.py +121 -38
- ccxt/coinex.py +4020 -3339
- ccxt/coinlist.py +273 -116
- ccxt/coinmate.py +204 -97
- ccxt/coinmetro.py +203 -110
- ccxt/coinone.py +142 -68
- ccxt/coinsph.py +206 -89
- ccxt/coinspot.py +137 -62
- ccxt/cryptocom.py +515 -185
- ccxt/currencycom.py +203 -85
- ccxt/defx.py +2065 -0
- ccxt/delta.py +467 -158
- ccxt/deribit.py +558 -324
- ccxt/digifinex.py +340 -223
- ccxt/ellipx.py +1826 -0
- ccxt/exmo.py +259 -128
- ccxt/gate.py +1473 -464
- ccxt/gemini.py +206 -84
- ccxt/hashkey.py +4164 -0
- ccxt/hitbtc.py +334 -178
- ccxt/hollaex.py +134 -83
- ccxt/htx.py +1095 -563
- ccxt/huobijp.py +105 -56
- ccxt/hyperliquid.py +1633 -269
- ccxt/idex.py +148 -95
- ccxt/independentreserve.py +235 -31
- ccxt/indodax.py +165 -62
- ccxt/kraken.py +871 -354
- ccxt/krakenfutures.py +324 -100
- ccxt/kucoin.py +1050 -355
- ccxt/kucoinfutures.py +1004 -149
- ccxt/kuna.py +138 -106
- ccxt/latoken.py +135 -79
- ccxt/lbank.py +290 -113
- ccxt/luno.py +112 -62
- ccxt/lykke.py +104 -55
- ccxt/mercado.py +36 -29
- ccxt/mexc.py +994 -429
- ccxt/myokx.py +43 -0
- ccxt/ndax.py +163 -82
- ccxt/novadax.py +121 -75
- ccxt/oceanex.py +175 -59
- ccxt/okcoin.py +222 -163
- ccxt/okx.py +1777 -455
- ccxt/onetrading.py +132 -414
- ccxt/oxfun.py +2831 -0
- ccxt/p2b.py +79 -51
- ccxt/paradex.py +2017 -0
- ccxt/paymium.py +56 -32
- ccxt/phemex.py +572 -196
- ccxt/poloniex.py +218 -95
- ccxt/poloniexfutures.py +260 -92
- ccxt/pro/__init__.py +29 -5
- ccxt/pro/alpaca.py +32 -17
- ccxt/pro/ascendex.py +63 -15
- ccxt/pro/bequant.py +4 -0
- ccxt/pro/binance.py +1596 -329
- ccxt/pro/binancecoinm.py +1 -0
- ccxt/pro/binanceus.py +2 -9
- ccxt/pro/binanceusdm.py +2 -0
- ccxt/pro/bingx.py +527 -134
- ccxt/pro/bitcoincom.py +4 -1
- ccxt/pro/bitfinex.py +731 -266
- ccxt/pro/bitfinex1.py +635 -0
- ccxt/pro/bitget.py +726 -357
- ccxt/pro/bithumb.py +380 -0
- ccxt/pro/bitmart.py +138 -39
- ccxt/pro/bitmex.py +199 -40
- ccxt/pro/bitopro.py +25 -13
- ccxt/pro/bitrue.py +31 -32
- ccxt/pro/bitstamp.py +7 -6
- ccxt/pro/bitvavo.py +204 -82
- ccxt/pro/blockchaincom.py +30 -17
- ccxt/pro/blofin.py +692 -0
- ccxt/pro/bybit.py +791 -82
- ccxt/pro/cex.py +99 -51
- ccxt/pro/coinbase.py +220 -30
- ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
- ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
- ccxt/pro/coinbaseinternational.py +193 -30
- ccxt/pro/coincatch.py +1464 -0
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +967 -661
- ccxt/pro/coinone.py +17 -10
- ccxt/pro/cryptocom.py +446 -66
- ccxt/pro/currencycom.py +11 -10
- ccxt/pro/defx.py +832 -0
- ccxt/pro/deribit.py +168 -32
- ccxt/pro/exmo.py +253 -21
- ccxt/pro/gate.py +729 -64
- ccxt/pro/gemini.py +44 -26
- ccxt/pro/hashkey.py +802 -0
- ccxt/pro/hitbtc.py +208 -103
- ccxt/pro/hollaex.py +25 -9
- ccxt/pro/htx.py +83 -39
- ccxt/pro/huobijp.py +17 -16
- ccxt/pro/hyperliquid.py +502 -31
- ccxt/pro/idex.py +28 -13
- ccxt/pro/independentreserve.py +21 -16
- ccxt/pro/kraken.py +298 -51
- ccxt/pro/krakenfutures.py +166 -75
- ccxt/pro/kucoin.py +395 -77
- ccxt/pro/kucoinfutures.py +400 -99
- ccxt/pro/lbank.py +52 -31
- ccxt/pro/luno.py +12 -10
- ccxt/pro/mexc.py +400 -50
- ccxt/pro/myokx.py +28 -0
- ccxt/pro/ndax.py +25 -12
- ccxt/pro/okcoin.py +28 -9
- ccxt/pro/okx.py +935 -124
- ccxt/pro/onetrading.py +41 -24
- ccxt/pro/oxfun.py +1054 -0
- ccxt/pro/p2b.py +100 -24
- ccxt/pro/paradex.py +352 -0
- ccxt/pro/phemex.py +93 -34
- ccxt/pro/poloniex.py +129 -50
- ccxt/pro/poloniexfutures.py +53 -32
- ccxt/pro/probit.py +93 -86
- ccxt/pro/upbit.py +401 -8
- ccxt/pro/vertex.py +943 -0
- ccxt/pro/wazirx.py +46 -28
- ccxt/pro/whitebit.py +65 -12
- ccxt/pro/woo.py +486 -70
- ccxt/pro/woofipro.py +1271 -0
- ccxt/pro/xt.py +1067 -0
- ccxt/probit.py +143 -110
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/__init__.py +38 -0
- ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
- ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
- ccxt/static_dependencies/lark/ast_utils.py +59 -0
- ccxt/static_dependencies/lark/common.py +86 -0
- ccxt/static_dependencies/lark/exceptions.py +292 -0
- ccxt/static_dependencies/lark/grammar.py +130 -0
- ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
- ccxt/static_dependencies/lark/indenter.py +143 -0
- ccxt/static_dependencies/lark/lark.py +658 -0
- ccxt/static_dependencies/lark/lexer.py +678 -0
- ccxt/static_dependencies/lark/load_grammar.py +1428 -0
- ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
- ccxt/static_dependencies/lark/parser_frontends.py +257 -0
- ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
- ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
- ccxt/static_dependencies/lark/parsers/earley.py +314 -0
- ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
- ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
- ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
- ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
- ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
- ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/lark/reconstruct.py +107 -0
- ccxt/static_dependencies/lark/tools/__init__.py +70 -0
- ccxt/static_dependencies/lark/tools/nearley.py +202 -0
- ccxt/static_dependencies/lark/tools/serialize.py +32 -0
- ccxt/static_dependencies/lark/tools/standalone.py +196 -0
- ccxt/static_dependencies/lark/tree.py +267 -0
- ccxt/static_dependencies/lark/tree_matcher.py +186 -0
- ccxt/static_dependencies/lark/tree_templates.py +180 -0
- ccxt/static_dependencies/lark/utils.py +343 -0
- ccxt/static_dependencies/lark/visitors.py +596 -0
- ccxt/static_dependencies/marshmallow/__init__.py +81 -0
- ccxt/static_dependencies/marshmallow/base.py +65 -0
- ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
- ccxt/static_dependencies/marshmallow/decorators.py +231 -0
- ccxt/static_dependencies/marshmallow/error_store.py +60 -0
- ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
- ccxt/static_dependencies/marshmallow/fields.py +2114 -0
- ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/schema.py +1228 -0
- ccxt/static_dependencies/marshmallow/types.py +12 -0
- ccxt/static_dependencies/marshmallow/utils.py +378 -0
- ccxt/static_dependencies/marshmallow/validate.py +678 -0
- ccxt/static_dependencies/marshmallow/warnings.py +2 -0
- ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
- ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
- ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
- ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
- ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
- ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
- ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/static_dependencies/starknet/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
- ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
- ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
- ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
- ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
- ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
- ccxt/static_dependencies/starknet/common.py +15 -0
- ccxt/static_dependencies/starknet/constants.py +39 -0
- ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
- ccxt/static_dependencies/starknet/hash/address.py +79 -0
- ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
- ccxt/static_dependencies/starknet/hash/selector.py +16 -0
- ccxt/static_dependencies/starknet/hash/storage.py +12 -0
- ccxt/static_dependencies/starknet/hash/utils.py +78 -0
- ccxt/static_dependencies/starknet/models/__init__.py +0 -0
- ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
- ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
- ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
- ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
- ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
- ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
- ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
- ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
- ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
- ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
- ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
- ccxt/static_dependencies/starknet/utils/schema.py +13 -0
- ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
- ccxt/static_dependencies/starkware/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
- ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
- ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
- ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
- ccxt/static_dependencies/sympy/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
- ccxt/static_dependencies/sympy/external/__init__.py +0 -0
- ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
- ccxt/static_dependencies/sympy/external/importtools.py +187 -0
- ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
- ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
- ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
- ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
- ccxt/test/{test_async.py → tests_async.py} +465 -407
- ccxt/test/tests_helpers.py +285 -0
- ccxt/test/tests_init.py +39 -0
- ccxt/test/{test_sync.py → tests_sync.py} +465 -409
- ccxt/timex.py +123 -70
- ccxt/tokocrypto.py +129 -93
- ccxt/tradeogre.py +39 -25
- ccxt/upbit.py +322 -113
- ccxt/vertex.py +2983 -0
- ccxt/wavesexchange.py +227 -173
- ccxt/wazirx.py +145 -65
- ccxt/whitebit.py +533 -138
- ccxt/woo.py +1155 -295
- ccxt/woofipro.py +2716 -0
- ccxt/xt.py +4627 -0
- ccxt/yobit.py +159 -92
- ccxt/zaif.py +80 -33
- ccxt/zonda.py +140 -69
- ccxt-4.4.48.dist-info/LICENSE.txt +21 -0
- ccxt-4.4.48.dist-info/METADATA +646 -0
- ccxt-4.4.48.dist-info/RECORD +669 -0
- {ccxt-4.2.76.dist-info → ccxt-4.4.48.dist-info}/WHEEL +1 -1
- ccxt/abstract/bitbay.py +0 -47
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3496
- ccxt/async_support/flowbtc.py +0 -34
- ccxt/bitbay.py +0 -17
- ccxt/bitfinex2.py +0 -3496
- ccxt/flowbtc.py +0 -34
- ccxt/hitbtc3.py +0 -16
- ccxt/pro/bitfinex2.py +0 -1081
- ccxt/test/base/__init__.py +0 -28
- 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 -103
- 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 -32
- 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_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -190
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -32
- 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 -63
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -345
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -86
- 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-4.2.76.dist-info/METADATA +0 -626
- ccxt-4.2.76.dist-info/RECORD +0 -534
- {ccxt-4.2.76.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
ccxt/kraken.py
CHANGED
@@ -6,9 +6,10 @@
|
|
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, Currency, IndexType, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
9
|
+
from ccxt.base.types import Balances, Currencies, Currency, DepositAddress, IndexType, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
|
+
from ccxt.base.errors import AuthenticationError
|
12
13
|
from ccxt.base.errors import PermissionDenied
|
13
14
|
from ccxt.base.errors import AccountSuspended
|
14
15
|
from ccxt.base.errors import ArgumentsRequired
|
@@ -18,14 +19,13 @@ from ccxt.base.errors import InsufficientFunds
|
|
18
19
|
from ccxt.base.errors import InvalidAddress
|
19
20
|
from ccxt.base.errors import InvalidOrder
|
20
21
|
from ccxt.base.errors import OrderNotFound
|
21
|
-
from ccxt.base.errors import CancelPending
|
22
22
|
from ccxt.base.errors import NotSupported
|
23
23
|
from ccxt.base.errors import DDoSProtection
|
24
24
|
from ccxt.base.errors import RateLimitExceeded
|
25
25
|
from ccxt.base.errors import ExchangeNotAvailable
|
26
26
|
from ccxt.base.errors import OnMaintenance
|
27
27
|
from ccxt.base.errors import InvalidNonce
|
28
|
-
from ccxt.base.errors import
|
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
|
@@ -54,14 +54,19 @@ class kraken(Exchange, ImplicitAPI):
|
|
54
54
|
'option': False,
|
55
55
|
'addMargin': False,
|
56
56
|
'cancelAllOrders': True,
|
57
|
+
'cancelAllOrdersAfter': True,
|
57
58
|
'cancelOrder': True,
|
58
59
|
'cancelOrders': True,
|
59
60
|
'createDepositAddress': True,
|
61
|
+
'createMarketBuyOrderWithCost': True,
|
62
|
+
'createMarketOrderWithCost': False,
|
63
|
+
'createMarketSellOrderWithCost': False,
|
60
64
|
'createOrder': True,
|
61
65
|
'createStopLimitOrder': True,
|
62
66
|
'createStopMarketOrder': True,
|
63
67
|
'createStopOrder': True,
|
64
68
|
'createTrailingAmountOrder': True,
|
69
|
+
'createTrailingPercentOrder': True,
|
65
70
|
'editOrder': True,
|
66
71
|
'fetchBalance': True,
|
67
72
|
'fetchBorrowInterest': False,
|
@@ -72,6 +77,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
72
77
|
'fetchCrossBorrowRates': False,
|
73
78
|
'fetchCurrencies': True,
|
74
79
|
'fetchDepositAddress': True,
|
80
|
+
'fetchDepositAddresses': False,
|
81
|
+
'fetchDepositAddressesByNetwork': False,
|
75
82
|
'fetchDeposits': True,
|
76
83
|
'fetchFundingHistory': False,
|
77
84
|
'fetchFundingRate': False,
|
@@ -94,6 +101,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
94
101
|
'fetchOrderTrades': 'emulated',
|
95
102
|
'fetchPositions': True,
|
96
103
|
'fetchPremiumIndexOHLCV': False,
|
104
|
+
'fetchStatus': True,
|
97
105
|
'fetchTicker': True,
|
98
106
|
'fetchTickers': True,
|
99
107
|
'fetchTime': True,
|
@@ -175,13 +183,13 @@ class kraken(Exchange, ImplicitAPI):
|
|
175
183
|
# rate-limits explained in comment in the top of self file
|
176
184
|
'Assets': 1,
|
177
185
|
'AssetPairs': 1,
|
178
|
-
'Depth': 1,
|
179
|
-
'OHLC': 1,
|
186
|
+
'Depth': 1.2,
|
187
|
+
'OHLC': 1.2, # 1.2 because 1 triggers too many requests immediately
|
180
188
|
'Spread': 1,
|
181
189
|
'SystemStatus': 1,
|
182
190
|
'Ticker': 1,
|
183
191
|
'Time': 1,
|
184
|
-
'Trades': 1,
|
192
|
+
'Trades': 1.2,
|
185
193
|
},
|
186
194
|
},
|
187
195
|
'private': {
|
@@ -189,6 +197,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
189
197
|
'AddOrder': 0,
|
190
198
|
'AddOrderBatch': 0,
|
191
199
|
'AddExport': 3,
|
200
|
+
'AmendOrder': 0,
|
192
201
|
'Balance': 3,
|
193
202
|
'CancelAll': 3,
|
194
203
|
'CancelAllOrdersAfter': 3,
|
@@ -244,6 +253,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
244
253
|
'XDG': 'DOGE',
|
245
254
|
},
|
246
255
|
'options': {
|
256
|
+
'timeDifference': 0, # the difference between system clock and Binance clock
|
257
|
+
'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
|
247
258
|
'marketsByAltname': {},
|
248
259
|
'delistedMarketsById': {},
|
249
260
|
# cannot withdraw/deposit these
|
@@ -253,100 +264,100 @@ class kraken(Exchange, ImplicitAPI):
|
|
253
264
|
'TRX': 'TRC20',
|
254
265
|
},
|
255
266
|
'depositMethods': {
|
256
|
-
'1INCH': '1inch(1INCH)',
|
267
|
+
'1INCH': '1inch' + ' ' + '(1INCH)',
|
257
268
|
'AAVE': 'Aave',
|
258
269
|
'ADA': 'ADA',
|
259
270
|
'ALGO': 'Algorand',
|
260
|
-
'ANKR': 'ANKR(ANKR)',
|
261
|
-
'ANT': 'Aragon(ANT)',
|
271
|
+
'ANKR': 'ANKR' + ' ' + '(ANKR)',
|
272
|
+
'ANT': 'Aragon' + ' ' + '(ANT)',
|
262
273
|
'ATOM': 'Cosmos',
|
263
|
-
'AXS': 'Axie Infinity Shards(AXS)',
|
264
|
-
'BADGER': 'Bager DAO(BADGER)',
|
265
|
-
'BAL': 'Balancer(BAL)',
|
266
|
-
'BAND': 'Band Protocol(BAND)',
|
274
|
+
'AXS': 'Axie Infinity Shards' + ' ' + '(AXS)',
|
275
|
+
'BADGER': 'Bager DAO' + ' ' + '(BADGER)',
|
276
|
+
'BAL': 'Balancer' + ' ' + '(BAL)',
|
277
|
+
'BAND': 'Band Protocol' + ' ' + '(BAND)',
|
267
278
|
'BAT': 'BAT',
|
268
279
|
'BCH': 'Bitcoin Cash',
|
269
|
-
'BNC': 'Bifrost(BNC)',
|
270
|
-
'BNT': 'Bancor(BNT)',
|
280
|
+
'BNC': 'Bifrost' + ' ' + '(BNC)',
|
281
|
+
'BNT': 'Bancor' + ' ' + '(BNT)',
|
271
282
|
'BTC': 'Bitcoin',
|
272
|
-
'CHZ': 'Chiliz(CHZ)',
|
273
|
-
'COMP': 'Compound(COMP)',
|
274
|
-
'CQT': '\tCovalent Query Token(CQT)',
|
275
|
-
'CRV': 'Curve DAO Token(CRV)',
|
276
|
-
'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)',
|
277
288
|
'DAI': 'Dai',
|
278
289
|
'DASH': 'Dash',
|
279
290
|
'DOGE': 'Dogecoin',
|
280
291
|
'DOT': 'Polkadot',
|
281
|
-
'DYDX': 'dYdX(DYDX)',
|
282
|
-
'ENJ': 'Enjin Coin(ENJ)',
|
292
|
+
'DYDX': 'dYdX' + ' ' + '(DYDX)',
|
293
|
+
'ENJ': 'Enjin Coin' + ' ' + '(ENJ)',
|
283
294
|
'EOS': 'EOS',
|
284
|
-
'ETC': 'Ether Classic(Hex)',
|
285
|
-
'ETH': 'Ether(Hex)',
|
295
|
+
'ETC': 'Ether Classic' + ' ' + '(Hex)',
|
296
|
+
'ETH': 'Ether' + ' ' + '(Hex)',
|
286
297
|
'EWT': 'Energy Web Token',
|
287
298
|
'FEE': 'Kraken Fee Credit',
|
288
299
|
'FIL': 'Filecoin',
|
289
300
|
'FLOW': 'Flow',
|
290
|
-
'GHST': 'Aavegotchi(GHST)',
|
301
|
+
'GHST': 'Aavegotchi' + ' ' + '(GHST)',
|
291
302
|
'GNO': 'GNO',
|
292
303
|
'GRT': 'GRT',
|
293
304
|
'ICX': 'Icon',
|
294
|
-
'INJ': 'Injective Protocol(INJ)',
|
295
|
-
'KAR': 'Karura(KAR)',
|
305
|
+
'INJ': 'Injective Protocol' + ' ' + '(INJ)',
|
306
|
+
'KAR': 'Karura' + ' ' + '(KAR)',
|
296
307
|
'KAVA': 'Kava',
|
297
|
-
'KEEP': 'Keep Token(KEEP)',
|
298
|
-
'KNC': 'Kyber Network(KNC)',
|
308
|
+
'KEEP': 'Keep Token' + ' ' + '(KEEP)',
|
309
|
+
'KNC': 'Kyber Network' + ' ' + '(KNC)',
|
299
310
|
'KSM': 'Kusama',
|
300
311
|
'LINK': 'Link',
|
301
|
-
'LPT': 'Livepeer Token(LPT)',
|
302
|
-
'LRC': 'Loopring(LRC)',
|
312
|
+
'LPT': 'Livepeer Token' + ' ' + '(LPT)',
|
313
|
+
'LRC': 'Loopring' + ' ' + '(LRC)',
|
303
314
|
'LSK': 'Lisk',
|
304
315
|
'LTC': 'Litecoin',
|
305
316
|
'MANA': 'MANA',
|
306
|
-
'MATIC': 'Polygon(MATIC)',
|
317
|
+
'MATIC': 'Polygon' + ' ' + '(MATIC)',
|
307
318
|
'MINA': 'Mina', # inspected from webui
|
308
|
-
'MIR': 'Mirror Protocol(MIR)',
|
309
|
-
'MKR': 'Maker(MKR)',
|
319
|
+
'MIR': 'Mirror Protocol' + ' ' + '(MIR)',
|
320
|
+
'MKR': 'Maker' + ' ' + '(MKR)',
|
310
321
|
'MLN': 'MLN',
|
311
|
-
'MOVR': 'Moonriver(MOVR)',
|
322
|
+
'MOVR': 'Moonriver' + ' ' + '(MOVR)',
|
312
323
|
'NANO': 'NANO',
|
313
324
|
'OCEAN': 'OCEAN',
|
314
|
-
'OGN': 'Origin Protocol(OGN)',
|
325
|
+
'OGN': 'Origin Protocol' + ' ' + '(OGN)',
|
315
326
|
'OMG': 'OMG',
|
316
|
-
'OXT': 'Orchid(OXT)',
|
317
|
-
'OXY': 'Oxygen(OXY)',
|
318
|
-
'PAXG': 'PAX(Gold)',
|
319
|
-
'PERP': 'Perpetual Protocol(PERP)',
|
320
|
-
'PHA': 'Phala(PHA)',
|
327
|
+
'OXT': 'Orchid' + ' ' + '(OXT)',
|
328
|
+
'OXY': 'Oxygen' + ' ' + '(OXY)',
|
329
|
+
'PAXG': 'PAX' + ' ' + '(Gold)',
|
330
|
+
'PERP': 'Perpetual Protocol' + ' ' + '(PERP)',
|
331
|
+
'PHA': 'Phala' + ' ' + '(PHA)',
|
321
332
|
'QTUM': 'QTUM',
|
322
|
-
'RARI': 'Rarible(RARI)',
|
323
|
-
'RAY': 'Raydium(RAY)',
|
324
|
-
'REN': 'Ren Protocol(REN)',
|
333
|
+
'RARI': 'Rarible' + ' ' + '(RARI)',
|
334
|
+
'RAY': 'Raydium' + ' ' + '(RAY)',
|
335
|
+
'REN': 'Ren Protocol' + ' ' + '(REN)',
|
325
336
|
'REP': 'REPv2',
|
326
337
|
'REPV1': 'REP',
|
327
|
-
'SAND': 'The Sandbox(SAND)',
|
338
|
+
'SAND': 'The Sandbox' + ' ' + '(SAND)',
|
328
339
|
'SC': 'Siacoin',
|
329
|
-
'SDN': 'Shiden(SDN)',
|
340
|
+
'SDN': 'Shiden' + ' ' + '(SDN)',
|
330
341
|
'SOL': 'Solana', # their deposit method api doesn't work for SOL - was guessed
|
331
|
-
'SNX': 'Synthetix Network(SNX)',
|
342
|
+
'SNX': 'Synthetix Network' + ' ' + '(SNX)',
|
332
343
|
'SRM': 'Serum', # inspected from webui
|
333
|
-
'STORJ': 'Storj(STORJ)',
|
334
|
-
'SUSHI': 'Sushiswap(SUSHI)',
|
344
|
+
'STORJ': 'Storj' + ' ' + '(STORJ)',
|
345
|
+
'SUSHI': 'Sushiswap' + ' ' + '(SUSHI)',
|
335
346
|
'TBTC': 'tBTC',
|
336
347
|
'TRX': 'Tron',
|
337
348
|
'UNI': 'UNI',
|
338
349
|
'USDC': 'USDC',
|
339
|
-
'USDT': 'Tether USD(ERC20)',
|
340
|
-
'USDT-TRC20': 'Tether USD(TRC20)',
|
350
|
+
'USDT': 'Tether USD' + ' ' + '(ERC20)',
|
351
|
+
'USDT-TRC20': 'Tether USD' + ' ' + '(TRC20)',
|
341
352
|
'WAVES': 'Waves',
|
342
|
-
'WBTC': 'Wrapped Bitcoin(WBTC)',
|
353
|
+
'WBTC': 'Wrapped Bitcoin' + ' ' + '(WBTC)',
|
343
354
|
'XLM': 'Stellar XLM',
|
344
355
|
'XMR': 'Monero',
|
345
356
|
'XRP': 'Ripple XRP',
|
346
357
|
'XTZ': 'XTZ',
|
347
358
|
'YFI': 'YFI',
|
348
|
-
'ZEC': 'Zcash(Transparent)',
|
349
|
-
'ZRX': '0x(ZRX)',
|
359
|
+
'ZEC': 'Zcash' + ' ' + '(Transparent)',
|
360
|
+
'ZRX': '0x' + ' ' + '(ZRX)',
|
350
361
|
},
|
351
362
|
'withdrawMethods': { # keeping it here because deposit and withdraw return different networks codes
|
352
363
|
'Lightning': 'Lightning',
|
@@ -434,44 +445,128 @@ class kraken(Exchange, ImplicitAPI):
|
|
434
445
|
'Celestia': 'TIA',
|
435
446
|
},
|
436
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
|
+
},
|
480
|
+
'fetchOrder': {
|
481
|
+
'marginMode': False,
|
482
|
+
'trigger': False,
|
483
|
+
'trailing': False,
|
484
|
+
},
|
485
|
+
'fetchOpenOrders': {
|
486
|
+
'marginMode': False,
|
487
|
+
'limit': None,
|
488
|
+
'trigger': False,
|
489
|
+
'trailing': False,
|
490
|
+
},
|
491
|
+
'fetchOrders': None,
|
492
|
+
'fetchClosedOrders': {
|
493
|
+
'marginMode': False,
|
494
|
+
'limit': None,
|
495
|
+
'daysBack': None,
|
496
|
+
'daysBackCanceled': None,
|
497
|
+
'untilDays': 100000,
|
498
|
+
'trigger': False,
|
499
|
+
'trailing': False,
|
500
|
+
},
|
501
|
+
'fetchOHLCV': {
|
502
|
+
'limit': 720,
|
503
|
+
},
|
504
|
+
},
|
505
|
+
'swap': {
|
506
|
+
'linear': None,
|
507
|
+
'inverse': None,
|
508
|
+
},
|
509
|
+
'future': {
|
510
|
+
'linear': None,
|
511
|
+
'inverse': None,
|
512
|
+
},
|
513
|
+
},
|
437
514
|
'precisionMode': TICK_SIZE,
|
438
515
|
'exceptions': {
|
439
|
-
'
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
516
|
+
'exact': {
|
517
|
+
'EQuery:Invalid asset pair': BadSymbol, # {"error":["EQuery:Invalid asset pair"]}
|
518
|
+
'EAPI:Invalid key': AuthenticationError,
|
519
|
+
'EFunding:Unknown withdraw key': InvalidAddress, # {"error":["EFunding:Unknown withdraw key"]}
|
520
|
+
'EFunding:Invalid amount': InsufficientFunds,
|
521
|
+
'EService:Unavailable': ExchangeNotAvailable,
|
522
|
+
'EDatabase:Internal error': ExchangeNotAvailable,
|
523
|
+
'EService:Busy': ExchangeNotAvailable,
|
524
|
+
'EQuery:Unknown asset': BadSymbol, # {"error":["EQuery:Unknown asset"]}
|
525
|
+
'EAPI:Rate limit exceeded': DDoSProtection,
|
526
|
+
'EOrder:Rate limit exceeded': DDoSProtection,
|
527
|
+
'EGeneral:Internal error': ExchangeNotAvailable,
|
528
|
+
'EGeneral:Temporary lockout': DDoSProtection,
|
529
|
+
'EGeneral:Permission denied': PermissionDenied,
|
530
|
+
'EGeneral:Invalid arguments:price': InvalidOrder,
|
531
|
+
'EOrder:Unknown order': InvalidOrder,
|
532
|
+
'EOrder:Invalid price:Invalid price argument': InvalidOrder,
|
533
|
+
'EOrder:Order minimum not met': InvalidOrder,
|
534
|
+
'EOrder:Insufficient funds': InsufficientFunds,
|
535
|
+
'EGeneral:Invalid arguments': BadRequest,
|
536
|
+
'ESession:Invalid session': AuthenticationError,
|
537
|
+
'EAPI:Invalid nonce': InvalidNonce,
|
538
|
+
'EFunding:No funding method': BadRequest, # {"error":"EFunding:No funding method"}
|
539
|
+
'EFunding:Unknown asset': BadSymbol, # {"error":["EFunding:Unknown asset"]}
|
540
|
+
'EService:Market in post_only mode': OnMaintenance, # {"error":["EService:Market in post_only mode"]}
|
541
|
+
'EGeneral:Too many requests': DDoSProtection, # {"error":["EGeneral:Too many requests"]}
|
542
|
+
'ETrade:User Locked': AccountSuspended, # {"error":["ETrade:User Locked"]}
|
543
|
+
},
|
544
|
+
'broad': {
|
545
|
+
':Invalid order': InvalidOrder,
|
546
|
+
':Invalid arguments:volume': InvalidOrder,
|
547
|
+
':Invalid arguments:viqc': InvalidOrder,
|
548
|
+
':Invalid nonce': InvalidNonce,
|
549
|
+
':IInsufficient funds': InsufficientFunds,
|
550
|
+
':Cancel pending': CancelPending,
|
551
|
+
':Rate limit exceeded': RateLimitExceeded,
|
552
|
+
},
|
462
553
|
},
|
463
554
|
})
|
464
555
|
|
465
556
|
def fee_to_precision(self, symbol, fee):
|
466
557
|
return self.decimal_to_precision(fee, TRUNCATE, self.markets[symbol]['precision']['amount'], self.precisionMode)
|
467
558
|
|
468
|
-
def fetch_markets(self, params={}):
|
559
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
469
560
|
"""
|
470
561
|
retrieves data on all markets for kraken
|
471
|
-
|
562
|
+
|
563
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTradableAssetPairs
|
564
|
+
|
472
565
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
473
566
|
:returns dict[]: an array of objects representing market data
|
474
567
|
"""
|
568
|
+
if self.options['adjustForTimeDifference']:
|
569
|
+
self.load_time_difference()
|
475
570
|
response = self.publicGetAssetPairs(params)
|
476
571
|
#
|
477
572
|
# {
|
@@ -547,6 +642,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
547
642
|
leverageBuy = self.safe_value(market, 'leverage_buy', [])
|
548
643
|
leverageBuyLength = len(leverageBuy)
|
549
644
|
precisionPrice = self.parse_number(self.parse_precision(self.safe_string(market, 'pair_decimals')))
|
645
|
+
status = self.safe_string(market, 'status')
|
646
|
+
isActive = status == 'online'
|
550
647
|
result.append({
|
551
648
|
'id': id,
|
552
649
|
'wsId': self.safe_string(market, 'wsname'),
|
@@ -565,7 +662,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
565
662
|
'swap': False,
|
566
663
|
'future': False,
|
567
664
|
'option': False,
|
568
|
-
'active':
|
665
|
+
'active': isActive,
|
569
666
|
'contract': False,
|
570
667
|
'linear': None,
|
571
668
|
'inverse': None,
|
@@ -609,23 +706,21 @@ class kraken(Exchange, ImplicitAPI):
|
|
609
706
|
if currencyId is not None:
|
610
707
|
if len(currencyId) > 3:
|
611
708
|
if (currencyId.find('X') == 0) or (currencyId.find('Z') == 0):
|
612
|
-
if currencyId.find('.') > 0:
|
613
|
-
return super(kraken, self).safe_currency(currencyId, currency)
|
614
|
-
else:
|
709
|
+
if not (currencyId.find('.') > 0) and (currencyId != 'ZEUS'):
|
615
710
|
currencyId = currencyId[1:]
|
616
711
|
return super(kraken, self).safe_currency(currencyId, currency)
|
617
712
|
|
618
713
|
def append_inactive_markets(self, result):
|
619
714
|
# result should be an array to append to
|
620
|
-
precision = {
|
715
|
+
precision: dict = {
|
621
716
|
'amount': self.parse_number('1e-8'),
|
622
717
|
'price': self.parse_number('1e-8'),
|
623
718
|
}
|
624
|
-
costLimits = {'min': None, 'max': None}
|
625
|
-
priceLimits = {'min': precision['price'], 'max': None}
|
626
|
-
amountLimits = {'min': precision['amount'], 'max': None}
|
627
|
-
limits = {'amount': amountLimits, 'price': priceLimits, 'cost': costLimits}
|
628
|
-
defaults = {
|
719
|
+
costLimits: dict = {'min': None, 'max': None}
|
720
|
+
priceLimits: dict = {'min': precision['price'], 'max': None}
|
721
|
+
amountLimits: dict = {'min': precision['amount'], 'max': None}
|
722
|
+
limits: dict = {'amount': amountLimits, 'price': priceLimits, 'cost': costLimits}
|
723
|
+
defaults: dict = {
|
629
724
|
'darkpool': False,
|
630
725
|
'info': None,
|
631
726
|
'maker': None,
|
@@ -641,10 +736,38 @@ class kraken(Exchange, ImplicitAPI):
|
|
641
736
|
result.append(self.extend(defaults, markets[i]))
|
642
737
|
return result
|
643
738
|
|
644
|
-
def
|
739
|
+
def fetch_status(self, params={}):
|
740
|
+
"""
|
741
|
+
the latest known information on the availability of the exchange API
|
742
|
+
|
743
|
+
https://docs.kraken.com/api/docs/rest-api/get-system-status/
|
744
|
+
|
745
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
746
|
+
:returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
|
747
|
+
"""
|
748
|
+
response = self.publicGetSystemStatus(params)
|
749
|
+
#
|
750
|
+
# {
|
751
|
+
# error: [],
|
752
|
+
# result: {status: 'online', timestamp: '2024-07-22T16:34:44Z'}
|
753
|
+
# }
|
754
|
+
#
|
755
|
+
result = self.safe_dict(response, 'result')
|
756
|
+
statusRaw = self.safe_string(result, 'status')
|
757
|
+
return {
|
758
|
+
'status': 'ok' if (statusRaw == 'online') else 'maintenance',
|
759
|
+
'updated': None,
|
760
|
+
'eta': None,
|
761
|
+
'url': None,
|
762
|
+
'info': response,
|
763
|
+
}
|
764
|
+
|
765
|
+
def fetch_currencies(self, params={}) -> Currencies:
|
645
766
|
"""
|
646
767
|
fetches all available currencies on an exchange
|
647
|
-
|
768
|
+
|
769
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getAssetInfo
|
770
|
+
|
648
771
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
649
772
|
:returns dict: an associative dictionary of currencies
|
650
773
|
"""
|
@@ -653,15 +776,20 @@ class kraken(Exchange, ImplicitAPI):
|
|
653
776
|
# {
|
654
777
|
# "error": [],
|
655
778
|
# "result": {
|
656
|
-
# "
|
657
|
-
#
|
779
|
+
# "BCH": {
|
780
|
+
# "aclass": "currency",
|
781
|
+
# "altname": "BCH",
|
782
|
+
# "decimals": 10,
|
783
|
+
# "display_decimals": 5
|
784
|
+
# "status": "enabled",
|
785
|
+
# },
|
658
786
|
# ...
|
659
787
|
# },
|
660
788
|
# }
|
661
789
|
#
|
662
790
|
currencies = self.safe_value(response, 'result', {})
|
663
791
|
ids = list(currencies.keys())
|
664
|
-
result = {}
|
792
|
+
result: dict = {}
|
665
793
|
for i in range(0, len(ids)):
|
666
794
|
id = ids[i]
|
667
795
|
currency = currencies[id]
|
@@ -669,15 +797,15 @@ class kraken(Exchange, ImplicitAPI):
|
|
669
797
|
# see: https://support.kraken.com/hc/en-us/articles/201893608-What-are-the-withdrawal-fees-
|
670
798
|
# to add support for multiple withdrawal/deposit methods and
|
671
799
|
# differentiated fees for each particular method
|
672
|
-
code = self.safe_currency_code(
|
800
|
+
code = self.safe_currency_code(id)
|
673
801
|
precision = self.parse_number(self.parse_precision(self.safe_string(currency, 'decimals')))
|
674
802
|
# assumes all currencies are active except those listed above
|
675
|
-
active =
|
803
|
+
active = self.safe_string(currency, 'status') == 'enabled'
|
676
804
|
result[code] = {
|
677
805
|
'id': id,
|
678
806
|
'code': code,
|
679
807
|
'info': currency,
|
680
|
-
'name':
|
808
|
+
'name': self.safe_string(currency, 'altname'),
|
681
809
|
'active': active,
|
682
810
|
'deposit': None,
|
683
811
|
'withdraw': None,
|
@@ -697,17 +825,19 @@ class kraken(Exchange, ImplicitAPI):
|
|
697
825
|
}
|
698
826
|
return result
|
699
827
|
|
700
|
-
def fetch_trading_fee(self, symbol: str, params={}):
|
828
|
+
def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
|
701
829
|
"""
|
702
830
|
fetch the trading fees for a market
|
703
|
-
|
831
|
+
|
832
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getTradeVolume
|
833
|
+
|
704
834
|
:param str symbol: unified market symbol
|
705
835
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
706
836
|
:returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
|
707
837
|
"""
|
708
838
|
self.load_markets()
|
709
839
|
market = self.market(symbol)
|
710
|
-
request = {
|
840
|
+
request: dict = {
|
711
841
|
'pair': market['id'],
|
712
842
|
'fee-info': True,
|
713
843
|
}
|
@@ -752,8 +882,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
752
882
|
return {
|
753
883
|
'info': response,
|
754
884
|
'symbol': market['symbol'],
|
755
|
-
'maker': self.
|
756
|
-
'taker': self.
|
885
|
+
'maker': self.parse_number(Precise.string_div(self.safe_string(symbolMakerFee, 'fee'), '100')),
|
886
|
+
'taker': self.parse_number(Precise.string_div(self.safe_string(symbolTakerFee, 'fee'), '100')),
|
757
887
|
'percentage': True,
|
758
888
|
'tierBased': True,
|
759
889
|
}
|
@@ -767,7 +897,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
767
897
|
def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
768
898
|
"""
|
769
899
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
770
|
-
|
900
|
+
|
901
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getOrderBook
|
902
|
+
|
771
903
|
:param str symbol: unified symbol of the market to fetch the order book for
|
772
904
|
:param int [limit]: the maximum amount of order book entries to return
|
773
905
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -777,7 +909,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
777
909
|
market = self.market(symbol)
|
778
910
|
if market['darkpool']:
|
779
911
|
raise ExchangeError(self.id + ' fetchOrderBook() does not provide an order book for darkpool symbol ' + symbol)
|
780
|
-
request = {
|
912
|
+
request: dict = {
|
781
913
|
'pair': market['id'],
|
782
914
|
}
|
783
915
|
if limit is not None:
|
@@ -812,7 +944,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
812
944
|
orderbook = self.safe_value(result, wsName, orderbook)
|
813
945
|
return self.parse_order_book(orderbook, symbol)
|
814
946
|
|
815
|
-
def parse_ticker(self, ticker, market: Market = None) -> Ticker:
|
947
|
+
def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
|
816
948
|
#
|
817
949
|
# {
|
818
950
|
# "a":["2432.77000","1","1.000"],
|
@@ -864,13 +996,15 @@ class kraken(Exchange, ImplicitAPI):
|
|
864
996
|
def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
865
997
|
"""
|
866
998
|
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
867
|
-
|
999
|
+
|
1000
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTickerInformation
|
1001
|
+
|
868
1002
|
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
869
1003
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
870
1004
|
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
871
1005
|
"""
|
872
1006
|
self.load_markets()
|
873
|
-
request = {}
|
1007
|
+
request: dict = {}
|
874
1008
|
if symbols is not None:
|
875
1009
|
symbols = self.market_symbols(symbols)
|
876
1010
|
marketIds = []
|
@@ -883,7 +1017,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
883
1017
|
response = self.publicGetTicker(self.extend(request, params))
|
884
1018
|
tickers = response['result']
|
885
1019
|
ids = list(tickers.keys())
|
886
|
-
result = {}
|
1020
|
+
result: dict = {}
|
887
1021
|
for i in range(0, len(ids)):
|
888
1022
|
id = ids[i]
|
889
1023
|
market = self.safe_market(id)
|
@@ -895,7 +1029,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
895
1029
|
def fetch_ticker(self, symbol: str, params={}) -> Ticker:
|
896
1030
|
"""
|
897
1031
|
fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
898
|
-
|
1032
|
+
|
1033
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTickerInformation
|
1034
|
+
|
899
1035
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
900
1036
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
901
1037
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -905,7 +1041,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
905
1041
|
if darkpool:
|
906
1042
|
raise ExchangeError(self.id + ' fetchTicker() does not provide a ticker for darkpool symbol ' + symbol)
|
907
1043
|
market = self.market(symbol)
|
908
|
-
request = {
|
1044
|
+
request: dict = {
|
909
1045
|
'pair': market['id'],
|
910
1046
|
}
|
911
1047
|
response = self.publicGetTicker(self.extend(request, params))
|
@@ -937,7 +1073,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
937
1073
|
def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
938
1074
|
"""
|
939
1075
|
fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
940
|
-
|
1076
|
+
|
1077
|
+
https://docs.kraken.com/api/docs/rest-api/get-ohlc-data
|
1078
|
+
|
941
1079
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
942
1080
|
:param str timeframe: the length of time each candle represents
|
943
1081
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
@@ -953,7 +1091,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
953
1091
|
return self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 720)
|
954
1092
|
market = self.market(symbol)
|
955
1093
|
parsedTimeframe = self.safe_integer(self.timeframes, timeframe)
|
956
|
-
request = {
|
1094
|
+
request: dict = {
|
957
1095
|
'pair': market['id'],
|
958
1096
|
}
|
959
1097
|
if parsedTimeframe is not None:
|
@@ -961,9 +1099,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
961
1099
|
else:
|
962
1100
|
request['interval'] = timeframe
|
963
1101
|
if since is not None:
|
964
|
-
|
965
|
-
|
966
|
-
request['since'] = self.number_to_string(
|
1102
|
+
scaledSince = self.parse_to_int(since / 1000)
|
1103
|
+
timeFrameInSeconds = parsedTimeframe * 60
|
1104
|
+
request['since'] = self.number_to_string(scaledSince - timeFrameInSeconds) # expected to be in seconds
|
967
1105
|
response = self.publicGetOHLC(self.extend(request, params))
|
968
1106
|
#
|
969
1107
|
# {
|
@@ -979,11 +1117,11 @@ class kraken(Exchange, ImplicitAPI):
|
|
979
1117
|
# }
|
980
1118
|
# }
|
981
1119
|
result = self.safe_value(response, 'result', {})
|
982
|
-
ohlcvs = self.
|
1120
|
+
ohlcvs = self.safe_list(result, market['id'], [])
|
983
1121
|
return self.parse_ohlcvs(ohlcvs, market, timeframe, since, limit)
|
984
1122
|
|
985
1123
|
def parse_ledger_entry_type(self, type):
|
986
|
-
types = {
|
1124
|
+
types: dict = {
|
987
1125
|
'trade': 'trade',
|
988
1126
|
'withdrawal': 'transaction',
|
989
1127
|
'deposit': 'transaction',
|
@@ -992,7 +1130,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
992
1130
|
}
|
993
1131
|
return self.safe_string(types, type, type)
|
994
1132
|
|
995
|
-
def parse_ledger_entry(self, item, currency: Currency = None):
|
1133
|
+
def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
|
996
1134
|
#
|
997
1135
|
# {
|
998
1136
|
# 'LTFK7F-N2CUX-PNY4SX': {
|
@@ -1014,15 +1152,17 @@ class kraken(Exchange, ImplicitAPI):
|
|
1014
1152
|
referenceId = self.safe_string(item, 'refid')
|
1015
1153
|
referenceAccount = None
|
1016
1154
|
type = self.parse_ledger_entry_type(self.safe_string(item, 'type'))
|
1017
|
-
|
1155
|
+
currencyId = self.safe_string(item, 'asset')
|
1156
|
+
code = self.safe_currency_code(currencyId, currency)
|
1157
|
+
currency = self.safe_currency(currencyId, currency)
|
1018
1158
|
amount = self.safe_string(item, 'amount')
|
1019
1159
|
if Precise.string_lt(amount, '0'):
|
1020
1160
|
direction = 'out'
|
1021
1161
|
amount = Precise.string_abs(amount)
|
1022
1162
|
else:
|
1023
1163
|
direction = 'in'
|
1024
|
-
timestamp = self.
|
1025
|
-
return {
|
1164
|
+
timestamp = self.safe_integer_product(item, 'time', 1000)
|
1165
|
+
return self.safe_ledger_entry({
|
1026
1166
|
'info': item,
|
1027
1167
|
'id': id,
|
1028
1168
|
'direction': direction,
|
@@ -1041,29 +1181,36 @@ class kraken(Exchange, ImplicitAPI):
|
|
1041
1181
|
'cost': self.safe_number(item, 'fee'),
|
1042
1182
|
'currency': code,
|
1043
1183
|
},
|
1044
|
-
}
|
1184
|
+
}, currency)
|
1045
1185
|
|
1046
|
-
def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
|
1186
|
+
def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
|
1047
1187
|
"""
|
1048
|
-
fetch the history of changes, actions done by the user or operations that altered balance of the user
|
1049
|
-
|
1050
|
-
|
1188
|
+
fetch the history of changes, actions done by the user or operations that altered the balance of the user
|
1189
|
+
|
1190
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getLedgers
|
1191
|
+
|
1192
|
+
:param str [code]: unified currency code, default is None
|
1051
1193
|
:param int [since]: timestamp in ms of the earliest ledger entry, default is None
|
1052
|
-
:param int [limit]: max number of ledger
|
1194
|
+
:param int [limit]: max number of ledger entries to return, default is None
|
1053
1195
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1054
1196
|
:param int [params.until]: timestamp in ms of the latest ledger entry
|
1055
|
-
:
|
1197
|
+
:param int [params.end]: timestamp in seconds of the latest ledger entry
|
1198
|
+
:returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
|
1056
1199
|
"""
|
1057
1200
|
# https://www.kraken.com/features/api#get-ledgers-info
|
1058
1201
|
self.load_markets()
|
1059
|
-
request = {}
|
1202
|
+
request: dict = {}
|
1060
1203
|
currency = None
|
1061
1204
|
if code is not None:
|
1062
1205
|
currency = self.currency(code)
|
1063
1206
|
request['asset'] = currency['id']
|
1064
1207
|
if since is not None:
|
1065
1208
|
request['start'] = self.parse_to_int(since / 1000)
|
1066
|
-
|
1209
|
+
until = self.safe_string_n(params, ['until', 'till'])
|
1210
|
+
if until is not None:
|
1211
|
+
params = self.omit(params, ['until', 'till'])
|
1212
|
+
untilDivided = Precise.string_div(until, '1000')
|
1213
|
+
request['end'] = self.parse_to_int(Precise.string_add(untilDivided, '1'))
|
1067
1214
|
response = self.privatePostLedgers(self.extend(request, params))
|
1068
1215
|
# { error: [],
|
1069
1216
|
# "result": {ledger: {'LPUAIB-TS774-UKHP7X': { refid: "A2B4HBV-L4MDIE-JU4N3N",
|
@@ -1112,11 +1259,11 @@ class kraken(Exchange, ImplicitAPI):
|
|
1112
1259
|
items.append(value)
|
1113
1260
|
return self.parse_ledger(items)
|
1114
1261
|
|
1115
|
-
def fetch_ledger_entry(self, id: str, code: Str = None, params={}):
|
1262
|
+
def fetch_ledger_entry(self, id: str, code: Str = None, params={}) -> LedgerEntry:
|
1116
1263
|
items = self.fetch_ledger_entries_by_ids([id], code, params)
|
1117
1264
|
return items[0]
|
1118
1265
|
|
1119
|
-
def parse_trade(self, trade, market: Market = None) -> Trade:
|
1266
|
+
def parse_trade(self, trade: dict, market: Market = None) -> Trade:
|
1120
1267
|
#
|
1121
1268
|
# fetchTrades(public)
|
1122
1269
|
#
|
@@ -1147,6 +1294,26 @@ class kraken(Exchange, ImplicitAPI):
|
|
1147
1294
|
# "misc": ''
|
1148
1295
|
# }
|
1149
1296
|
#
|
1297
|
+
# fetchMyTrades
|
1298
|
+
#
|
1299
|
+
# {
|
1300
|
+
# "ordertxid": "OSJVN7-A2AE-63WZV",
|
1301
|
+
# "postxid": "TBP7O6-PNXI-CONU",
|
1302
|
+
# "pair": "XXBTZUSD",
|
1303
|
+
# "time": 1710429248.3052235,
|
1304
|
+
# "type": "sell",
|
1305
|
+
# "ordertype": "liquidation market",
|
1306
|
+
# "price": "72026.50000",
|
1307
|
+
# "cost": "7.20265",
|
1308
|
+
# "fee": "0.01873",
|
1309
|
+
# "vol": "0.00010000",
|
1310
|
+
# "margin": "1.44053",
|
1311
|
+
# "leverage": "5",
|
1312
|
+
# "misc": "closing",
|
1313
|
+
# "trade_id": 68230622,
|
1314
|
+
# "maker": False
|
1315
|
+
# }
|
1316
|
+
#
|
1150
1317
|
timestamp = None
|
1151
1318
|
side = None
|
1152
1319
|
type = None
|
@@ -1193,6 +1360,10 @@ class kraken(Exchange, ImplicitAPI):
|
|
1193
1360
|
if market is not None:
|
1194
1361
|
symbol = market['symbol']
|
1195
1362
|
cost = self.safe_string(trade, 'cost')
|
1363
|
+
maker = self.safe_bool(trade, 'maker')
|
1364
|
+
takerOrMaker = None
|
1365
|
+
if maker is not None:
|
1366
|
+
takerOrMaker = 'maker' if maker else 'taker'
|
1196
1367
|
return self.safe_trade({
|
1197
1368
|
'id': id,
|
1198
1369
|
'order': orderId,
|
@@ -1202,7 +1373,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
1202
1373
|
'symbol': symbol,
|
1203
1374
|
'type': type,
|
1204
1375
|
'side': side,
|
1205
|
-
'takerOrMaker':
|
1376
|
+
'takerOrMaker': takerOrMaker,
|
1206
1377
|
'price': price,
|
1207
1378
|
'amount': amount,
|
1208
1379
|
'cost': cost,
|
@@ -1212,7 +1383,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
1212
1383
|
def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
1213
1384
|
"""
|
1214
1385
|
get the list of most recent trades for a particular symbol
|
1215
|
-
|
1386
|
+
|
1387
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getRecentTrades
|
1388
|
+
|
1216
1389
|
:param str symbol: unified symbol of the market to fetch trades for
|
1217
1390
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
1218
1391
|
:param int [limit]: the maximum amount of trades to fetch
|
@@ -1222,16 +1395,13 @@ class kraken(Exchange, ImplicitAPI):
|
|
1222
1395
|
self.load_markets()
|
1223
1396
|
market = self.market(symbol)
|
1224
1397
|
id = market['id']
|
1225
|
-
request = {
|
1398
|
+
request: dict = {
|
1226
1399
|
'pair': id,
|
1227
1400
|
}
|
1228
1401
|
# https://support.kraken.com/hc/en-us/articles/218198197-How-to-pull-all-trade-data-using-the-Kraken-REST-API
|
1229
1402
|
# https://github.com/ccxt/ccxt/issues/5677
|
1230
1403
|
if since is not None:
|
1231
|
-
#
|
1232
|
-
# therefore we use string concatenation here
|
1233
|
-
request['since'] = since * 1e6
|
1234
|
-
request['since'] = str(since) + '000000' # expected to be in nanoseconds
|
1404
|
+
request['since'] = self.number_to_string(self.parse_to_int(since / 1000)) # expected to be in seconds
|
1235
1405
|
if limit is not None:
|
1236
1406
|
request['count'] = limit
|
1237
1407
|
response = self.publicGetTrades(self.extend(request, params))
|
@@ -1260,7 +1430,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
1260
1430
|
|
1261
1431
|
def parse_balance(self, response) -> Balances:
|
1262
1432
|
balances = self.safe_value(response, 'result', {})
|
1263
|
-
result = {
|
1433
|
+
result: dict = {
|
1264
1434
|
'info': response,
|
1265
1435
|
'timestamp': None,
|
1266
1436
|
'datetime': None,
|
@@ -1279,7 +1449,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
1279
1449
|
def fetch_balance(self, params={}) -> Balances:
|
1280
1450
|
"""
|
1281
1451
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
1282
|
-
|
1452
|
+
|
1453
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getExtendedBalance
|
1454
|
+
|
1283
1455
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1284
1456
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
1285
1457
|
"""
|
@@ -1302,46 +1474,83 @@ class kraken(Exchange, ImplicitAPI):
|
|
1302
1474
|
#
|
1303
1475
|
return self.parse_balance(response)
|
1304
1476
|
|
1477
|
+
def create_market_order_with_cost(self, symbol: str, side: OrderSide, cost: float, params={}):
|
1478
|
+
"""
|
1479
|
+
create a market order by providing the symbol, side and cost
|
1480
|
+
|
1481
|
+
https://docs.kraken.com/rest/#tag/Spot-Trading/operation/addOrder
|
1482
|
+
|
1483
|
+
:param str symbol: unified symbol of the market to create an order in(only USD markets are supported)
|
1484
|
+
:param str side: 'buy' or 'sell'
|
1485
|
+
:param float cost: how much you want to trade in units of the quote currency
|
1486
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1487
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1488
|
+
"""
|
1489
|
+
self.load_markets()
|
1490
|
+
# only buy orders are supported by the endpoint
|
1491
|
+
req = {
|
1492
|
+
'cost': cost,
|
1493
|
+
}
|
1494
|
+
return self.create_order(symbol, 'market', side, 1, None, self.extend(req, params))
|
1495
|
+
|
1496
|
+
def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
|
1497
|
+
"""
|
1498
|
+
create a market buy order by providing the symbol, side and cost
|
1499
|
+
|
1500
|
+
https://docs.kraken.com/rest/#tag/Spot-Trading/operation/addOrder
|
1501
|
+
|
1502
|
+
:param str symbol: unified symbol of the market to create an order in
|
1503
|
+
:param float cost: how much you want to trade in units of the quote currency
|
1504
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1505
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1506
|
+
"""
|
1507
|
+
self.load_markets()
|
1508
|
+
return self.create_market_order_with_cost(symbol, 'buy', cost, params)
|
1509
|
+
|
1305
1510
|
def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
1306
1511
|
"""
|
1307
|
-
:see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
|
1308
1512
|
create a trade order
|
1513
|
+
|
1514
|
+
https://docs.kraken.com/api/docs/rest-api/add-order
|
1515
|
+
|
1309
1516
|
:param str symbol: unified symbol of the market to create an order in
|
1310
1517
|
:param str type: 'market' or 'limit'
|
1311
1518
|
:param str side: 'buy' or 'sell'
|
1312
1519
|
:param float amount: how much of currency you want to trade in units of base currency
|
1313
|
-
:param float [price]: the price at which the order is to be
|
1520
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
1314
1521
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1315
1522
|
:param bool [params.postOnly]: if True, the order will only be posted to the order book and not executed immediately
|
1316
1523
|
:param bool [params.reduceOnly]: *margin only* indicates if self order is to reduce the size of a position
|
1317
1524
|
:param float [params.stopLossPrice]: *margin only* the price that a stop loss order is triggered at
|
1318
1525
|
:param float [params.takeProfitPrice]: *margin only* the price that a take profit order is triggered at
|
1319
1526
|
:param str [params.trailingAmount]: *margin only* the quote amount to trail away from the current market price
|
1527
|
+
:param str [params.trailingPercent]: *margin only* the percent to trail away from the current market price
|
1320
1528
|
:param str [params.trailingLimitAmount]: *margin only* the quote amount away from the trailingAmount
|
1529
|
+
:param str [params.trailingLimitPercent]: *margin only* the percent away from the trailingAmount
|
1321
1530
|
:param str [params.offset]: *margin only* '+' or '-' whether you want the trailingLimitAmount value to be positive or negative, default is negative '-'
|
1322
1531
|
:param str [params.trigger]: *margin only* the activation price type, 'last' or 'index', default is 'last'
|
1323
1532
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1324
1533
|
"""
|
1325
1534
|
self.load_markets()
|
1326
1535
|
market = self.market(symbol)
|
1327
|
-
request = {
|
1536
|
+
request: dict = {
|
1328
1537
|
'pair': market['id'],
|
1329
1538
|
'type': side,
|
1330
1539
|
'ordertype': type,
|
1331
1540
|
'volume': self.amount_to_precision(symbol, amount),
|
1332
1541
|
}
|
1333
|
-
orderRequest = self.order_request('createOrder
|
1542
|
+
orderRequest = self.order_request('createOrder', symbol, type, request, amount, price, params)
|
1334
1543
|
response = self.privatePostAddOrder(self.extend(orderRequest[0], orderRequest[1]))
|
1335
1544
|
#
|
1336
1545
|
# {
|
1337
1546
|
# "error": [],
|
1338
1547
|
# "result": {
|
1339
|
-
# "descr": {order: 'buy 0.02100000 ETHUSDT @ limit 330.00'},
|
1548
|
+
# "descr": {order: 'buy 0.02100000 ETHUSDT @ limit 330.00'}, # see more examples in "parseOrder"
|
1340
1549
|
# "txid": ['OEKVV2-IH52O-TPL6GZ']
|
1341
1550
|
# }
|
1342
1551
|
# }
|
1343
1552
|
#
|
1344
|
-
result = self.
|
1553
|
+
result = self.safe_dict(response, 'result')
|
1345
1554
|
return self.parse_order(result)
|
1346
1555
|
|
1347
1556
|
def find_market_by_altname_or_id(self, id):
|
@@ -1384,8 +1593,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
1384
1593
|
self.options['delistedMarketsById'][id] = market
|
1385
1594
|
return market
|
1386
1595
|
|
1387
|
-
def parse_order_status(self, status):
|
1388
|
-
statuses = {
|
1596
|
+
def parse_order_status(self, status: Str):
|
1597
|
+
statuses: dict = {
|
1389
1598
|
'pending': 'open', # order pending book entry
|
1390
1599
|
'open': 'open',
|
1391
1600
|
'closed': 'closed',
|
@@ -1395,55 +1604,38 @@ class kraken(Exchange, ImplicitAPI):
|
|
1395
1604
|
return self.safe_string(statuses, status, status)
|
1396
1605
|
|
1397
1606
|
def parse_order_type(self, status):
|
1398
|
-
statuses = {
|
1607
|
+
statuses: dict = {
|
1608
|
+
# we dont add "space" delimited orders here(eg. stop loss) because they need separate parsing
|
1399
1609
|
'take-profit': 'market',
|
1400
|
-
'stop-loss-limit': 'limit',
|
1401
1610
|
'stop-loss': 'market',
|
1611
|
+
'stop-loss-limit': 'limit',
|
1402
1612
|
'take-profit-limit': 'limit',
|
1403
1613
|
'trailing-stop-limit': 'limit',
|
1404
1614
|
}
|
1405
1615
|
return self.safe_string(statuses, status, status)
|
1406
1616
|
|
1407
|
-
def parse_order(self, order, market: Market = None) -> Order:
|
1617
|
+
def parse_order(self, order: dict, market: Market = None) -> Order:
|
1408
1618
|
#
|
1409
|
-
# createOrder
|
1619
|
+
# createOrder
|
1410
1620
|
#
|
1411
1621
|
# {
|
1412
|
-
# "descr": {
|
1622
|
+
# "descr": {
|
1623
|
+
# "order": "buy 0.02100000 ETHUSDT @ limit 330.00" # limit orders
|
1624
|
+
# "buy 0.12345678 ETHUSDT @ market" # market order
|
1625
|
+
# "sell 0.28002676 ETHUSDT @ stop loss 0.0123 -> limit 0.0.1222" # stop order
|
1626
|
+
# "sell 0.00100000 ETHUSDT @ stop loss 2677.00 -> limit 2577.00 with 5:1 leverage"
|
1627
|
+
# "buy 0.10000000 LTCUSDT @ take profit 75.00000 -> limit 74.00000"
|
1628
|
+
# "sell 10.00000000 XRPEUR @ trailing stop +50.0000%" # trailing stop
|
1629
|
+
# },
|
1413
1630
|
# "txid": ['OEKVV2-IH52O-TPL6GZ']
|
1414
1631
|
# }
|
1415
|
-
# {
|
1416
|
-
# "txid": ["TX_ID_HERE"],
|
1417
|
-
# "descr": {"order":"buy 0.12345678 ETHEUR @ market"},
|
1418
|
-
# }
|
1419
|
-
#
|
1420
|
-
#
|
1421
|
-
# createOrder for stop orders
|
1422
|
-
#
|
1423
|
-
# {
|
1424
|
-
# "txid":["OSILNC-VQI5Q-775ZDQ"],
|
1425
|
-
# "descr":{"order":"sell 167.28002676 ADAXBT @ stop loss 0.00003280 -> limit 0.00003212"}
|
1426
|
-
# }
|
1427
|
-
#
|
1428
|
-
#
|
1429
|
-
# {
|
1430
|
-
# "txid":["OVHMJV-BZW2V-6NZFWF"],
|
1431
|
-
# "descr":{"order":"sell 0.00100000 ETHUSD @ stop loss 2677.00 -> limit 2577.00 with 5:1 leverage"}
|
1432
|
-
# }
|
1433
1632
|
#
|
1434
1633
|
# editOrder
|
1435
1634
|
#
|
1436
1635
|
# {
|
1437
|
-
# "
|
1438
|
-
# "txid": "OAW2BO-7RWEK-PZY5UO",
|
1439
|
-
# "originaltxid": "OXL6SS-UPNMC-26WBE7",
|
1440
|
-
# "volume": "0.00075000",
|
1441
|
-
# "price": "13500.0",
|
1442
|
-
# "orders_cancelled": 1,
|
1443
|
-
# "descr": {
|
1444
|
-
# "order": "buy 0.00075000 XBTUSDT @ limit 13500.0"
|
1445
|
-
# }
|
1636
|
+
# "amend_id": "TJSMEH-AA67V-YUSQ6O"
|
1446
1637
|
# }
|
1638
|
+
#
|
1447
1639
|
# ws - createOrder
|
1448
1640
|
# {
|
1449
1641
|
# "descr": 'sell 0.00010000 XBTUSDT @ market',
|
@@ -1497,31 +1689,68 @@ class kraken(Exchange, ImplicitAPI):
|
|
1497
1689
|
# }
|
1498
1690
|
# }
|
1499
1691
|
#
|
1692
|
+
# fetchOpenOrders
|
1693
|
+
#
|
1694
|
+
# {
|
1695
|
+
# "refid": null,
|
1696
|
+
# "userref": null,
|
1697
|
+
# "cl_ord_id": "1234",
|
1698
|
+
# "status": "open",
|
1699
|
+
# "opentm": 1733815269.370054,
|
1700
|
+
# "starttm": 0,
|
1701
|
+
# "expiretm": 0,
|
1702
|
+
# "descr": {
|
1703
|
+
# "pair": "XBTUSD",
|
1704
|
+
# "type": "buy",
|
1705
|
+
# "ordertype": "limit",
|
1706
|
+
# "price": "70000.0",
|
1707
|
+
# "price2": "0",
|
1708
|
+
# "leverage": "none",
|
1709
|
+
# "order": "buy 0.00010000 XBTUSD @ limit 70000.0",
|
1710
|
+
# "close": ""
|
1711
|
+
# },
|
1712
|
+
# "vol": "0.00010000",
|
1713
|
+
# "vol_exec": "0.00000000",
|
1714
|
+
# "cost": "0.00000",
|
1715
|
+
# "fee": "0.00000",
|
1716
|
+
# "price": "0.00000",
|
1717
|
+
# "stopprice": "0.00000",
|
1718
|
+
# "limitprice": "0.00000",
|
1719
|
+
# "misc": "",
|
1720
|
+
# "oflags": "fciq"
|
1721
|
+
# }
|
1722
|
+
#
|
1500
1723
|
description = self.safe_dict(order, 'descr', {})
|
1724
|
+
orderDescriptionObj = self.safe_dict(order, 'descr') # can be null
|
1501
1725
|
orderDescription = None
|
1502
|
-
if
|
1503
|
-
orderDescription = self.safe_string(
|
1726
|
+
if orderDescriptionObj is not None:
|
1727
|
+
orderDescription = self.safe_string(orderDescriptionObj, 'order')
|
1504
1728
|
else:
|
1505
1729
|
orderDescription = self.safe_string(order, 'descr')
|
1506
1730
|
side = None
|
1507
|
-
|
1731
|
+
rawType = None
|
1508
1732
|
marketId = None
|
1509
1733
|
price = None
|
1510
1734
|
amount = None
|
1511
|
-
|
1735
|
+
triggerPrice = None
|
1512
1736
|
if orderDescription is not None:
|
1513
1737
|
parts = orderDescription.split(' ')
|
1514
1738
|
side = self.safe_string(parts, 0)
|
1515
1739
|
amount = self.safe_string(parts, 1)
|
1516
1740
|
marketId = self.safe_string(parts, 2)
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1741
|
+
part4 = self.safe_string(parts, 4)
|
1742
|
+
part5 = self.safe_string(parts, 5)
|
1743
|
+
if part4 == 'limit' or part4 == 'market':
|
1744
|
+
rawType = part4 # eg, limit, market
|
1745
|
+
else:
|
1746
|
+
rawType = part4 + ' ' + part5 # eg. stop loss, take profit, trailing stop
|
1747
|
+
if rawType == 'stop loss' or rawType == 'take profit':
|
1748
|
+
triggerPrice = self.safe_string(parts, 6)
|
1520
1749
|
price = self.safe_string(parts, 9)
|
1521
|
-
elif
|
1750
|
+
elif rawType == 'limit':
|
1522
1751
|
price = self.safe_string(parts, 5)
|
1523
1752
|
side = self.safe_string(description, 'type', side)
|
1524
|
-
|
1753
|
+
rawType = self.safe_string(description, 'ordertype', rawType) # orderType has dash, e.g. trailing-stop
|
1525
1754
|
marketId = self.safe_string(description, 'pair', marketId)
|
1526
1755
|
foundMarket = self.find_market_by_altname_or_id(marketId)
|
1527
1756
|
symbol = None
|
@@ -1560,11 +1789,12 @@ class kraken(Exchange, ImplicitAPI):
|
|
1560
1789
|
elif flags.find('fcib') >= 0:
|
1561
1790
|
fee['currency'] = market['base']
|
1562
1791
|
status = self.parse_order_status(self.safe_string(order, 'status'))
|
1563
|
-
id = self.
|
1564
|
-
if (id is None) or (id
|
1565
|
-
txid = self.
|
1792
|
+
id = self.safe_string_n(order, ['id', 'txid', 'amend_id'])
|
1793
|
+
if (id is None) or (id.startswith('[')):
|
1794
|
+
txid = self.safe_list(order, 'txid')
|
1566
1795
|
id = self.safe_string(txid, 0)
|
1567
|
-
|
1796
|
+
userref = self.safe_string(order, 'userref')
|
1797
|
+
clientOrderId = self.safe_string(order, 'cl_ord_id', userref)
|
1568
1798
|
rawTrades = self.safe_value(order, 'trades', [])
|
1569
1799
|
trades = []
|
1570
1800
|
for i in range(0, len(rawTrades)):
|
@@ -1573,15 +1803,32 @@ class kraken(Exchange, ImplicitAPI):
|
|
1573
1803
|
trades.append(self.safe_trade({'id': rawTrade, 'orderId': id, 'symbol': symbol, 'info': {}}))
|
1574
1804
|
else:
|
1575
1805
|
trades.append(rawTrade)
|
1576
|
-
|
1806
|
+
# in #24192 PR, self field is not something consistent/actual
|
1807
|
+
# triggerPrice = self.omit_zero(self.safe_string(order, 'stopprice', triggerPrice))
|
1577
1808
|
stopLossPrice = None
|
1578
1809
|
takeProfitPrice = None
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1810
|
+
# the dashed strings are not provided from fields(eg. fetch order)
|
1811
|
+
# while spaced strings from "order" sentence(when other fields not available)
|
1812
|
+
if rawType is not None:
|
1813
|
+
if rawType.startswith('take-profit'):
|
1814
|
+
takeProfitPrice = self.safe_string(description, 'price')
|
1815
|
+
price = self.omit_zero(self.safe_string(description, 'price2'))
|
1816
|
+
elif rawType.startswith('stop-loss'):
|
1817
|
+
stopLossPrice = self.safe_string(description, 'price')
|
1818
|
+
price = self.omit_zero(self.safe_string(description, 'price2'))
|
1819
|
+
elif rawType == 'take profit':
|
1820
|
+
takeProfitPrice = triggerPrice
|
1821
|
+
elif rawType == 'stop loss':
|
1822
|
+
stopLossPrice = triggerPrice
|
1823
|
+
finalType = self.parse_order_type(rawType)
|
1824
|
+
# unlike from endpoints which provide eg: "take-profit-limit"
|
1825
|
+
# for "space-delimited" orders we dont have market/limit suffixes, their format is
|
1826
|
+
# eg: `stop loss > limit 123`, so we need to parse them manually
|
1827
|
+
if self.in_array(finalType, ['stop loss', 'take profit']):
|
1828
|
+
finalType = 'market' if (price is None) else 'limit'
|
1829
|
+
amendId = self.safe_string(order, 'amend_id')
|
1830
|
+
if amendId is not None:
|
1831
|
+
isPostOnly = None
|
1585
1832
|
return self.safe_order({
|
1586
1833
|
'id': id,
|
1587
1834
|
'clientOrderId': clientOrderId,
|
@@ -1591,13 +1838,12 @@ class kraken(Exchange, ImplicitAPI):
|
|
1591
1838
|
'lastTradeTimestamp': None,
|
1592
1839
|
'status': status,
|
1593
1840
|
'symbol': symbol,
|
1594
|
-
'type':
|
1841
|
+
'type': finalType,
|
1595
1842
|
'timeInForce': None,
|
1596
1843
|
'postOnly': isPostOnly,
|
1597
1844
|
'side': side,
|
1598
1845
|
'price': price,
|
1599
|
-
'
|
1600
|
-
'triggerPrice': stopPrice,
|
1846
|
+
'triggerPrice': triggerPrice,
|
1601
1847
|
'takeProfitPrice': takeProfitPrice,
|
1602
1848
|
'stopLossPrice': stopLossPrice,
|
1603
1849
|
'cost': None,
|
@@ -1605,27 +1851,43 @@ class kraken(Exchange, ImplicitAPI):
|
|
1605
1851
|
'filled': filled,
|
1606
1852
|
'average': average,
|
1607
1853
|
'remaining': None,
|
1854
|
+
'reduceOnly': self.safe_bool_2(order, 'reduceOnly', 'reduce_only'),
|
1608
1855
|
'fee': fee,
|
1609
1856
|
'trades': trades,
|
1610
1857
|
}, market)
|
1611
1858
|
|
1612
|
-
def order_request(self, method, symbol, type, request, price=None, params={}):
|
1613
|
-
clientOrderId = self.
|
1614
|
-
params = self.omit(params, ['
|
1859
|
+
def order_request(self, method: str, symbol: str, type: str, request: dict, amount: Num, price: Num = None, params={}):
|
1860
|
+
clientOrderId = self.safe_string(params, 'clientOrderId')
|
1861
|
+
params = self.omit(params, ['clientOrderId'])
|
1615
1862
|
if clientOrderId is not None:
|
1616
|
-
request['
|
1863
|
+
request['cl_ord_id'] = clientOrderId
|
1617
1864
|
stopLossTriggerPrice = self.safe_string(params, 'stopLossPrice')
|
1618
1865
|
takeProfitTriggerPrice = self.safe_string(params, 'takeProfitPrice')
|
1619
1866
|
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
1620
1867
|
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
1621
1868
|
isStopLossOrTakeProfitTrigger = isStopLossTriggerOrder or isTakeProfitTriggerOrder
|
1622
1869
|
trailingAmount = self.safe_string(params, 'trailingAmount')
|
1870
|
+
trailingPercent = self.safe_string(params, 'trailingPercent')
|
1623
1871
|
trailingLimitAmount = self.safe_string(params, 'trailingLimitAmount')
|
1872
|
+
trailingLimitPercent = self.safe_string(params, 'trailingLimitPercent')
|
1624
1873
|
isTrailingAmountOrder = trailingAmount is not None
|
1874
|
+
isTrailingPercentOrder = trailingPercent is not None
|
1625
1875
|
isLimitOrder = type.endswith('limit') # supporting limit, stop-loss-limit, take-profit-limit, etc
|
1626
|
-
|
1876
|
+
isMarketOrder = type == 'market'
|
1877
|
+
cost = self.safe_string(params, 'cost')
|
1878
|
+
flags = self.safe_string(params, 'oflags')
|
1879
|
+
params = self.omit(params, ['cost', 'oflags'])
|
1880
|
+
isViqcOrder = (flags is not None) and (flags.find('viqc') > -1) # volume in quote currency
|
1881
|
+
if isMarketOrder and (cost is not None or isViqcOrder):
|
1882
|
+
if cost is None and (amount is not None):
|
1883
|
+
request['volume'] = self.cost_to_precision(symbol, self.number_to_string(amount))
|
1884
|
+
else:
|
1885
|
+
request['volume'] = self.cost_to_precision(symbol, cost)
|
1886
|
+
extendedOflags = flags + ',viqc' if (flags is not None) else 'viqc'
|
1887
|
+
request['oflags'] = extendedOflags
|
1888
|
+
elif isLimitOrder and not isTrailingAmountOrder and not isTrailingPercentOrder:
|
1627
1889
|
request['price'] = self.price_to_precision(symbol, price)
|
1628
|
-
reduceOnly = self.
|
1890
|
+
reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only')
|
1629
1891
|
if isStopLossOrTakeProfitTrigger:
|
1630
1892
|
if isStopLossTriggerOrder:
|
1631
1893
|
request['price'] = self.price_to_precision(symbol, stopLossTriggerPrice)
|
@@ -1641,22 +1903,36 @@ class kraken(Exchange, ImplicitAPI):
|
|
1641
1903
|
request['ordertype'] = 'take-profit'
|
1642
1904
|
if isLimitOrder:
|
1643
1905
|
request['price2'] = self.price_to_precision(symbol, price)
|
1644
|
-
elif isTrailingAmountOrder:
|
1906
|
+
elif isTrailingAmountOrder or isTrailingPercentOrder:
|
1907
|
+
trailingPercentString = None
|
1908
|
+
if trailingPercent is not None:
|
1909
|
+
trailingPercentString = ('+' + trailingPercent) if (trailingPercent.endswith('%')) else ('+' + trailingPercent + '%')
|
1910
|
+
trailingAmountString = '+' + trailingAmount if (trailingAmount is not None) else None # must use + for self
|
1911
|
+
offset = self.safe_string(params, 'offset', '-') # can use + or - for self
|
1912
|
+
trailingLimitAmountString = offset + self.number_to_string(trailingLimitAmount) if (trailingLimitAmount is not None) else None
|
1645
1913
|
trailingActivationPriceType = self.safe_string(params, 'trigger', 'last')
|
1646
|
-
trailingAmountString = '+' + trailingAmount
|
1647
1914
|
request['trigger'] = trailingActivationPriceType
|
1648
|
-
if isLimitOrder or (trailingLimitAmount is not None):
|
1649
|
-
offset = self.safe_string(params, 'offset', '-')
|
1650
|
-
trailingLimitAmountString = offset + self.number_to_string(trailingLimitAmount)
|
1651
|
-
request['price'] = trailingAmountString
|
1652
|
-
request['price2'] = trailingLimitAmountString
|
1915
|
+
if isLimitOrder or (trailingLimitAmount is not None) or (trailingLimitPercent is not None):
|
1653
1916
|
request['ordertype'] = 'trailing-stop-limit'
|
1917
|
+
if trailingLimitPercent is not None:
|
1918
|
+
trailingLimitPercentString = (offset + trailingLimitPercent) if (trailingLimitPercent.endswith('%')) else (offset + trailingLimitPercent + '%')
|
1919
|
+
request['price'] = trailingPercentString
|
1920
|
+
request['price2'] = trailingLimitPercentString
|
1921
|
+
elif trailingLimitAmount is not None:
|
1922
|
+
request['price'] = trailingAmountString
|
1923
|
+
request['price2'] = trailingLimitAmountString
|
1654
1924
|
else:
|
1655
|
-
request['price'] = trailingAmountString
|
1656
1925
|
request['ordertype'] = 'trailing-stop'
|
1926
|
+
if trailingPercent is not None:
|
1927
|
+
request['price'] = trailingPercentString
|
1928
|
+
else:
|
1929
|
+
request['price'] = trailingAmountString
|
1657
1930
|
if reduceOnly:
|
1658
|
-
|
1659
|
-
|
1931
|
+
if method == 'createOrderWs':
|
1932
|
+
request['reduce_only'] = True # ws request can't have stringified bool
|
1933
|
+
else:
|
1934
|
+
request['reduce_only'] = 'true' # not using hasattr(self, boolean) case, because the urlencodedNested transforms it into 'True' string
|
1935
|
+
close = self.safe_dict(params, 'close')
|
1660
1936
|
if close is not None:
|
1661
1937
|
close = self.extend({}, close)
|
1662
1938
|
closePrice = self.safe_value(close, 'price')
|
@@ -1673,81 +1949,101 @@ class kraken(Exchange, ImplicitAPI):
|
|
1673
1949
|
postOnly = None
|
1674
1950
|
postOnly, params = self.handle_post_only(isMarket, False, params)
|
1675
1951
|
if postOnly:
|
1676
|
-
|
1677
|
-
|
1952
|
+
extendedPostFlags = flags + ',post' if (flags is not None) else 'post'
|
1953
|
+
request['oflags'] = extendedPostFlags
|
1954
|
+
if (flags is not None) and not ('oflags' in request):
|
1955
|
+
request['oflags'] = flags
|
1956
|
+
params = self.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'trailingLimitAmount', 'trailingLimitPercent', 'offset'])
|
1678
1957
|
return [request, params]
|
1679
1958
|
|
1680
1959
|
def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
1681
1960
|
"""
|
1682
1961
|
edit a trade order
|
1683
|
-
|
1962
|
+
|
1963
|
+
https://docs.kraken.com/api/docs/rest-api/amend-order
|
1964
|
+
|
1684
1965
|
:param str id: order id
|
1685
1966
|
:param str symbol: unified symbol of the market to create an order in
|
1686
1967
|
:param str type: 'market' or 'limit'
|
1687
1968
|
:param str side: 'buy' or 'sell'
|
1688
|
-
:param float amount: how much of the currency you want to trade in units of the base currency
|
1689
|
-
:param float [price]: the price at which the order is to be
|
1969
|
+
:param float [amount]: how much of the currency you want to trade in units of the base currency
|
1970
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
1690
1971
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1691
|
-
:param float [params.stopLossPrice]:
|
1692
|
-
:param float [params.takeProfitPrice]:
|
1693
|
-
:param str [params.trailingAmount]:
|
1694
|
-
:param str [params.
|
1695
|
-
:param str [params.
|
1696
|
-
:param str [params.
|
1972
|
+
:param float [params.stopLossPrice]: the price that a stop loss order is triggered at
|
1973
|
+
:param float [params.takeProfitPrice]: the price that a take profit order is triggered at
|
1974
|
+
:param str [params.trailingAmount]: the quote amount to trail away from the current market price
|
1975
|
+
:param str [params.trailingPercent]: the percent to trail away from the current market price
|
1976
|
+
:param str [params.trailingLimitAmount]: the quote amount away from the trailingAmount
|
1977
|
+
:param str [params.trailingLimitPercent]: the percent away from the trailingAmount
|
1978
|
+
:param str [params.offset]: '+' or '-' whether you want the trailingLimitAmount value to be positive or negative
|
1979
|
+
:param boolean [params.postOnly]: if True, the order will only be posted to the order book and not executed immediately
|
1980
|
+
:param str [params.clientOrderId]: the orders client order id
|
1697
1981
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1698
1982
|
"""
|
1699
1983
|
self.load_markets()
|
1700
1984
|
market = self.market(symbol)
|
1701
1985
|
if not market['spot']:
|
1702
1986
|
raise NotSupported(self.id + ' editOrder() does not support ' + market['type'] + ' orders, only spot orders are accepted')
|
1703
|
-
request = {
|
1987
|
+
request: dict = {
|
1704
1988
|
'txid': id,
|
1705
|
-
'pair': market['id'],
|
1706
1989
|
}
|
1990
|
+
clientOrderId = self.safe_string_2(params, 'clientOrderId', 'cl_ord_id')
|
1991
|
+
if clientOrderId is not None:
|
1992
|
+
request['cl_ord_id'] = clientOrderId
|
1993
|
+
params = self.omit(params, ['clientOrderId', 'cl_ord_id'])
|
1994
|
+
request = self.omit(request, 'txid')
|
1995
|
+
isMarket = (type == 'market')
|
1996
|
+
postOnly = None
|
1997
|
+
postOnly, params = self.handle_post_only(isMarket, False, params)
|
1998
|
+
if postOnly:
|
1999
|
+
request['post_only'] = 'true' # not using hasattr(self, boolean) case, because the urlencodedNested transforms it into 'True' string
|
1707
2000
|
if amount is not None:
|
1708
|
-
request['
|
1709
|
-
|
1710
|
-
|
2001
|
+
request['order_qty'] = self.amount_to_precision(symbol, amount)
|
2002
|
+
if price is not None:
|
2003
|
+
request['limit_price'] = self.price_to_precision(symbol, price)
|
2004
|
+
allTriggerPrices = self.safe_string_n(params, ['stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'trailingLimitAmount', 'trailingLimitPercent'])
|
2005
|
+
if allTriggerPrices is not None:
|
2006
|
+
offset = self.safe_string(params, 'offset')
|
2007
|
+
params = self.omit(params, ['stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'trailingLimitAmount', 'trailingLimitPercent', 'offset'])
|
2008
|
+
if offset is not None:
|
2009
|
+
allTriggerPrices = offset + allTriggerPrices
|
2010
|
+
request['trigger_price'] = allTriggerPrices
|
2011
|
+
else:
|
2012
|
+
request['trigger_price'] = self.price_to_precision(symbol, allTriggerPrices)
|
2013
|
+
response = self.privatePostAmendOrder(self.extend(request, params))
|
1711
2014
|
#
|
1712
2015
|
# {
|
1713
2016
|
# "error": [],
|
1714
2017
|
# "result": {
|
1715
|
-
# "
|
1716
|
-
# "txid": "OAW2BO-7RWEK-PZY5UO",
|
1717
|
-
# "originaltxid": "OXL6SS-UPNMC-26WBE7",
|
1718
|
-
# "volume": "0.00075000",
|
1719
|
-
# "price": "13500.0",
|
1720
|
-
# "orders_cancelled": 1,
|
1721
|
-
# "descr": {
|
1722
|
-
# "order": "buy 0.00075000 XBTUSDT @ limit 13500.0"
|
1723
|
-
# }
|
2018
|
+
# "amend_id": "TJSMEH-AA67V-YUSQ6O"
|
1724
2019
|
# }
|
1725
2020
|
# }
|
1726
2021
|
#
|
1727
|
-
|
1728
|
-
return self.parse_order(
|
2022
|
+
result = self.safe_dict(response, 'result', {})
|
2023
|
+
return self.parse_order(result, market)
|
1729
2024
|
|
1730
2025
|
def fetch_order(self, id: str, symbol: Str = None, params={}):
|
1731
2026
|
"""
|
1732
2027
|
fetches information on an order made by the user
|
1733
|
-
|
2028
|
+
|
2029
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getOrdersInfo
|
2030
|
+
|
2031
|
+
:param str id: order id
|
1734
2032
|
:param str symbol: not used by kraken fetchOrder
|
1735
2033
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1736
2034
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1737
2035
|
"""
|
1738
2036
|
self.load_markets()
|
1739
2037
|
clientOrderId = self.safe_value_2(params, 'userref', 'clientOrderId')
|
1740
|
-
request = {
|
2038
|
+
request: dict = {
|
1741
2039
|
'trades': True, # whether or not to include trades in output(optional, default False)
|
1742
|
-
|
2040
|
+
'txid': id, # do not comma separate a list of ids - use fetchOrdersByIds instead
|
1743
2041
|
# 'userref': 'optional', # restrict results to given user reference id(optional)
|
1744
2042
|
}
|
1745
2043
|
query = params
|
1746
2044
|
if clientOrderId is not None:
|
1747
2045
|
request['userref'] = clientOrderId
|
1748
2046
|
query = self.omit(params, ['userref', 'clientOrderId'])
|
1749
|
-
else:
|
1750
|
-
request['txid'] = id
|
1751
2047
|
response = self.privatePostQueryOrders(self.extend(request, query))
|
1752
2048
|
#
|
1753
2049
|
# {
|
@@ -1794,7 +2090,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
1794
2090
|
def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
1795
2091
|
"""
|
1796
2092
|
fetch all the trades made from a single order
|
1797
|
-
|
2093
|
+
|
2094
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getTradesInfo
|
2095
|
+
|
1798
2096
|
:param str id: order id
|
1799
2097
|
:param str symbol: unified market symbol
|
1800
2098
|
:param int [since]: the earliest time in ms to fetch trades for
|
@@ -1828,7 +2126,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
1828
2126
|
index = self.sum(j * batchSize, k)
|
1829
2127
|
if index < numTradeIds:
|
1830
2128
|
requestIds.append(tradeIds[index])
|
1831
|
-
request = {
|
2129
|
+
request: dict = {
|
1832
2130
|
'txid': ','.join(requestIds),
|
1833
2131
|
}
|
1834
2132
|
response = self.privatePostQueryTrades(request)
|
@@ -1865,8 +2163,11 @@ class kraken(Exchange, ImplicitAPI):
|
|
1865
2163
|
def fetch_orders_by_ids(self, ids, symbol: Str = None, params={}):
|
1866
2164
|
"""
|
1867
2165
|
fetch orders by the list of order id
|
1868
|
-
|
1869
|
-
|
2166
|
+
|
2167
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getClosedOrders
|
2168
|
+
|
2169
|
+
:param str[] [ids]: list of order id
|
2170
|
+
:param str [symbol]: unified ccxt market symbol
|
1870
2171
|
:param dict [params]: extra parameters specific to the kraken api endpoint
|
1871
2172
|
:returns dict[]: a list of `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1872
2173
|
"""
|
@@ -1888,15 +2189,19 @@ class kraken(Exchange, ImplicitAPI):
|
|
1888
2189
|
def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
1889
2190
|
"""
|
1890
2191
|
fetch all trades made by the user
|
1891
|
-
|
2192
|
+
|
2193
|
+
https://docs.kraken.com/api/docs/rest-api/get-trade-history
|
2194
|
+
|
1892
2195
|
:param str symbol: unified market symbol
|
1893
2196
|
:param int [since]: the earliest time in ms to fetch trades for
|
1894
2197
|
:param int [limit]: the maximum number of trades structures to retrieve
|
1895
2198
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2199
|
+
:param int [params.until]: timestamp in ms of the latest trade entry
|
2200
|
+
:param int [params.end]: timestamp in seconds of the latest trade entry
|
1896
2201
|
:returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
1897
2202
|
"""
|
1898
2203
|
self.load_markets()
|
1899
|
-
request = {
|
2204
|
+
request: dict = {
|
1900
2205
|
# 'type': 'all', # any position, closed position, closing position, no position
|
1901
2206
|
# 'trades': False, # whether or not to include trades related to position in output
|
1902
2207
|
# 'start': 1234567890, # starting unix timestamp or trade tx id of results(exclusive)
|
@@ -1905,6 +2210,11 @@ class kraken(Exchange, ImplicitAPI):
|
|
1905
2210
|
}
|
1906
2211
|
if since is not None:
|
1907
2212
|
request['start'] = self.parse_to_int(since / 1000)
|
2213
|
+
until = self.safe_string_n(params, ['until', 'till'])
|
2214
|
+
if until is not None:
|
2215
|
+
params = self.omit(params, ['until', 'till'])
|
2216
|
+
untilDivided = Precise.string_div(until, '1000')
|
2217
|
+
request['end'] = self.parse_to_int(Precise.string_add(untilDivided, '1'))
|
1908
2218
|
response = self.privatePostTradesHistory(self.extend(request, params))
|
1909
2219
|
#
|
1910
2220
|
# {
|
@@ -1923,7 +2233,10 @@ class kraken(Exchange, ImplicitAPI):
|
|
1923
2233
|
# "fee": "0.000026",
|
1924
2234
|
# "vol": "16.00000000",
|
1925
2235
|
# "margin": "0.000000",
|
2236
|
+
# "leverage": "5",
|
1926
2237
|
# "misc": ""
|
2238
|
+
# "trade_id": 68230622,
|
2239
|
+
# "maker": False
|
1927
2240
|
# },
|
1928
2241
|
# ...
|
1929
2242
|
# },
|
@@ -1943,38 +2256,59 @@ class kraken(Exchange, ImplicitAPI):
|
|
1943
2256
|
def cancel_order(self, id: str, symbol: Str = None, params={}):
|
1944
2257
|
"""
|
1945
2258
|
cancels an open order
|
1946
|
-
|
2259
|
+
|
2260
|
+
https://docs.kraken.com/api/docs/rest-api/cancel-order
|
2261
|
+
|
1947
2262
|
:param str id: order id
|
1948
|
-
:param str symbol: unified symbol of the market the order was made in
|
2263
|
+
:param str [symbol]: unified symbol of the market the order was made in
|
1949
2264
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1950
|
-
:
|
2265
|
+
:param str [params.clientOrderId]: the orders client order id
|
2266
|
+
:param int [params.userref]: the orders user reference id
|
2267
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1951
2268
|
"""
|
1952
2269
|
self.load_markets()
|
1953
2270
|
response = None
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
2271
|
+
requestId = self.safe_value(params, 'userref', id) # string or integer
|
2272
|
+
params = self.omit(params, 'userref')
|
2273
|
+
request: dict = {
|
2274
|
+
'txid': requestId, # order id or userref
|
1957
2275
|
}
|
1958
|
-
|
2276
|
+
clientOrderId = self.safe_string_2(params, 'clientOrderId', 'cl_ord_id')
|
2277
|
+
if clientOrderId is not None:
|
2278
|
+
request['cl_ord_id'] = clientOrderId
|
2279
|
+
params = self.omit(params, ['clientOrderId', 'cl_ord_id'])
|
2280
|
+
request = self.omit(request, 'txid')
|
1959
2281
|
try:
|
1960
2282
|
response = self.privatePostCancelOrder(self.extend(request, params))
|
2283
|
+
#
|
2284
|
+
# {
|
2285
|
+
# error: [],
|
2286
|
+
# result: {
|
2287
|
+
# count: '1'
|
2288
|
+
# }
|
2289
|
+
# }
|
2290
|
+
#
|
1961
2291
|
except Exception as e:
|
1962
2292
|
if self.last_http_response:
|
1963
2293
|
if self.last_http_response.find('EOrder:Unknown order') >= 0:
|
1964
2294
|
raise OrderNotFound(self.id + ' cancelOrder() error ' + self.last_http_response)
|
1965
2295
|
raise e
|
1966
|
-
return
|
2296
|
+
return self.safe_order({
|
2297
|
+
'info': response,
|
2298
|
+
})
|
1967
2299
|
|
1968
2300
|
def cancel_orders(self, ids, symbol: Str = None, params={}):
|
1969
2301
|
"""
|
1970
2302
|
cancel multiple orders
|
1971
|
-
|
2303
|
+
|
2304
|
+
https://docs.kraken.com/rest/#tag/Spot-Trading/operation/cancelOrderBatch
|
2305
|
+
|
1972
2306
|
:param str[] ids: open orders transaction ID(txid) or user reference(userref)
|
1973
2307
|
:param str symbol: unified market symbol
|
1974
2308
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1975
2309
|
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1976
2310
|
"""
|
1977
|
-
request = {
|
2311
|
+
request: dict = {
|
1978
2312
|
'orders': ids,
|
1979
2313
|
}
|
1980
2314
|
response = self.privatePostCancelOrderBatch(self.extend(request, params))
|
@@ -1986,68 +2320,172 @@ class kraken(Exchange, ImplicitAPI):
|
|
1986
2320
|
# }
|
1987
2321
|
# }
|
1988
2322
|
#
|
1989
|
-
return
|
2323
|
+
return [
|
2324
|
+
self.safe_order({
|
2325
|
+
'info': response,
|
2326
|
+
}),
|
2327
|
+
]
|
1990
2328
|
|
1991
2329
|
def cancel_all_orders(self, symbol: Str = None, params={}):
|
1992
2330
|
"""
|
1993
2331
|
cancel all open orders
|
1994
|
-
|
2332
|
+
|
2333
|
+
https://docs.kraken.com/rest/#tag/Spot-Trading/operation/cancelAllOrders
|
2334
|
+
|
1995
2335
|
:param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
|
1996
2336
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1997
2337
|
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1998
2338
|
"""
|
1999
2339
|
self.load_markets()
|
2000
|
-
|
2340
|
+
response = self.privatePostCancelAll(params)
|
2341
|
+
#
|
2342
|
+
# {
|
2343
|
+
# error: [],
|
2344
|
+
# result: {
|
2345
|
+
# count: '1'
|
2346
|
+
# }
|
2347
|
+
# }
|
2348
|
+
#
|
2349
|
+
return [
|
2350
|
+
self.safe_order({
|
2351
|
+
'info': response,
|
2352
|
+
}),
|
2353
|
+
]
|
2354
|
+
|
2355
|
+
def cancel_all_orders_after(self, timeout: Int, params={}):
|
2356
|
+
"""
|
2357
|
+
dead man's switch, cancel all orders after the given timeout
|
2358
|
+
|
2359
|
+
https://docs.kraken.com/rest/#tag/Spot-Trading/operation/cancelAllOrdersAfter
|
2360
|
+
|
2361
|
+
:param number timeout: time in milliseconds, 0 represents cancel the timer
|
2362
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2363
|
+
:returns dict: the api result
|
2364
|
+
"""
|
2365
|
+
if timeout > 86400000:
|
2366
|
+
raise BadRequest(self.id + 'cancelAllOrdersAfter timeout should be less than 86400000 milliseconds')
|
2367
|
+
self.load_markets()
|
2368
|
+
request: dict = {
|
2369
|
+
'timeout': (self.parse_to_int(timeout / 1000)) if (timeout > 0) else 0,
|
2370
|
+
}
|
2371
|
+
response = self.privatePostCancelAllOrdersAfter(self.extend(request, params))
|
2372
|
+
#
|
2373
|
+
# {
|
2374
|
+
# "error": [],
|
2375
|
+
# "result": {
|
2376
|
+
# "currentTime": "2023-03-24T17:41:56Z",
|
2377
|
+
# "triggerTime": "2023-03-24T17:42:56Z"
|
2378
|
+
# }
|
2379
|
+
# }
|
2380
|
+
#
|
2381
|
+
return response
|
2001
2382
|
|
2002
2383
|
def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
2003
2384
|
"""
|
2004
2385
|
fetch all unfilled currently open orders
|
2005
|
-
|
2006
|
-
|
2386
|
+
|
2387
|
+
https://docs.kraken.com/api/docs/rest-api/get-open-orders
|
2388
|
+
|
2389
|
+
:param str [symbol]: unified market symbol
|
2007
2390
|
:param int [since]: the earliest time in ms to fetch open orders for
|
2008
2391
|
:param int [limit]: the maximum number of open orders structures to retrieve
|
2009
2392
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2393
|
+
:param str [params.clientOrderId]: the orders client order id
|
2394
|
+
:param int [params.userref]: the orders user reference id
|
2010
2395
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
2011
2396
|
"""
|
2012
2397
|
self.load_markets()
|
2013
|
-
request = {}
|
2398
|
+
request: dict = {}
|
2014
2399
|
if since is not None:
|
2015
2400
|
request['start'] = self.parse_to_int(since / 1000)
|
2016
|
-
|
2017
|
-
|
2401
|
+
userref = self.safe_integer(params, 'userref')
|
2402
|
+
if userref is not None:
|
2403
|
+
request['userref'] = userref
|
2404
|
+
params = self.omit(params, 'userref')
|
2405
|
+
clientOrderId = self.safe_string(params, 'clientOrderId')
|
2018
2406
|
if clientOrderId is not None:
|
2019
|
-
request['
|
2020
|
-
|
2021
|
-
response = self.privatePostOpenOrders(self.extend(request,
|
2407
|
+
request['cl_ord_id'] = clientOrderId
|
2408
|
+
params = self.omit(params, 'clientOrderId')
|
2409
|
+
response = self.privatePostOpenOrders(self.extend(request, params))
|
2410
|
+
#
|
2411
|
+
# {
|
2412
|
+
# "error": [],
|
2413
|
+
# "result": {
|
2414
|
+
# "open": {
|
2415
|
+
# "O45M52-BFD5S-YXKQOU": {
|
2416
|
+
# "refid": null,
|
2417
|
+
# "userref": null,
|
2418
|
+
# "cl_ord_id": "1234",
|
2419
|
+
# "status": "open",
|
2420
|
+
# "opentm": 1733815269.370054,
|
2421
|
+
# "starttm": 0,
|
2422
|
+
# "expiretm": 0,
|
2423
|
+
# "descr": {
|
2424
|
+
# "pair": "XBTUSD",
|
2425
|
+
# "type": "buy",
|
2426
|
+
# "ordertype": "limit",
|
2427
|
+
# "price": "70000.0",
|
2428
|
+
# "price2": "0",
|
2429
|
+
# "leverage": "none",
|
2430
|
+
# "order": "buy 0.00010000 XBTUSD @ limit 70000.0",
|
2431
|
+
# "close": ""
|
2432
|
+
# },
|
2433
|
+
# "vol": "0.00010000",
|
2434
|
+
# "vol_exec": "0.00000000",
|
2435
|
+
# "cost": "0.00000",
|
2436
|
+
# "fee": "0.00000",
|
2437
|
+
# "price": "0.00000",
|
2438
|
+
# "stopprice": "0.00000",
|
2439
|
+
# "limitprice": "0.00000",
|
2440
|
+
# "misc": "",
|
2441
|
+
# "oflags": "fciq"
|
2442
|
+
# }
|
2443
|
+
# }
|
2444
|
+
# }
|
2445
|
+
# }
|
2446
|
+
#
|
2022
2447
|
market = None
|
2023
2448
|
if symbol is not None:
|
2024
2449
|
market = self.market(symbol)
|
2025
|
-
result = self.
|
2026
|
-
|
2450
|
+
result = self.safe_dict(response, 'result', {})
|
2451
|
+
open = self.safe_dict(result, 'open', {})
|
2452
|
+
orders = []
|
2453
|
+
orderIds = list(open.keys())
|
2454
|
+
for i in range(0, len(orderIds)):
|
2455
|
+
id = orderIds[i]
|
2456
|
+
item = open[id]
|
2457
|
+
orders.append(self.extend({'id': id}, item))
|
2027
2458
|
return self.parse_orders(orders, market, since, limit)
|
2028
2459
|
|
2029
2460
|
def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
2030
2461
|
"""
|
2031
2462
|
fetches information on multiple closed orders made by the user
|
2032
|
-
|
2033
|
-
|
2463
|
+
|
2464
|
+
https://docs.kraken.com/api/docs/rest-api/get-closed-orders
|
2465
|
+
|
2466
|
+
:param str [symbol]: unified market symbol of the market orders were made in
|
2034
2467
|
:param int [since]: the earliest time in ms to fetch orders for
|
2035
2468
|
:param int [limit]: the maximum number of order structures to retrieve
|
2036
2469
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2037
2470
|
:param int [params.until]: timestamp in ms of the latest entry
|
2471
|
+
:param str [params.clientOrderId]: the orders client order id
|
2472
|
+
:param int [params.userref]: the orders user reference id
|
2038
2473
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
2039
2474
|
"""
|
2040
2475
|
self.load_markets()
|
2041
|
-
request = {}
|
2476
|
+
request: dict = {}
|
2042
2477
|
if since is not None:
|
2043
2478
|
request['start'] = self.parse_to_int(since / 1000)
|
2044
|
-
|
2045
|
-
|
2479
|
+
userref = self.safe_integer(params, 'userref')
|
2480
|
+
if userref is not None:
|
2481
|
+
request['userref'] = userref
|
2482
|
+
params = self.omit(params, 'userref')
|
2483
|
+
clientOrderId = self.safe_string(params, 'clientOrderId')
|
2046
2484
|
if clientOrderId is not None:
|
2047
|
-
request['
|
2048
|
-
|
2485
|
+
request['cl_ord_id'] = clientOrderId
|
2486
|
+
params = self.omit(params, 'clientOrderId')
|
2049
2487
|
request, params = self.handle_until_option('end', request, params)
|
2050
|
-
response = self.privatePostClosedOrders(self.extend(request,
|
2488
|
+
response = self.privatePostClosedOrders(self.extend(request, params))
|
2051
2489
|
#
|
2052
2490
|
# {
|
2053
2491
|
# "error":[],
|
@@ -2090,13 +2528,19 @@ class kraken(Exchange, ImplicitAPI):
|
|
2090
2528
|
market = None
|
2091
2529
|
if symbol is not None:
|
2092
2530
|
market = self.market(symbol)
|
2093
|
-
result = self.
|
2094
|
-
|
2531
|
+
result = self.safe_dict(response, 'result', {})
|
2532
|
+
closed = self.safe_dict(result, 'closed', {})
|
2533
|
+
orders = []
|
2534
|
+
orderIds = list(closed.keys())
|
2535
|
+
for i in range(0, len(orderIds)):
|
2536
|
+
id = orderIds[i]
|
2537
|
+
item = closed[id]
|
2538
|
+
orders.append(self.extend({'id': id}, item))
|
2095
2539
|
return self.parse_orders(orders, market, since, limit)
|
2096
2540
|
|
2097
|
-
def parse_transaction_status(self, status):
|
2541
|
+
def parse_transaction_status(self, status: Str):
|
2098
2542
|
# IFEX transaction states
|
2099
|
-
statuses = {
|
2543
|
+
statuses: dict = {
|
2100
2544
|
'Initial': 'pending',
|
2101
2545
|
'Pending': 'pending',
|
2102
2546
|
'Success': 'ok',
|
@@ -2110,7 +2554,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
2110
2554
|
withdrawMethods = self.safe_value(self.options, 'withdrawMethods', {})
|
2111
2555
|
return self.safe_string(withdrawMethods, network, network)
|
2112
2556
|
|
2113
|
-
def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
|
2557
|
+
def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
|
2114
2558
|
#
|
2115
2559
|
# fetchDeposits
|
2116
2560
|
#
|
@@ -2228,23 +2672,31 @@ class kraken(Exchange, ImplicitAPI):
|
|
2228
2672
|
def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
2229
2673
|
"""
|
2230
2674
|
fetch all deposits made to an account
|
2231
|
-
|
2675
|
+
|
2676
|
+
https://docs.kraken.com/rest/#tag/Funding/operation/getStatusRecentDeposits
|
2677
|
+
|
2232
2678
|
:param str code: unified currency code
|
2233
2679
|
:param int [since]: the earliest time in ms to fetch deposits for
|
2234
2680
|
:param int [limit]: the maximum number of deposits structures to retrieve
|
2235
2681
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2682
|
+
:param int [params.until]: timestamp in ms of the latest transaction entry
|
2683
|
+
:param int [params.end]: timestamp in seconds of the latest transaction entry
|
2236
2684
|
:returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
|
2237
2685
|
"""
|
2238
2686
|
# https://www.kraken.com/en-us/help/api#deposit-status
|
2239
|
-
if code is None:
|
2240
|
-
raise ArgumentsRequired(self.id + ' fetchDeposits() requires a currency code argument')
|
2241
2687
|
self.load_markets()
|
2242
|
-
|
2243
|
-
|
2244
|
-
|
2245
|
-
|
2688
|
+
request: dict = {}
|
2689
|
+
if code is not None:
|
2690
|
+
currency = self.currency(code)
|
2691
|
+
request['asset'] = currency['id']
|
2246
2692
|
if since is not None:
|
2247
|
-
|
2693
|
+
sinceString = self.number_to_string(since)
|
2694
|
+
request['start'] = Precise.string_div(sinceString, '1000')
|
2695
|
+
until = self.safe_string_n(params, ['until', 'till'])
|
2696
|
+
if until is not None:
|
2697
|
+
params = self.omit(params, ['until', 'till'])
|
2698
|
+
untilDivided = Precise.string_div(until, '1000')
|
2699
|
+
request['end'] = Precise.string_add(untilDivided, '1')
|
2248
2700
|
response = self.privatePostDepositStatus(self.extend(request, params))
|
2249
2701
|
#
|
2250
2702
|
# { error: [],
|
@@ -2264,7 +2716,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
2264
2716
|
def fetch_time(self, params={}):
|
2265
2717
|
"""
|
2266
2718
|
fetches the current integer timestamp in milliseconds from the exchange server
|
2267
|
-
|
2719
|
+
|
2720
|
+
https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getServerTime
|
2721
|
+
|
2268
2722
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2269
2723
|
:returns int: the current integer timestamp in milliseconds from the exchange server
|
2270
2724
|
"""
|
@@ -2285,13 +2739,16 @@ class kraken(Exchange, ImplicitAPI):
|
|
2285
2739
|
def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
2286
2740
|
"""
|
2287
2741
|
fetch all withdrawals made from an account
|
2288
|
-
|
2742
|
+
|
2743
|
+
https://docs.kraken.com/rest/#tag/Funding/operation/getStatusRecentWithdrawals
|
2744
|
+
|
2289
2745
|
:param str code: unified currency code
|
2290
2746
|
:param int [since]: the earliest time in ms to fetch withdrawals for
|
2291
2747
|
:param int [limit]: the maximum number of withdrawals structures to retrieve
|
2292
2748
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2293
|
-
:param
|
2294
|
-
:param
|
2749
|
+
:param int [params.until]: timestamp in ms of the latest transaction entry
|
2750
|
+
:param int [params.end]: timestamp in seconds of the latest transaction entry
|
2751
|
+
:param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times
|
2295
2752
|
:returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
|
2296
2753
|
"""
|
2297
2754
|
self.load_markets()
|
@@ -2300,12 +2757,18 @@ class kraken(Exchange, ImplicitAPI):
|
|
2300
2757
|
if paginate:
|
2301
2758
|
params['cursor'] = True
|
2302
2759
|
return self.fetch_paginated_call_cursor('fetchWithdrawals', code, since, limit, params, 'next_cursor', 'cursor')
|
2303
|
-
request = {}
|
2760
|
+
request: dict = {}
|
2304
2761
|
if code is not None:
|
2305
2762
|
currency = self.currency(code)
|
2306
2763
|
request['asset'] = currency['id']
|
2307
2764
|
if since is not None:
|
2308
|
-
|
2765
|
+
sinceString = self.number_to_string(since)
|
2766
|
+
request['start'] = Precise.string_div(sinceString, '1000')
|
2767
|
+
until = self.safe_string_n(params, ['until', 'till'])
|
2768
|
+
if until is not None:
|
2769
|
+
params = self.omit(params, ['until', 'till'])
|
2770
|
+
untilDivided = Precise.string_div(until, '1000')
|
2771
|
+
request['end'] = Precise.string_add(untilDivided, '1')
|
2309
2772
|
response = self.privatePostWithdrawStatus(self.extend(request, params))
|
2310
2773
|
#
|
2311
2774
|
# with no pagination
|
@@ -2366,12 +2829,14 @@ class kraken(Exchange, ImplicitAPI):
|
|
2366
2829
|
def create_deposit_address(self, code: str, params={}):
|
2367
2830
|
"""
|
2368
2831
|
create a currency deposit address
|
2369
|
-
|
2832
|
+
|
2833
|
+
https://docs.kraken.com/rest/#tag/Funding/operation/getDepositAddresses
|
2834
|
+
|
2370
2835
|
:param str code: unified currency code of the currency for the deposit address
|
2371
2836
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2372
2837
|
:returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
|
2373
2838
|
"""
|
2374
|
-
request = {
|
2839
|
+
request: dict = {
|
2375
2840
|
'new': 'true',
|
2376
2841
|
}
|
2377
2842
|
return self.fetch_deposit_address(code, self.extend(request, params))
|
@@ -2379,14 +2844,16 @@ class kraken(Exchange, ImplicitAPI):
|
|
2379
2844
|
def fetch_deposit_methods(self, code: str, params={}):
|
2380
2845
|
"""
|
2381
2846
|
fetch deposit methods for a currency associated with self account
|
2382
|
-
|
2847
|
+
|
2848
|
+
https://docs.kraken.com/rest/#tag/Funding/operation/getDepositMethods
|
2849
|
+
|
2383
2850
|
:param str code: unified currency code
|
2384
2851
|
:param dict [params]: extra parameters specific to the kraken api endpoint
|
2385
2852
|
:returns dict: of deposit methods
|
2386
2853
|
"""
|
2387
2854
|
self.load_markets()
|
2388
2855
|
currency = self.currency(code)
|
2389
|
-
request = {
|
2856
|
+
request: dict = {
|
2390
2857
|
'asset': currency['id'],
|
2391
2858
|
}
|
2392
2859
|
response = self.privatePostDepositMethods(self.extend(request, params))
|
@@ -2415,10 +2882,12 @@ class kraken(Exchange, ImplicitAPI):
|
|
2415
2882
|
#
|
2416
2883
|
return self.safe_value(response, 'result')
|
2417
2884
|
|
2418
|
-
def fetch_deposit_address(self, code: str, params={}):
|
2885
|
+
def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
|
2419
2886
|
"""
|
2420
2887
|
fetch the deposit address for a currency associated with self account
|
2421
|
-
|
2888
|
+
|
2889
|
+
https://docs.kraken.com/rest/#tag/Funding/operation/getDepositAddresses
|
2890
|
+
|
2422
2891
|
:param str code: unified currency code
|
2423
2892
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2424
2893
|
:returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
|
@@ -2449,7 +2918,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
2449
2918
|
if depositMethod is None:
|
2450
2919
|
firstDepositMethod = self.safe_value(depositMethods, 0, {})
|
2451
2920
|
depositMethod = self.safe_string(firstDepositMethod, 'method')
|
2452
|
-
request = {
|
2921
|
+
request: dict = {
|
2453
2922
|
'asset': currency['id'],
|
2454
2923
|
'method': depositMethod,
|
2455
2924
|
}
|
@@ -2468,7 +2937,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
2468
2937
|
raise InvalidAddress(self.id + ' privatePostDepositAddresses() returned no addresses for ' + code)
|
2469
2938
|
return self.parse_deposit_address(firstResult, currency)
|
2470
2939
|
|
2471
|
-
def parse_deposit_address(self, depositAddress, currency: Currency = None):
|
2940
|
+
def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
|
2472
2941
|
#
|
2473
2942
|
# {
|
2474
2943
|
# "address":"0x77b5051f97efa9cc52c9ad5b023a53fc15c200d3",
|
@@ -2481,17 +2950,19 @@ class kraken(Exchange, ImplicitAPI):
|
|
2481
2950
|
code = currency['code']
|
2482
2951
|
self.check_address(address)
|
2483
2952
|
return {
|
2953
|
+
'info': depositAddress,
|
2484
2954
|
'currency': code,
|
2955
|
+
'network': None,
|
2485
2956
|
'address': address,
|
2486
2957
|
'tag': tag,
|
2487
|
-
'network': None,
|
2488
|
-
'info': depositAddress,
|
2489
2958
|
}
|
2490
2959
|
|
2491
|
-
def withdraw(self, code: str, amount: float, address, tag=None, params={}):
|
2960
|
+
def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
|
2492
2961
|
"""
|
2493
2962
|
make a withdrawal
|
2494
|
-
|
2963
|
+
|
2964
|
+
https://docs.kraken.com/rest/#tag/Funding/operation/withdrawFunds
|
2965
|
+
|
2495
2966
|
:param str code: unified currency code
|
2496
2967
|
:param float amount: the amount to withdraw
|
2497
2968
|
:param str address: the address to withdraw to
|
@@ -2504,7 +2975,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
2504
2975
|
if 'key' in params:
|
2505
2976
|
self.load_markets()
|
2506
2977
|
currency = self.currency(code)
|
2507
|
-
request = {
|
2978
|
+
request: dict = {
|
2508
2979
|
'asset': currency['id'],
|
2509
2980
|
'amount': amount,
|
2510
2981
|
'address': address,
|
@@ -2518,23 +2989,25 @@ class kraken(Exchange, ImplicitAPI):
|
|
2518
2989
|
# }
|
2519
2990
|
# }
|
2520
2991
|
#
|
2521
|
-
result = self.
|
2992
|
+
result = self.safe_dict(response, 'result', {})
|
2522
2993
|
return self.parse_transaction(result, currency)
|
2523
2994
|
raise ExchangeError(self.id + " withdraw() requires a 'key' parameter(withdrawal key name, up on your account)")
|
2524
2995
|
|
2525
2996
|
def fetch_positions(self, symbols: Strings = None, params={}):
|
2526
2997
|
"""
|
2527
2998
|
fetch all open positions
|
2528
|
-
|
2529
|
-
|
2999
|
+
|
3000
|
+
https://docs.kraken.com/rest/#tag/Account-Data/operation/getOpenPositions
|
3001
|
+
|
3002
|
+
:param str[] [symbols]: not used by kraken fetchPositions()
|
2530
3003
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2531
3004
|
:returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
2532
3005
|
"""
|
2533
3006
|
self.load_markets()
|
2534
|
-
request = {
|
3007
|
+
request: dict = {
|
2535
3008
|
# 'txid': 'comma delimited list of transaction ids to restrict output to',
|
2536
|
-
|
2537
|
-
|
3009
|
+
'docalcs': 'true', # whether or not to include profit/loss calculations
|
3010
|
+
'consolidation': 'market', # what to consolidate the positions data around, market will consolidate positions based on market pair
|
2538
3011
|
}
|
2539
3012
|
response = self.privatePostOpenPositions(self.extend(request, params))
|
2540
3013
|
#
|
@@ -2582,12 +3055,61 @@ class kraken(Exchange, ImplicitAPI):
|
|
2582
3055
|
# ]
|
2583
3056
|
# }
|
2584
3057
|
#
|
2585
|
-
|
2586
|
-
|
2587
|
-
|
3058
|
+
symbols = self.market_symbols(symbols)
|
3059
|
+
result = self.safe_list(response, 'result')
|
3060
|
+
results = self.parse_positions(result, symbols)
|
3061
|
+
return self.filter_by_array_positions(results, 'symbol', symbols, False)
|
3062
|
+
|
3063
|
+
def parse_position(self, position: dict, market: Market = None):
|
3064
|
+
#
|
3065
|
+
# {
|
3066
|
+
# "pair": "ETHUSDT",
|
3067
|
+
# "positions": "1",
|
3068
|
+
# "type": "buy",
|
3069
|
+
# "leverage": "2.00000",
|
3070
|
+
# "cost": "28.49800",
|
3071
|
+
# "fee": "0.07979",
|
3072
|
+
# "vol": "0.02000000",
|
3073
|
+
# "vol_closed": "0.00000000",
|
3074
|
+
# "margin": "14.24900"
|
3075
|
+
# }
|
3076
|
+
#
|
3077
|
+
marketId = self.safe_string(position, 'pair')
|
3078
|
+
rawSide = self.safe_string(position, 'type')
|
3079
|
+
side = 'long' if (rawSide == 'buy') else 'short'
|
3080
|
+
return self.safe_position({
|
3081
|
+
'info': position,
|
3082
|
+
'id': None,
|
3083
|
+
'symbol': self.safe_symbol(marketId, market),
|
3084
|
+
'notional': None,
|
3085
|
+
'marginMode': None,
|
3086
|
+
'liquidationPrice': None,
|
3087
|
+
'entryPrice': None,
|
3088
|
+
'unrealizedPnl': self.safe_number(position, 'net'),
|
3089
|
+
'realizedPnl': None,
|
3090
|
+
'percentage': None,
|
3091
|
+
'contracts': self.safe_number(position, 'vol'),
|
3092
|
+
'contractSize': None,
|
3093
|
+
'markPrice': None,
|
3094
|
+
'lastPrice': None,
|
3095
|
+
'side': side,
|
3096
|
+
'hedged': None,
|
3097
|
+
'timestamp': None,
|
3098
|
+
'datetime': None,
|
3099
|
+
'lastUpdateTimestamp': None,
|
3100
|
+
'maintenanceMargin': None,
|
3101
|
+
'maintenanceMarginPercentage': None,
|
3102
|
+
'collateral': None,
|
3103
|
+
'initialMargin': self.safe_number(position, 'margin'),
|
3104
|
+
'initialMarginPercentage': None,
|
3105
|
+
'leverage': self.safe_number(position, 'leverage'),
|
3106
|
+
'marginRatio': None,
|
3107
|
+
'stopLossPrice': None,
|
3108
|
+
'takeProfitPrice': None,
|
3109
|
+
})
|
2588
3110
|
|
2589
3111
|
def parse_account_type(self, account):
|
2590
|
-
accountByType = {
|
3112
|
+
accountByType: dict = {
|
2591
3113
|
'spot': 'Spot Wallet',
|
2592
3114
|
'swap': 'Futures Wallet',
|
2593
3115
|
'future': 'Futures Wallet',
|
@@ -2597,7 +3119,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
2597
3119
|
def transfer_out(self, code: str, amount, params={}):
|
2598
3120
|
"""
|
2599
3121
|
transfer from spot wallet to futures wallet
|
2600
|
-
|
3122
|
+
|
3123
|
+
https://docs.kraken.com/rest/#tag/User-Funding/operation/walletTransfer
|
3124
|
+
|
2601
3125
|
:param str code: Unified currency code
|
2602
3126
|
:param float amount: Size of the transfer
|
2603
3127
|
:param dict [params]: Exchange specific parameters
|
@@ -2607,7 +3131,9 @@ class kraken(Exchange, ImplicitAPI):
|
|
2607
3131
|
|
2608
3132
|
def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
2609
3133
|
"""
|
2610
|
-
|
3134
|
+
|
3135
|
+
https://docs.kraken.com/rest/#tag/User-Funding/operation/walletTransfer
|
3136
|
+
|
2611
3137
|
transfers currencies between sub-accounts(only spot->swap direction is supported)
|
2612
3138
|
:param str code: Unified currency code
|
2613
3139
|
:param float amount: Size of the transfer
|
@@ -2620,7 +3146,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
2620
3146
|
currency = self.currency(code)
|
2621
3147
|
fromAccount = self.parse_account_type(fromAccount)
|
2622
3148
|
toAccount = self.parse_account_type(toAccount)
|
2623
|
-
request = {
|
3149
|
+
request: dict = {
|
2624
3150
|
'amount': self.currency_to_precision(code, amount),
|
2625
3151
|
'from': fromAccount,
|
2626
3152
|
'to': toAccount,
|
@@ -2645,7 +3171,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
2645
3171
|
'toAccount': toAccount,
|
2646
3172
|
})
|
2647
3173
|
|
2648
|
-
def parse_transfer(self, transfer, currency: Currency = None):
|
3174
|
+
def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
|
2649
3175
|
#
|
2650
3176
|
# transfer
|
2651
3177
|
#
|
@@ -2678,11 +3204,15 @@ class kraken(Exchange, ImplicitAPI):
|
|
2678
3204
|
# urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
|
2679
3205
|
url += '?' + self.urlencode_nested(params)
|
2680
3206
|
elif api == 'private':
|
3207
|
+
price = self.safe_string(params, 'price')
|
3208
|
+
isTriggerPercent = False
|
3209
|
+
if price is not None:
|
3210
|
+
isTriggerPercent = True if (price.endswith('%')) else False
|
2681
3211
|
isCancelOrderBatch = (path == 'CancelOrderBatch')
|
2682
3212
|
self.check_required_credentials()
|
2683
3213
|
nonce = str(self.nonce())
|
2684
3214
|
# urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
|
2685
|
-
if isCancelOrderBatch:
|
3215
|
+
if isCancelOrderBatch or isTriggerPercent:
|
2686
3216
|
body = self.json(self.extend({'nonce': nonce}, params))
|
2687
3217
|
else:
|
2688
3218
|
body = self.urlencode_nested(self.extend({'nonce': nonce}, params))
|
@@ -2695,9 +3225,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
2695
3225
|
headers = {
|
2696
3226
|
'API-Key': self.apiKey,
|
2697
3227
|
'API-Sign': signature,
|
2698
|
-
# 'Content-Type': 'application/x-www-form-urlencoded',
|
2699
3228
|
}
|
2700
|
-
if isCancelOrderBatch:
|
3229
|
+
if isCancelOrderBatch or isTriggerPercent:
|
2701
3230
|
headers['Content-Type'] = 'application/json'
|
2702
3231
|
else:
|
2703
3232
|
headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
@@ -2707,24 +3236,11 @@ class kraken(Exchange, ImplicitAPI):
|
|
2707
3236
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
2708
3237
|
|
2709
3238
|
def nonce(self):
|
2710
|
-
return self.milliseconds()
|
3239
|
+
return self.milliseconds() - self.options['timeDifference']
|
2711
3240
|
|
2712
|
-
def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
3241
|
+
def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
2713
3242
|
if code == 520:
|
2714
3243
|
raise ExchangeNotAvailable(self.id + ' ' + str(code) + ' ' + reason)
|
2715
|
-
# todo: rewrite self for "broad" exceptions matching
|
2716
|
-
if body.find('Invalid order') >= 0:
|
2717
|
-
raise InvalidOrder(self.id + ' ' + body)
|
2718
|
-
if body.find('Invalid nonce') >= 0:
|
2719
|
-
raise InvalidNonce(self.id + ' ' + body)
|
2720
|
-
if body.find('Insufficient funds') >= 0:
|
2721
|
-
raise InsufficientFunds(self.id + ' ' + body)
|
2722
|
-
if body.find('Cancel pending') >= 0:
|
2723
|
-
raise CancelPending(self.id + ' ' + body)
|
2724
|
-
if body.find('Invalid arguments:volume') >= 0:
|
2725
|
-
raise InvalidOrder(self.id + ' ' + body)
|
2726
|
-
if body.find('Rate limit exceeded') >= 0:
|
2727
|
-
raise RateLimitExceeded(self.id + ' ' + body)
|
2728
3244
|
if response is None:
|
2729
3245
|
return None
|
2730
3246
|
if body[0] == '{':
|
@@ -2735,6 +3251,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
2735
3251
|
message = self.id + ' ' + body
|
2736
3252
|
for i in range(0, len(response['error'])):
|
2737
3253
|
error = response['error'][i]
|
2738
|
-
self.throw_exactly_matched_exception(self.exceptions, error, message)
|
3254
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], error, message)
|
3255
|
+
self.throw_exactly_matched_exception(self.exceptions['broad'], error, message)
|
2739
3256
|
raise ExchangeError(message)
|
2740
3257
|
return None
|