ccxt-ir 4.3.46.0.3__py2.py3-none-any.whl → 4.5.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +39 -35
- ccxt/abantether.py +8 -8
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/apex.py +31 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +106 -48
- ccxt/abstract/binancecoinm.py +106 -48
- ccxt/abstract/binanceus.py +141 -83
- ccxt/abstract/binanceusdm.py +106 -48
- ccxt/abstract/bingx.py +50 -1
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +67 -0
- ccxt/abstract/bitmart.py +19 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitrue.py +68 -68
- ccxt/abstract/bitstamp.py +1 -0
- ccxt/abstract/blofin.py +30 -0
- ccxt/abstract/btcbox.py +2 -0
- ccxt/abstract/bybit.py +28 -13
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbaseexchange.py +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/cryptocom.py +16 -0
- ccxt/abstract/cryptomus.py +20 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/derive.py +117 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/foxbit.py +26 -0
- ccxt/abstract/gate.py +19 -0
- ccxt/abstract/gateio.py +19 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hibachi.py +26 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +1 -0
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +10 -0
- ccxt/abstract/kucoinfutures.py +18 -0
- ccxt/abstract/lbank.py +2 -1
- ccxt/abstract/luno.py +1 -0
- ccxt/abstract/mexc.py +2 -0
- ccxt/abstract/modetrade.py +119 -0
- ccxt/abstract/myokx.py +349 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +25 -0
- ccxt/abstract/okxus.py +349 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/paradex.py +23 -0
- ccxt/abstract/phemex.py +2 -0
- ccxt/abstract/poloniex.py +36 -0
- ccxt/abstract/tradeogre.py +3 -1
- ccxt/abstract/upbit.py +51 -34
- ccxt/abstract/whitebit.py +16 -0
- ccxt/abstract/woo.py +64 -6
- ccxt/abstract/xt.py +10 -5
- ccxt/afratether.py +7 -7
- ccxt/alpaca.py +828 -51
- ccxt/apex.py +1875 -0
- ccxt/arzinja.py +7 -7
- ccxt/arzplus.py +9 -9
- ccxt/ascendex.py +501 -306
- ccxt/async_support/__init__.py +39 -35
- ccxt/async_support/abantether.py +8 -8
- ccxt/async_support/afratether.py +9 -9
- ccxt/async_support/alpaca.py +828 -51
- ccxt/async_support/apex.py +1875 -0
- ccxt/async_support/arzinja.py +10 -10
- ccxt/async_support/arzplus.py +12 -12
- ccxt/async_support/ascendex.py +502 -306
- ccxt/async_support/base/exchange.py +303 -89
- ccxt/async_support/base/ws/cache.py +9 -3
- ccxt/async_support/base/ws/client.py +173 -38
- ccxt/async_support/base/ws/future.py +25 -37
- ccxt/async_support/bequant.py +5 -3
- ccxt/async_support/bigone.py +279 -144
- ccxt/async_support/binance.py +2347 -1158
- ccxt/async_support/binancecoinm.py +9 -3
- ccxt/async_support/binanceus.py +17 -3
- ccxt/async_support/binanceusdm.py +9 -4
- ccxt/async_support/bingx.py +2962 -920
- ccxt/async_support/bit2c.py +147 -27
- ccxt/async_support/bitbank.py +151 -23
- ccxt/async_support/bitbns.py +104 -30
- ccxt/async_support/bitfinex.py +3291 -1113
- ccxt/async_support/bitflyer.py +202 -27
- ccxt/async_support/bitget.py +3683 -1538
- ccxt/async_support/bithumb.py +195 -38
- ccxt/async_support/bitimen.py +12 -12
- ccxt/async_support/bitir.py +38 -38
- ccxt/async_support/bitmart.py +1288 -350
- ccxt/async_support/bitmex.py +260 -75
- ccxt/async_support/bitopro.py +262 -62
- ccxt/async_support/bitpin.py +17 -16
- ccxt/async_support/bitrue.py +459 -290
- ccxt/async_support/bitso.py +199 -54
- ccxt/async_support/bitstamp.py +230 -96
- ccxt/async_support/bitteam.py +167 -25
- ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
- ccxt/async_support/bitvavo.py +213 -49
- ccxt/async_support/blockchaincom.py +160 -46
- ccxt/async_support/blofin.py +502 -120
- ccxt/async_support/btcalpha.py +169 -31
- ccxt/async_support/btcbox.py +292 -23
- ccxt/async_support/btcmarkets.py +211 -58
- ccxt/async_support/btcturk.py +161 -38
- ccxt/async_support/bybit.py +1775 -1030
- ccxt/async_support/cex.py +1440 -1303
- ccxt/async_support/coinbase.py +724 -212
- ccxt/async_support/coinbaseadvanced.py +2 -1
- ccxt/async_support/coinbaseexchange.py +388 -89
- ccxt/async_support/coinbaseinternational.py +412 -57
- ccxt/async_support/coincatch.py +177 -78
- ccxt/async_support/coincheck.py +135 -19
- ccxt/async_support/coinex.py +606 -232
- ccxt/async_support/coinmate.py +189 -63
- ccxt/async_support/coinmetro.py +195 -54
- ccxt/async_support/coinone.py +158 -51
- ccxt/async_support/coinsph.py +336 -61
- ccxt/async_support/coinspot.py +151 -52
- ccxt/async_support/cryptocom.py +661 -111
- ccxt/async_support/cryptomus.py +1137 -0
- ccxt/async_support/defx.py +2071 -0
- ccxt/async_support/delta.py +299 -99
- ccxt/async_support/deribit.py +348 -126
- ccxt/async_support/derive.py +2572 -0
- ccxt/async_support/digifinex.py +430 -214
- ccxt/async_support/ellipx.py +2029 -0
- ccxt/async_support/eterex.py +10 -10
- ccxt/async_support/excoino.py +31 -31
- ccxt/async_support/exir.py +14 -14
- ccxt/async_support/exmo.py +344 -131
- ccxt/async_support/exnovin.py +10 -10
- ccxt/async_support/farhadexchange.py +12 -12
- ccxt/async_support/fmfwio.py +2 -1
- ccxt/async_support/foxbit.py +1935 -0
- ccxt/async_support/gate.py +1351 -529
- ccxt/async_support/gateio.py +2 -1
- ccxt/async_support/gemini.py +144 -39
- ccxt/async_support/hashkey.py +152 -109
- ccxt/async_support/hibachi.py +2080 -0
- ccxt/async_support/hitbtc.py +395 -167
- ccxt/async_support/hitobit.py +12 -12
- ccxt/async_support/hollaex.py +307 -119
- ccxt/async_support/htx.py +851 -383
- ccxt/async_support/huobi.py +2 -1
- ccxt/async_support/hyperliquid.py +1848 -536
- ccxt/async_support/independentreserve.py +288 -15
- ccxt/async_support/indodax.py +190 -33
- ccxt/async_support/jibitex.py +12 -12
- ccxt/async_support/kraken.py +795 -351
- ccxt/async_support/krakenfutures.py +214 -62
- ccxt/async_support/kucoin.py +715 -396
- ccxt/async_support/kucoinfutures.py +652 -89
- ccxt/async_support/latoken.py +217 -113
- ccxt/async_support/lbank.py +425 -97
- ccxt/async_support/luno.py +382 -35
- ccxt/async_support/mercado.py +113 -6
- ccxt/async_support/mexc.py +874 -437
- ccxt/async_support/modetrade.py +2818 -0
- ccxt/async_support/myokx.py +54 -0
- ccxt/async_support/ndax.py +221 -64
- ccxt/async_support/nobitex.py +31 -37
- ccxt/async_support/novadax.py +190 -34
- ccxt/async_support/oceanex.py +217 -28
- ccxt/async_support/okcoin.py +253 -145
- ccxt/async_support/okexchange.py +11 -11
- ccxt/async_support/okx.py +1088 -351
- ccxt/async_support/okxus.py +54 -0
- ccxt/async_support/ompfinex.py +25 -24
- ccxt/async_support/onetrading.py +213 -392
- ccxt/async_support/oxfun.py +245 -166
- ccxt/async_support/p2b.py +151 -29
- ccxt/async_support/paradex.py +562 -49
- ccxt/async_support/paymium.py +82 -19
- ccxt/async_support/phemex.py +713 -172
- ccxt/async_support/poloniex.py +1602 -283
- ccxt/async_support/probit.py +224 -95
- ccxt/async_support/ramzinex.py +30 -27
- ccxt/async_support/sarmayex.py +9 -9
- ccxt/async_support/sarrafex.py +13 -13
- ccxt/async_support/tabdeal.py +14 -13
- ccxt/async_support/tetherland.py +9 -9
- ccxt/async_support/timex.py +210 -51
- ccxt/async_support/tokocrypto.py +167 -47
- ccxt/async_support/tradeogre.py +266 -31
- ccxt/async_support/twox.py +9 -9
- ccxt/async_support/ubitex.py +12 -12
- ccxt/async_support/upbit.py +568 -165
- ccxt/async_support/vertex.py +160 -32
- ccxt/async_support/wallex.py +12 -12
- ccxt/async_support/wavesexchange.py +165 -30
- ccxt/async_support/whitebit.py +975 -127
- ccxt/async_support/woo.py +1918 -1016
- ccxt/async_support/woofipro.py +433 -141
- ccxt/async_support/xt.py +649 -193
- ccxt/async_support/yobit.py +195 -70
- ccxt/async_support/zaif.py +91 -15
- ccxt/async_support/zonda.py +151 -36
- ccxt/base/decimal_to_precision.py +14 -10
- ccxt/base/errors.py +49 -18
- ccxt/base/exchange.py +1556 -450
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +114 -6
- ccxt/bequant.py +5 -3
- ccxt/bigone.py +279 -144
- ccxt/binance.py +2347 -1158
- ccxt/binancecoinm.py +9 -3
- ccxt/binanceus.py +17 -3
- ccxt/binanceusdm.py +9 -4
- ccxt/bingx.py +2962 -920
- ccxt/bit2c.py +147 -27
- ccxt/bitbank.py +151 -23
- ccxt/bitbns.py +104 -30
- ccxt/bitfinex.py +3290 -1113
- ccxt/bitflyer.py +202 -27
- ccxt/bitget.py +3683 -1538
- ccxt/bithumb.py +194 -38
- ccxt/bitimen.py +9 -9
- ccxt/bitir.py +35 -35
- ccxt/bitmart.py +1288 -350
- ccxt/bitmex.py +260 -75
- ccxt/bitopro.py +262 -62
- ccxt/bitpin.py +15 -14
- ccxt/bitrue.py +459 -290
- ccxt/bitso.py +199 -54
- ccxt/bitstamp.py +230 -96
- ccxt/bitteam.py +167 -25
- ccxt/{huobijp.py → bittrade.py} +158 -30
- ccxt/bitvavo.py +213 -49
- ccxt/blockchaincom.py +160 -46
- ccxt/blofin.py +502 -120
- ccxt/btcalpha.py +169 -31
- ccxt/btcbox.py +291 -23
- ccxt/btcmarkets.py +211 -58
- ccxt/btcturk.py +161 -38
- ccxt/bybit.py +1775 -1030
- ccxt/cex.py +1439 -1303
- ccxt/coinbase.py +724 -212
- ccxt/coinbaseadvanced.py +2 -1
- ccxt/coinbaseexchange.py +388 -89
- ccxt/coinbaseinternational.py +412 -57
- ccxt/coincatch.py +177 -78
- ccxt/coincheck.py +135 -19
- ccxt/coinex.py +606 -232
- ccxt/coinmate.py +189 -63
- ccxt/coinmetro.py +194 -54
- ccxt/coinone.py +158 -51
- ccxt/coinsph.py +336 -61
- ccxt/coinspot.py +151 -52
- ccxt/cryptocom.py +661 -111
- ccxt/cryptomus.py +1137 -0
- ccxt/defx.py +2070 -0
- ccxt/delta.py +299 -99
- ccxt/deribit.py +348 -126
- ccxt/derive.py +2571 -0
- ccxt/digifinex.py +430 -214
- ccxt/ellipx.py +2029 -0
- ccxt/eterex.py +7 -7
- ccxt/excoino.py +29 -29
- ccxt/exir.py +11 -11
- ccxt/exmo.py +343 -131
- ccxt/exnovin.py +8 -8
- ccxt/farhadexchange.py +10 -10
- ccxt/fmfwio.py +2 -1
- ccxt/foxbit.py +1935 -0
- ccxt/gate.py +1351 -529
- ccxt/gateio.py +2 -1
- ccxt/gemini.py +144 -39
- ccxt/hashkey.py +152 -109
- ccxt/hibachi.py +2079 -0
- ccxt/hitbtc.py +395 -167
- ccxt/hitobit.py +9 -9
- ccxt/hollaex.py +307 -119
- ccxt/htx.py +851 -383
- ccxt/huobi.py +2 -1
- ccxt/hyperliquid.py +1848 -536
- ccxt/independentreserve.py +287 -15
- ccxt/indodax.py +190 -33
- ccxt/jibitex.py +9 -9
- ccxt/kraken.py +794 -351
- ccxt/krakenfutures.py +214 -62
- ccxt/kucoin.py +715 -396
- ccxt/kucoinfutures.py +652 -89
- ccxt/latoken.py +217 -113
- ccxt/lbank.py +425 -97
- ccxt/luno.py +382 -35
- ccxt/mercado.py +113 -6
- ccxt/mexc.py +873 -437
- ccxt/modetrade.py +2818 -0
- ccxt/myokx.py +54 -0
- ccxt/ndax.py +221 -64
- ccxt/nobitex.py +29 -35
- ccxt/novadax.py +190 -34
- ccxt/oceanex.py +217 -28
- ccxt/okcoin.py +253 -145
- ccxt/okexchange.py +9 -9
- ccxt/okx.py +1088 -351
- ccxt/okxus.py +54 -0
- ccxt/ompfinex.py +22 -21
- ccxt/onetrading.py +213 -392
- ccxt/oxfun.py +245 -166
- ccxt/p2b.py +151 -29
- ccxt/paradex.py +562 -49
- ccxt/paymium.py +82 -19
- ccxt/phemex.py +712 -172
- ccxt/poloniex.py +1601 -283
- ccxt/pro/__init__.py +76 -17
- ccxt/pro/alpaca.py +21 -6
- ccxt/pro/apex.py +984 -0
- ccxt/pro/ascendex.py +58 -10
- ccxt/pro/bequant.py +6 -1
- ccxt/pro/binance.py +728 -156
- ccxt/pro/binancecoinm.py +6 -2
- ccxt/pro/binanceus.py +8 -4
- ccxt/pro/binanceusdm.py +7 -2
- ccxt/pro/bingx.py +333 -142
- ccxt/pro/bitfinex.py +727 -262
- ccxt/pro/bitget.py +570 -79
- ccxt/pro/bithumb.py +20 -6
- ccxt/pro/bitmart.py +216 -87
- ccxt/pro/bitmex.py +47 -9
- ccxt/pro/bitopro.py +26 -14
- ccxt/pro/bitrue.py +22 -22
- ccxt/pro/bitstamp.py +54 -21
- ccxt/pro/{huobijp.py → bittrade.py} +7 -6
- ccxt/pro/bitvavo.py +191 -67
- ccxt/pro/blockchaincom.py +21 -8
- ccxt/pro/blofin.py +9 -1
- ccxt/pro/bybit.py +632 -245
- ccxt/pro/cex.py +59 -24
- ccxt/pro/coinbase.py +102 -73
- ccxt/pro/coinbaseadvanced.py +2 -1
- ccxt/pro/coinbaseexchange.py +8 -8
- ccxt/pro/coinbaseinternational.py +181 -25
- ccxt/pro/coincatch.py +6 -7
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +967 -665
- ccxt/pro/coinone.py +16 -9
- ccxt/pro/cryptocom.py +448 -45
- ccxt/pro/defx.py +831 -0
- ccxt/pro/deribit.py +150 -14
- ccxt/pro/derive.py +704 -0
- ccxt/pro/exmo.py +239 -6
- ccxt/pro/gate.py +623 -65
- ccxt/pro/gateio.py +2 -1
- ccxt/pro/gemini.py +27 -11
- ccxt/pro/hashkey.py +2 -2
- ccxt/pro/hitbtc.py +196 -91
- ccxt/pro/hollaex.py +23 -7
- ccxt/pro/htx.py +51 -14
- ccxt/pro/huobi.py +2 -1
- ccxt/pro/hyperliquid.py +591 -27
- ccxt/pro/independentreserve.py +9 -6
- ccxt/pro/kraken.py +640 -320
- ccxt/pro/krakenfutures.py +62 -35
- ccxt/pro/kucoin.py +267 -46
- ccxt/pro/kucoinfutures.py +165 -21
- ccxt/pro/lbank.py +102 -21
- ccxt/pro/luno.py +12 -8
- ccxt/pro/mexc.py +877 -111
- ccxt/pro/modetrade.py +1271 -0
- ccxt/pro/myokx.py +38 -0
- ccxt/pro/ndax.py +15 -2
- ccxt/pro/okcoin.py +23 -4
- ccxt/pro/okx.py +573 -98
- ccxt/pro/okxus.py +38 -0
- ccxt/pro/onetrading.py +30 -13
- ccxt/pro/oxfun.py +131 -27
- ccxt/pro/p2b.py +88 -22
- ccxt/pro/paradex.py +3 -3
- ccxt/pro/phemex.py +75 -21
- ccxt/pro/poloniex.py +124 -41
- ccxt/pro/probit.py +87 -80
- ccxt/pro/tradeogre.py +272 -0
- ccxt/pro/upbit.py +152 -12
- ccxt/pro/vertex.py +8 -3
- ccxt/pro/whitebit.py +58 -5
- ccxt/pro/woo.py +228 -37
- ccxt/pro/woofipro.py +106 -18
- ccxt/pro/xt.py +111 -5
- ccxt/probit.py +224 -95
- ccxt/protobuf/__init__.py +0 -0
- ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
- ccxt/protobuf/mexc/__init__.py +0 -0
- ccxt/ramzinex.py +28 -25
- ccxt/sarmayex.py +7 -7
- ccxt/sarrafex.py +10 -10
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/tabdeal.py +12 -11
- ccxt/test/tests_async.py +261 -57
- ccxt/test/tests_helpers.py +1 -3
- ccxt/test/tests_init.py +4 -3
- ccxt/test/tests_sync.py +261 -57
- ccxt/tetherland.py +7 -7
- ccxt/timex.py +210 -51
- ccxt/tokocrypto.py +167 -47
- ccxt/tradeogre.py +266 -31
- ccxt/twox.py +7 -7
- ccxt/ubitex.py +9 -9
- ccxt/upbit.py +568 -165
- ccxt/vertex.py +160 -32
- ccxt/wallex.py +9 -9
- ccxt/wavesexchange.py +165 -30
- ccxt/whitebit.py +975 -127
- ccxt/woo.py +1917 -1016
- ccxt/woofipro.py +432 -141
- ccxt/xt.py +649 -193
- ccxt/yobit.py +194 -70
- ccxt/zaif.py +91 -15
- ccxt/zonda.py +151 -36
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info}/METADATA +225 -73
- ccxt_ir-4.5.0.dist-info/RECORD +743 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info}/WHEEL +1 -1
- ccxt/__test__.py +0 -7
- ccxt/abstract/ace.py +0 -15
- ccxt/abstract/bitbay.py +0 -53
- ccxt/abstract/bitcoincom.py +0 -115
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/bitpanda.py +0 -35
- ccxt/abstract/bl3p.py +0 -19
- ccxt/abstract/coinlist.py +0 -54
- ccxt/abstract/currencycom.py +0 -68
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/abstract/idex.py +0 -26
- ccxt/abstract/kuna.py +0 -182
- ccxt/abstract/lykke.py +0 -29
- ccxt/abstract/poloniexfutures.py +0 -48
- ccxt/abstract/wazirx.py +0 -30
- ccxt/ace.py +0 -1012
- ccxt/async_support/ace.py +0 -1012
- ccxt/async_support/base/ws/aiohttp_client.py +0 -125
- ccxt/async_support/base/ws/fast_client.py +0 -96
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitcoincom.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3552
- ccxt/async_support/bitpanda.py +0 -16
- ccxt/async_support/bl3p.py +0 -485
- ccxt/async_support/coinlist.py +0 -2243
- ccxt/async_support/currencycom.py +0 -1950
- ccxt/async_support/hitbtc3.py +0 -16
- ccxt/async_support/idex.py +0 -1766
- ccxt/async_support/kuna.py +0 -1841
- ccxt/async_support/lykke.py +0 -1270
- ccxt/async_support/poloniexfutures.py +0 -1717
- ccxt/async_support/wazirx.py +0 -1224
- ccxt/bitbay.py +0 -17
- ccxt/bitcoincom.py +0 -17
- ccxt/bitfinex2.py +0 -3552
- ccxt/bitpanda.py +0 -16
- ccxt/bl3p.py +0 -485
- ccxt/coinlist.py +0 -2243
- ccxt/currencycom.py +0 -1950
- ccxt/hitbtc3.py +0 -16
- ccxt/idex.py +0 -1766
- ccxt/kuna.py +0 -1841
- ccxt/lykke.py +0 -1270
- ccxt/poloniexfutures.py +0 -1717
- ccxt/pro/bitcoincom.py +0 -34
- ccxt/pro/bitfinex2.py +0 -1083
- ccxt/pro/bitpanda.py +0 -15
- ccxt/pro/currencycom.py +0 -536
- ccxt/pro/idex.py +0 -672
- ccxt/pro/poloniexfutures.py +0 -990
- ccxt/pro/wazirx.py +0 -749
- ccxt/test/base/__init__.py +0 -29
- ccxt/test/base/test_account.py +0 -26
- ccxt/test/base/test_balance.py +0 -56
- ccxt/test/base/test_borrow_interest.py +0 -35
- ccxt/test/base/test_borrow_rate.py +0 -32
- ccxt/test/base/test_calculate_fee.py +0 -51
- ccxt/test/base/test_crypto.py +0 -127
- ccxt/test/base/test_currency.py +0 -76
- ccxt/test/base/test_datetime.py +0 -109
- ccxt/test/base/test_decimal_to_precision.py +0 -392
- ccxt/test/base/test_deep_extend.py +0 -68
- ccxt/test/base/test_deposit_withdrawal.py +0 -50
- ccxt/test/base/test_exchange_datetime_functions.py +0 -76
- ccxt/test/base/test_funding_rate_history.py +0 -29
- ccxt/test/base/test_last_price.py +0 -31
- ccxt/test/base/test_ledger_entry.py +0 -45
- ccxt/test/base/test_ledger_item.py +0 -48
- ccxt/test/base/test_leverage_tier.py +0 -33
- ccxt/test/base/test_liquidation.py +0 -50
- ccxt/test/base/test_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -193
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -33
- ccxt/test/base/test_open_interest.py +0 -32
- ccxt/test/base/test_order.py +0 -64
- ccxt/test/base/test_order_book.py +0 -69
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -353
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -92
- ccxt/test/base/test_trade.py +0 -47
- ccxt/test/base/test_trading_fee.py +0 -26
- ccxt/test/base/test_transaction.py +0 -39
- ccxt/test/test_async.py +0 -1649
- ccxt/test/test_sync.py +0 -1648
- ccxt/wazirx.py +0 -1224
- ccxt_ir-4.3.46.0.3.dist-info/RECORD +0 -773
- /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info/licenses}/LICENSE.txt +0 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info}/top_level.txt +0 -0
ccxt/pro/kraken.py
CHANGED
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
import ccxt.async_support
|
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
|
|
8
|
-
from ccxt.base.types import Int, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
|
|
8
|
+
from ccxt.base.types import Any, Balances, Bool, Int, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
|
|
9
9
|
from ccxt.async_support.base.ws.client import Client
|
|
10
10
|
from typing import List
|
|
11
11
|
from ccxt.base.errors import ExchangeError
|
|
12
12
|
from ccxt.base.errors import AuthenticationError
|
|
13
13
|
from ccxt.base.errors import PermissionDenied
|
|
14
14
|
from ccxt.base.errors import AccountSuspended
|
|
15
|
+
from ccxt.base.errors import ArgumentsRequired
|
|
15
16
|
from ccxt.base.errors import BadRequest
|
|
16
17
|
from ccxt.base.errors import BadSymbol
|
|
17
18
|
from ccxt.base.errors import InsufficientFunds
|
|
@@ -20,17 +21,17 @@ from ccxt.base.errors import OrderNotFound
|
|
|
20
21
|
from ccxt.base.errors import NotSupported
|
|
21
22
|
from ccxt.base.errors import RateLimitExceeded
|
|
22
23
|
from ccxt.base.errors import ExchangeNotAvailable
|
|
23
|
-
from ccxt.base.errors import
|
|
24
|
+
from ccxt.base.errors import ChecksumError
|
|
24
25
|
from ccxt.base.precise import Precise
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
class kraken(ccxt.async_support.kraken):
|
|
28
29
|
|
|
29
|
-
def describe(self):
|
|
30
|
+
def describe(self) -> Any:
|
|
30
31
|
return self.deep_extend(super(kraken, self).describe(), {
|
|
31
32
|
'has': {
|
|
32
33
|
'ws': True,
|
|
33
|
-
'watchBalance':
|
|
34
|
+
'watchBalance': True,
|
|
34
35
|
'watchMyTrades': True,
|
|
35
36
|
'watchOHLCV': True,
|
|
36
37
|
'watchOrderBook': True,
|
|
@@ -38,6 +39,7 @@ class kraken(ccxt.async_support.kraken):
|
|
|
38
39
|
'watchOrders': True,
|
|
39
40
|
'watchTicker': True,
|
|
40
41
|
'watchTickers': True,
|
|
42
|
+
'watchBidsAsks': True,
|
|
41
43
|
'watchTrades': True,
|
|
42
44
|
'watchTradesForSymbols': True,
|
|
43
45
|
'createOrderWs': True,
|
|
@@ -53,6 +55,8 @@ class kraken(ccxt.async_support.kraken):
|
|
|
53
55
|
'ws': {
|
|
54
56
|
'public': 'wss://ws.kraken.com',
|
|
55
57
|
'private': 'wss://ws-auth.kraken.com',
|
|
58
|
+
'privateV2': 'wss://ws-auth.kraken.com/v2',
|
|
59
|
+
'publicV2': 'wss://ws.kraken.com/v2',
|
|
56
60
|
'beta': 'wss://beta-ws.kraken.com',
|
|
57
61
|
'beta-private': 'wss://beta-ws-auth.kraken.com',
|
|
58
62
|
},
|
|
@@ -66,7 +70,13 @@ class kraken(ccxt.async_support.kraken):
|
|
|
66
70
|
'OHLCVLimit': 1000,
|
|
67
71
|
'ordersLimit': 1000,
|
|
68
72
|
'symbolsByOrderId': {},
|
|
69
|
-
'
|
|
73
|
+
'watchOrderBook': {
|
|
74
|
+
'checksum': False,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
'streaming': {
|
|
78
|
+
'ping': self.ping,
|
|
79
|
+
'keepAlive': 6000,
|
|
70
80
|
},
|
|
71
81
|
'exceptions': {
|
|
72
82
|
'ws': {
|
|
@@ -76,6 +86,7 @@ class kraken(ccxt.async_support.kraken):
|
|
|
76
86
|
'broad': {
|
|
77
87
|
'Already subscribed': BadRequest,
|
|
78
88
|
'Currency pair not in ISO 4217-A3 format': BadSymbol,
|
|
89
|
+
'Currency pair not supported': BadSymbol,
|
|
79
90
|
'Malformed request': BadRequest,
|
|
80
91
|
'Pair field must be an array': BadRequest,
|
|
81
92
|
'Pair field unsupported for self subscription type': BadRequest,
|
|
@@ -118,159 +129,310 @@ class kraken(ccxt.async_support.kraken):
|
|
|
118
129
|
'EService:Market in post_only mode': NotSupported,
|
|
119
130
|
'EService:Unavailable': ExchangeNotAvailable,
|
|
120
131
|
'ETrade:Invalid request': BadRequest,
|
|
132
|
+
'ESession:Invalid session': AuthenticationError,
|
|
121
133
|
},
|
|
122
134
|
},
|
|
123
135
|
},
|
|
124
136
|
})
|
|
125
137
|
|
|
138
|
+
def order_request_ws(self, method: str, symbol: str, type: str, request: dict, amount: Num, price: Num = None, params={}):
|
|
139
|
+
isLimitOrder = type.endswith('limit') # supporting limit, stop-loss-limit, take-profit-limit, etc
|
|
140
|
+
if isLimitOrder:
|
|
141
|
+
if price is None:
|
|
142
|
+
raise ArgumentsRequired(self.id + ' limit orders require a price argument')
|
|
143
|
+
request['params']['limit_price'] = self.parse_to_numeric(self.price_to_precision(symbol, price))
|
|
144
|
+
isMarket = (type == 'market')
|
|
145
|
+
postOnly = None
|
|
146
|
+
postOnly, params = self.handle_post_only(isMarket, False, params)
|
|
147
|
+
if postOnly:
|
|
148
|
+
request['params']['post_only'] = True
|
|
149
|
+
clientOrderId = self.safe_string(params, 'clientOrderId')
|
|
150
|
+
if clientOrderId is not None:
|
|
151
|
+
request['params']['cl_ord_id'] = clientOrderId
|
|
152
|
+
cost = self.safe_string(params, 'cost')
|
|
153
|
+
if cost is not None:
|
|
154
|
+
request['params']['order_qty'] = self.parse_to_numeric(self.cost_to_precision(symbol, cost))
|
|
155
|
+
stopLoss = self.safe_dict(params, 'stopLoss', {})
|
|
156
|
+
takeProfit = self.safe_dict(params, 'takeProfit', {})
|
|
157
|
+
presetStopLoss = self.safe_string(stopLoss, 'triggerPrice')
|
|
158
|
+
presetTakeProfit = self.safe_string(takeProfit, 'triggerPrice')
|
|
159
|
+
presetStopLossLimit = self.safe_string(stopLoss, 'price')
|
|
160
|
+
presetTakeProfitLimit = self.safe_string(takeProfit, 'price')
|
|
161
|
+
isPresetStopLoss = presetStopLoss is not None
|
|
162
|
+
isPresetTakeProfit = presetTakeProfit is not None
|
|
163
|
+
stopLossPrice = self.safe_string(params, 'stopLossPrice')
|
|
164
|
+
takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
|
|
165
|
+
isStopLossPriceOrder = stopLossPrice is not None
|
|
166
|
+
isTakeProfitPriceOrder = takeProfitPrice is not None
|
|
167
|
+
trailingAmount = self.safe_string(params, 'trailingAmount')
|
|
168
|
+
trailingPercent = self.safe_string(params, 'trailingPercent')
|
|
169
|
+
trailingLimitAmount = self.safe_string(params, 'trailingLimitAmount')
|
|
170
|
+
trailingLimitPercent = self.safe_string(params, 'trailingLimitPercent')
|
|
171
|
+
isTrailingAmountOrder = trailingAmount is not None
|
|
172
|
+
isTrailingPercentOrder = trailingPercent is not None
|
|
173
|
+
isTrailingLimitAmountOrder = trailingLimitAmount is not None
|
|
174
|
+
isTrailingLimitPercentOrder = trailingLimitPercent is not None
|
|
175
|
+
offset = self.safe_string(params, 'offset', '') # can set self to - for minus
|
|
176
|
+
trailingAmountString = offset + self.number_to_string(trailingAmount) if (trailingAmount is not None) else None
|
|
177
|
+
trailingPercentString = offset + self.number_to_string(trailingPercent) if (trailingPercent is not None) else None
|
|
178
|
+
trailingLimitAmountString = offset + self.number_to_string(trailingLimitAmount) if (trailingLimitAmount is not None) else None
|
|
179
|
+
trailingLimitPercentString = offset + self.number_to_string(trailingLimitPercent) if (trailingLimitPercent is not None) else None
|
|
180
|
+
priceType = 'pct' if (isTrailingPercentOrder or isTrailingLimitPercentOrder) else 'quote'
|
|
181
|
+
if method == 'createOrderWs':
|
|
182
|
+
reduceOnly = self.safe_bool(params, 'reduceOnly')
|
|
183
|
+
if reduceOnly:
|
|
184
|
+
request['params']['reduce_only'] = True
|
|
185
|
+
timeInForce = self.safe_string_lower(params, 'timeInForce')
|
|
186
|
+
if timeInForce is not None:
|
|
187
|
+
request['params']['time_in_force'] = timeInForce
|
|
188
|
+
params = self.omit(params, ['reduceOnly', 'timeInForce'])
|
|
189
|
+
if isStopLossPriceOrder or isTakeProfitPriceOrder or isTrailingAmountOrder or isTrailingPercentOrder or isTrailingLimitAmountOrder or isTrailingLimitPercentOrder:
|
|
190
|
+
request['params']['triggers'] = {}
|
|
191
|
+
if isPresetStopLoss or isPresetTakeProfit:
|
|
192
|
+
request['params']['conditional'] = {}
|
|
193
|
+
if isPresetStopLoss:
|
|
194
|
+
request['params']['conditional']['order_type'] = 'stop-loss'
|
|
195
|
+
request['params']['conditional']['trigger_price'] = self.parse_to_numeric(self.price_to_precision(symbol, presetStopLoss))
|
|
196
|
+
elif isPresetTakeProfit:
|
|
197
|
+
request['params']['conditional']['order_type'] = 'take-profit'
|
|
198
|
+
request['params']['conditional']['trigger_price'] = self.parse_to_numeric(self.price_to_precision(symbol, presetTakeProfit))
|
|
199
|
+
if presetStopLossLimit is not None:
|
|
200
|
+
request['params']['conditional']['order_type'] = 'stop-loss-limit'
|
|
201
|
+
request['params']['conditional']['limit_price'] = self.parse_to_numeric(self.price_to_precision(symbol, presetStopLossLimit))
|
|
202
|
+
elif presetTakeProfitLimit is not None:
|
|
203
|
+
request['params']['conditional']['order_type'] = 'take-profit-limit'
|
|
204
|
+
request['params']['conditional']['limit_price'] = self.parse_to_numeric(self.price_to_precision(symbol, presetTakeProfitLimit))
|
|
205
|
+
params = self.omit(params, ['stopLoss', 'takeProfit'])
|
|
206
|
+
elif isStopLossPriceOrder or isTakeProfitPriceOrder:
|
|
207
|
+
if isStopLossPriceOrder:
|
|
208
|
+
request['params']['triggers']['price'] = self.parse_to_numeric(self.price_to_precision(symbol, stopLossPrice))
|
|
209
|
+
if isLimitOrder:
|
|
210
|
+
request['params']['order_type'] = 'stop-loss-limit'
|
|
211
|
+
else:
|
|
212
|
+
request['params']['order_type'] = 'stop-loss'
|
|
213
|
+
else:
|
|
214
|
+
request['params']['triggers']['price'] = self.parse_to_numeric(self.price_to_precision(symbol, takeProfitPrice))
|
|
215
|
+
if isLimitOrder:
|
|
216
|
+
request['params']['order_type'] = 'take-profit-limit'
|
|
217
|
+
else:
|
|
218
|
+
request['params']['order_type'] = 'take-profit'
|
|
219
|
+
elif isTrailingAmountOrder or isTrailingPercentOrder or isTrailingLimitAmountOrder or isTrailingLimitPercentOrder:
|
|
220
|
+
request['params']['triggers']['price_type'] = priceType
|
|
221
|
+
if not isLimitOrder and (isTrailingAmountOrder or isTrailingPercentOrder):
|
|
222
|
+
request['params']['order_type'] = 'trailing-stop'
|
|
223
|
+
if isTrailingAmountOrder:
|
|
224
|
+
request['params']['triggers']['price'] = self.parse_to_numeric(trailingAmountString)
|
|
225
|
+
else:
|
|
226
|
+
request['params']['triggers']['price'] = self.parse_to_numeric(trailingPercentString)
|
|
227
|
+
else:
|
|
228
|
+
# trailing limit orders are not conventionally supported because the static limit_price_type param is not available for trailing-stop-limit orders
|
|
229
|
+
request['params']['limit_price_type'] = priceType
|
|
230
|
+
request['params']['order_type'] = 'trailing-stop-limit'
|
|
231
|
+
if isTrailingLimitAmountOrder:
|
|
232
|
+
request['params']['triggers']['price'] = self.parse_to_numeric(trailingLimitAmountString)
|
|
233
|
+
else:
|
|
234
|
+
request['params']['triggers']['price'] = self.parse_to_numeric(trailingLimitPercentString)
|
|
235
|
+
elif method == 'editOrderWs':
|
|
236
|
+
if isPresetStopLoss or isPresetTakeProfit:
|
|
237
|
+
raise NotSupported(self.id + ' editing the stopLoss and takeProfit on existing orders is currently not supported')
|
|
238
|
+
if isStopLossPriceOrder or isTakeProfitPriceOrder:
|
|
239
|
+
if isStopLossPriceOrder:
|
|
240
|
+
request['params']['trigger_price'] = self.parse_to_numeric(self.price_to_precision(symbol, stopLossPrice))
|
|
241
|
+
else:
|
|
242
|
+
request['params']['trigger_price'] = self.parse_to_numeric(self.price_to_precision(symbol, takeProfitPrice))
|
|
243
|
+
elif isTrailingAmountOrder or isTrailingPercentOrder or isTrailingLimitAmountOrder or isTrailingLimitPercentOrder:
|
|
244
|
+
request['params']['trigger_price_type'] = priceType
|
|
245
|
+
if not isLimitOrder and (isTrailingAmountOrder or isTrailingPercentOrder):
|
|
246
|
+
if isTrailingAmountOrder:
|
|
247
|
+
request['params']['trigger_price'] = self.parse_to_numeric(trailingAmountString)
|
|
248
|
+
else:
|
|
249
|
+
request['params']['trigger_price'] = self.parse_to_numeric(trailingPercentString)
|
|
250
|
+
else:
|
|
251
|
+
request['params']['limit_price_type'] = priceType
|
|
252
|
+
if isTrailingLimitAmountOrder:
|
|
253
|
+
request['params']['trigger_price'] = self.parse_to_numeric(trailingLimitAmountString)
|
|
254
|
+
else:
|
|
255
|
+
request['params']['trigger_price'] = self.parse_to_numeric(trailingLimitPercentString)
|
|
256
|
+
params = self.omit(params, ['clientOrderId', 'cost', 'offset', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'trailingLimitAmount', 'trailingLimitPercent'])
|
|
257
|
+
return [request, params]
|
|
258
|
+
|
|
126
259
|
async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
|
|
127
260
|
"""
|
|
128
|
-
:see: https://docs.kraken.com/websockets/#message-addOrder
|
|
129
261
|
create a trade order
|
|
262
|
+
|
|
263
|
+
https://docs.kraken.com/api/docs/websocket-v2/add_order
|
|
264
|
+
|
|
130
265
|
:param str symbol: unified symbol of the market to create an order in
|
|
131
266
|
:param str type: 'market' or 'limit'
|
|
132
267
|
:param str side: 'buy' or 'sell'
|
|
133
268
|
:param float amount: how much of currency you want to trade in units of base currency
|
|
134
|
-
:param float [price]: the price at which the order is to be
|
|
269
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
135
270
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
136
271
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
137
272
|
"""
|
|
138
273
|
await self.load_markets()
|
|
139
274
|
token = await self.authenticate()
|
|
140
275
|
market = self.market(symbol)
|
|
141
|
-
url = self.urls['api']['ws']['
|
|
276
|
+
url = self.urls['api']['ws']['privateV2']
|
|
142
277
|
requestId = self.request_id()
|
|
143
278
|
messageHash = requestId
|
|
144
279
|
request: dict = {
|
|
145
|
-
'
|
|
146
|
-
'
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
280
|
+
'method': 'add_order',
|
|
281
|
+
'params': {
|
|
282
|
+
'order_type': type,
|
|
283
|
+
'side': side,
|
|
284
|
+
'order_qty': self.parse_to_numeric(self.amount_to_precision(symbol, amount)),
|
|
285
|
+
'symbol': market['symbol'],
|
|
286
|
+
'token': token,
|
|
287
|
+
},
|
|
288
|
+
'req_id': requestId,
|
|
152
289
|
}
|
|
153
|
-
request, params = self.
|
|
290
|
+
request, params = self.order_request_ws('createOrderWs', symbol, type, request, amount, price, params)
|
|
154
291
|
return await self.watch(url, messageHash, self.extend(request, params), messageHash)
|
|
155
292
|
|
|
156
293
|
def handle_create_edit_order(self, client, message):
|
|
157
294
|
#
|
|
158
295
|
# createOrder
|
|
159
|
-
#
|
|
160
|
-
#
|
|
161
|
-
#
|
|
162
|
-
#
|
|
163
|
-
#
|
|
164
|
-
#
|
|
165
|
-
#
|
|
296
|
+
# {
|
|
297
|
+
# "method": "add_order",
|
|
298
|
+
# "req_id": 1,
|
|
299
|
+
# "result": {
|
|
300
|
+
# "order_id": "OXM2QD-EALR2-YBAVEU"
|
|
301
|
+
# },
|
|
302
|
+
# "success": True,
|
|
303
|
+
# "time_in": "2025-05-13T10:12:13.876173Z",
|
|
304
|
+
# "time_out": "2025-05-13T10:12:13.890137Z"
|
|
305
|
+
# }
|
|
306
|
+
#
|
|
166
307
|
# editOrder
|
|
167
|
-
#
|
|
168
|
-
#
|
|
169
|
-
#
|
|
170
|
-
#
|
|
171
|
-
#
|
|
172
|
-
#
|
|
173
|
-
#
|
|
174
|
-
#
|
|
308
|
+
# {
|
|
309
|
+
# "method": "amend_order",
|
|
310
|
+
# "req_id": 1,
|
|
311
|
+
# "result": {
|
|
312
|
+
# "amend_id": "TYDLSQ-OYNYU-3MNRER",
|
|
313
|
+
# "order_id": "OGL7HR-SWFO4-NRQTHO"
|
|
314
|
+
# },
|
|
315
|
+
# "success": True,
|
|
316
|
+
# "time_in": "2025-05-14T13:54:10.840342Z",
|
|
317
|
+
# "time_out": "2025-05-14T13:54:10.855046Z"
|
|
318
|
+
# }
|
|
175
319
|
#
|
|
176
|
-
|
|
177
|
-
|
|
320
|
+
result = self.safe_dict(message, 'result', {})
|
|
321
|
+
order = self.parse_order(result)
|
|
322
|
+
messageHash = self.safe_value_2(message, 'reqid', 'req_id')
|
|
178
323
|
client.resolve(order, messageHash)
|
|
179
324
|
|
|
180
325
|
async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}) -> Order:
|
|
181
326
|
"""
|
|
182
327
|
edit a trade order
|
|
183
|
-
|
|
328
|
+
|
|
329
|
+
https://docs.kraken.com/api/docs/websocket-v2/amend_order
|
|
330
|
+
|
|
184
331
|
:param str id: order id
|
|
185
332
|
:param str symbol: unified symbol of the market to create an order in
|
|
186
333
|
:param str type: 'market' or 'limit'
|
|
187
334
|
:param str side: 'buy' or 'sell'
|
|
188
335
|
:param float amount: how much of the currency you want to trade in units of the base currency
|
|
189
|
-
:param float [price]: the price at which the order is to be
|
|
336
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
190
337
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
191
338
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
192
339
|
"""
|
|
193
340
|
await self.load_markets()
|
|
194
341
|
token = await self.authenticate()
|
|
195
|
-
|
|
196
|
-
url = self.urls['api']['ws']['private']
|
|
342
|
+
url = self.urls['api']['ws']['privateV2']
|
|
197
343
|
requestId = self.request_id()
|
|
198
344
|
messageHash = requestId
|
|
199
345
|
request: dict = {
|
|
200
|
-
'
|
|
201
|
-
'
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
346
|
+
'method': 'amend_order',
|
|
347
|
+
'params': {
|
|
348
|
+
'order_id': id,
|
|
349
|
+
'order_qty': self.parse_to_numeric(self.amount_to_precision(symbol, amount)),
|
|
350
|
+
'token': token,
|
|
351
|
+
},
|
|
352
|
+
'req_id': requestId,
|
|
205
353
|
}
|
|
206
|
-
|
|
207
|
-
request['volume'] = self.amount_to_precision(symbol, amount)
|
|
208
|
-
request, params = self.orderRequest('editOrderWs', symbol, type, request, amount, price, params)
|
|
354
|
+
request, params = self.order_request_ws('editOrderWs', symbol, type, request, amount, price, params)
|
|
209
355
|
return await self.watch(url, messageHash, self.extend(request, params), messageHash)
|
|
210
356
|
|
|
211
357
|
async def cancel_orders_ws(self, ids: List[str], symbol: Str = None, params={}):
|
|
212
358
|
"""
|
|
213
|
-
:see: https://docs.kraken.com/websockets/#message-cancelOrder
|
|
214
359
|
cancel multiple orders
|
|
360
|
+
|
|
361
|
+
https://docs.kraken.com/api/docs/websocket-v2/cancel_order
|
|
362
|
+
|
|
215
363
|
:param str[] ids: order ids
|
|
216
|
-
:param str symbol: unified market symbol, default is None
|
|
364
|
+
:param str [symbol]: unified market symbol, default is None
|
|
217
365
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
218
366
|
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
219
367
|
"""
|
|
368
|
+
if symbol is not None:
|
|
369
|
+
raise NotSupported(self.id + ' cancelOrdersWs() does not support cancelling orders for a specific symbol.')
|
|
220
370
|
await self.load_markets()
|
|
221
371
|
token = await self.authenticate()
|
|
222
|
-
url = self.urls['api']['ws']['
|
|
372
|
+
url = self.urls['api']['ws']['privateV2']
|
|
223
373
|
requestId = self.request_id()
|
|
224
374
|
messageHash = requestId
|
|
225
375
|
request: dict = {
|
|
226
|
-
'
|
|
227
|
-
'
|
|
228
|
-
|
|
229
|
-
|
|
376
|
+
'method': 'cancel_order',
|
|
377
|
+
'params': {
|
|
378
|
+
'order_id': ids,
|
|
379
|
+
'token': token,
|
|
380
|
+
},
|
|
381
|
+
'req_id': requestId,
|
|
230
382
|
}
|
|
231
383
|
return await self.watch(url, messageHash, self.extend(request, params), messageHash)
|
|
232
384
|
|
|
233
385
|
async def cancel_order_ws(self, id: str, symbol: Str = None, params={}) -> Order:
|
|
234
386
|
"""
|
|
235
|
-
:see: https://docs.kraken.com/websockets/#message-cancelOrder
|
|
236
387
|
cancels an open order
|
|
388
|
+
|
|
389
|
+
https://docs.kraken.com/api/docs/websocket-v2/cancel_order
|
|
390
|
+
|
|
237
391
|
:param str id: order id
|
|
238
|
-
:param str symbol: unified symbol of the market the order was made in
|
|
392
|
+
:param str [symbol]: unified symbol of the market the order was made in
|
|
239
393
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
240
394
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
241
395
|
"""
|
|
396
|
+
if symbol is not None:
|
|
397
|
+
raise NotSupported(self.id + ' cancelOrderWs() does not support cancelling orders for a specific symbol.')
|
|
242
398
|
await self.load_markets()
|
|
243
399
|
token = await self.authenticate()
|
|
244
|
-
url = self.urls['api']['ws']['
|
|
400
|
+
url = self.urls['api']['ws']['privateV2']
|
|
245
401
|
requestId = self.request_id()
|
|
246
402
|
messageHash = requestId
|
|
247
|
-
clientOrderId = self.safe_value_2(params, 'userref', 'clientOrderId', id)
|
|
248
|
-
params = self.omit(params, ['userref', 'clientOrderId'])
|
|
249
403
|
request: dict = {
|
|
250
|
-
'
|
|
251
|
-
'
|
|
252
|
-
|
|
253
|
-
|
|
404
|
+
'method': 'cancel_order',
|
|
405
|
+
'params': {
|
|
406
|
+
'order_id': [id],
|
|
407
|
+
'token': token,
|
|
408
|
+
},
|
|
409
|
+
'req_id': requestId,
|
|
254
410
|
}
|
|
255
411
|
return await self.watch(url, messageHash, self.extend(request, params), messageHash)
|
|
256
412
|
|
|
257
413
|
def handle_cancel_order(self, client, message):
|
|
258
414
|
#
|
|
259
|
-
#
|
|
260
|
-
#
|
|
261
|
-
#
|
|
262
|
-
#
|
|
263
|
-
#
|
|
264
|
-
#
|
|
415
|
+
# {
|
|
416
|
+
# "method": "cancel_order",
|
|
417
|
+
# "req_id": 123456789,
|
|
418
|
+
# "result": {
|
|
419
|
+
# "order_id": "OKAGJC-YHIWK-WIOZWG"
|
|
420
|
+
# },
|
|
421
|
+
# "success": True,
|
|
422
|
+
# "time_in": "2023-09-21T14:36:57.428972Z",
|
|
423
|
+
# "time_out": "2023-09-21T14:36:57.437952Z"
|
|
424
|
+
# }
|
|
265
425
|
#
|
|
266
|
-
reqId = self.safe_value(message, '
|
|
426
|
+
reqId = self.safe_value(message, 'req_id')
|
|
267
427
|
client.resolve(message, reqId)
|
|
268
428
|
|
|
269
429
|
async def cancel_all_orders_ws(self, symbol: Str = None, params={}):
|
|
270
430
|
"""
|
|
271
|
-
:see: https://docs.kraken.com/websockets/#message-cancelAll
|
|
272
431
|
cancel all open orders
|
|
273
|
-
|
|
432
|
+
|
|
433
|
+
https://docs.kraken.com/api/docs/websocket-v2/cancel_all
|
|
434
|
+
|
|
435
|
+
:param str [symbol]: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
|
|
274
436
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
275
437
|
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
276
438
|
"""
|
|
@@ -278,75 +440,84 @@ class kraken(ccxt.async_support.kraken):
|
|
|
278
440
|
raise NotSupported(self.id + ' cancelAllOrdersWs() does not support cancelling orders in a specific market.')
|
|
279
441
|
await self.load_markets()
|
|
280
442
|
token = await self.authenticate()
|
|
281
|
-
url = self.urls['api']['ws']['
|
|
443
|
+
url = self.urls['api']['ws']['privateV2']
|
|
282
444
|
requestId = self.request_id()
|
|
283
445
|
messageHash = requestId
|
|
284
446
|
request: dict = {
|
|
285
|
-
'
|
|
286
|
-
'
|
|
287
|
-
|
|
447
|
+
'method': 'cancel_all',
|
|
448
|
+
'params': {
|
|
449
|
+
'token': token,
|
|
450
|
+
},
|
|
451
|
+
'req_id': requestId,
|
|
288
452
|
}
|
|
289
453
|
return await self.watch(url, messageHash, self.extend(request, params), messageHash)
|
|
290
454
|
|
|
291
455
|
def handle_cancel_all_orders(self, client, message):
|
|
292
456
|
#
|
|
293
|
-
#
|
|
294
|
-
#
|
|
295
|
-
#
|
|
296
|
-
#
|
|
297
|
-
#
|
|
298
|
-
#
|
|
457
|
+
# {
|
|
458
|
+
# "method": "cancel_all",
|
|
459
|
+
# "req_id": 123456789,
|
|
460
|
+
# "result": {
|
|
461
|
+
# "count": 1
|
|
462
|
+
# },
|
|
463
|
+
# "success": True,
|
|
464
|
+
# "time_in": "2023-09-21T14:36:57.428972Z",
|
|
465
|
+
# "time_out": "2023-09-21T14:36:57.437952Z"
|
|
466
|
+
# }
|
|
299
467
|
#
|
|
300
|
-
reqId = self.safe_value(message, '
|
|
468
|
+
reqId = self.safe_value(message, 'req_id')
|
|
301
469
|
client.resolve(message, reqId)
|
|
302
470
|
|
|
303
|
-
def handle_ticker(self, client, message
|
|
471
|
+
def handle_ticker(self, client, message):
|
|
304
472
|
#
|
|
305
|
-
#
|
|
306
|
-
#
|
|
307
|
-
#
|
|
308
|
-
#
|
|
309
|
-
#
|
|
310
|
-
#
|
|
311
|
-
#
|
|
312
|
-
#
|
|
313
|
-
#
|
|
314
|
-
#
|
|
315
|
-
#
|
|
316
|
-
#
|
|
317
|
-
#
|
|
318
|
-
#
|
|
319
|
-
#
|
|
320
|
-
#
|
|
473
|
+
# {
|
|
474
|
+
# "channel": "ticker",
|
|
475
|
+
# "type": "snapshot",
|
|
476
|
+
# "data": [
|
|
477
|
+
# {
|
|
478
|
+
# "symbol": "BTC/USD",
|
|
479
|
+
# "bid": 108359.8,
|
|
480
|
+
# "bid_qty": 0.01362603,
|
|
481
|
+
# "ask": 108359.9,
|
|
482
|
+
# "ask_qty": 17.17988863,
|
|
483
|
+
# "last": 108359.8,
|
|
484
|
+
# "volume": 2158.32346723,
|
|
485
|
+
# "vwap": 108894.5,
|
|
486
|
+
# "low": 106824,
|
|
487
|
+
# "high": 111300,
|
|
488
|
+
# "change": -2679.9,
|
|
489
|
+
# "change_pct": -2.41
|
|
490
|
+
# }
|
|
491
|
+
# ]
|
|
492
|
+
# }
|
|
321
493
|
#
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
symbol =
|
|
494
|
+
data = self.safe_list(message, 'data', [])
|
|
495
|
+
ticker = data[0]
|
|
496
|
+
symbol = self.safe_string(ticker, 'symbol')
|
|
325
497
|
messageHash = self.get_message_hash('ticker', None, symbol)
|
|
326
|
-
|
|
327
|
-
vwap = self.safe_string(ticker['p'], 0)
|
|
498
|
+
vwap = self.safe_string(ticker, 'vwap')
|
|
328
499
|
quoteVolume = None
|
|
329
|
-
baseVolume = self.safe_string(ticker
|
|
500
|
+
baseVolume = self.safe_string(ticker, 'volume')
|
|
330
501
|
if baseVolume is not None and vwap is not None:
|
|
331
502
|
quoteVolume = Precise.string_mul(baseVolume, vwap)
|
|
332
|
-
last = self.safe_string(ticker
|
|
503
|
+
last = self.safe_string(ticker, 'last')
|
|
333
504
|
result = self.safe_ticker({
|
|
334
505
|
'symbol': symbol,
|
|
335
506
|
'timestamp': None,
|
|
336
507
|
'datetime': None,
|
|
337
|
-
'high': self.safe_string(ticker
|
|
338
|
-
'low': self.safe_string(ticker
|
|
339
|
-
'bid': self.safe_string(ticker
|
|
340
|
-
'bidVolume': self.safe_string(ticker
|
|
341
|
-
'ask': self.safe_string(ticker
|
|
342
|
-
'askVolume': self.safe_string(ticker
|
|
508
|
+
'high': self.safe_string(ticker, 'high'),
|
|
509
|
+
'low': self.safe_string(ticker, 'low'),
|
|
510
|
+
'bid': self.safe_string(ticker, 'bid'),
|
|
511
|
+
'bidVolume': self.safe_string(ticker, 'bid_qty'),
|
|
512
|
+
'ask': self.safe_string(ticker, 'ask'),
|
|
513
|
+
'askVolume': self.safe_string(ticker, 'ask_qty'),
|
|
343
514
|
'vwap': vwap,
|
|
344
|
-
'open':
|
|
515
|
+
'open': None,
|
|
345
516
|
'close': last,
|
|
346
517
|
'last': last,
|
|
347
518
|
'previousClose': None,
|
|
348
|
-
'change':
|
|
349
|
-
'percentage':
|
|
519
|
+
'change': self.safe_string(ticker, 'change'),
|
|
520
|
+
'percentage': self.safe_string(ticker, 'change_pct'),
|
|
350
521
|
'average': None,
|
|
351
522
|
'baseVolume': baseVolume,
|
|
352
523
|
'quoteVolume': quoteVolume,
|
|
@@ -355,30 +526,35 @@ class kraken(ccxt.async_support.kraken):
|
|
|
355
526
|
self.tickers[symbol] = result
|
|
356
527
|
client.resolve(result, messageHash)
|
|
357
528
|
|
|
358
|
-
def handle_trades(self, client: Client, message
|
|
529
|
+
def handle_trades(self, client: Client, message):
|
|
359
530
|
#
|
|
360
|
-
#
|
|
361
|
-
#
|
|
362
|
-
#
|
|
363
|
-
#
|
|
364
|
-
#
|
|
365
|
-
#
|
|
366
|
-
#
|
|
367
|
-
#
|
|
368
|
-
#
|
|
531
|
+
# {
|
|
532
|
+
# "channel": "trade",
|
|
533
|
+
# "type": "update",
|
|
534
|
+
# "data": [
|
|
535
|
+
# {
|
|
536
|
+
# "symbol": "MATIC/USD",
|
|
537
|
+
# "side": "sell",
|
|
538
|
+
# "price": 0.5117,
|
|
539
|
+
# "qty": 40.0,
|
|
540
|
+
# "ord_type": "market",
|
|
541
|
+
# "trade_id": 4665906,
|
|
542
|
+
# "timestamp": "2023-09-25T07:49:37.708706Z"
|
|
543
|
+
# }
|
|
544
|
+
# ]
|
|
545
|
+
# }
|
|
369
546
|
#
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
messageHash = self.get_message_hash(name, None, symbol)
|
|
547
|
+
data = self.safe_list(message, 'data', [])
|
|
548
|
+
trade = data[0]
|
|
549
|
+
symbol = self.safe_string(trade, 'symbol')
|
|
550
|
+
messageHash = self.get_message_hash('trade', None, symbol)
|
|
375
551
|
stored = self.safe_value(self.trades, symbol)
|
|
376
552
|
if stored is None:
|
|
377
553
|
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
|
378
554
|
stored = ArrayCache(limit)
|
|
379
555
|
self.trades[symbol] = stored
|
|
380
|
-
|
|
381
|
-
parsed = self.parse_trades(
|
|
556
|
+
market = self.market(symbol)
|
|
557
|
+
parsed = self.parse_trades(data, market)
|
|
382
558
|
for i in range(0, len(parsed)):
|
|
383
559
|
stored.append(parsed[i])
|
|
384
560
|
client.resolve(stored, messageHash)
|
|
@@ -462,6 +638,9 @@ class kraken(ccxt.async_support.kraken):
|
|
|
462
638
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
|
463
639
|
"""
|
|
464
640
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
641
|
+
|
|
642
|
+
https://docs.kraken.com/api/docs/websocket-v2/ticker
|
|
643
|
+
|
|
465
644
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
|
466
645
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
467
646
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
@@ -474,7 +653,10 @@ class kraken(ccxt.async_support.kraken):
|
|
|
474
653
|
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
|
475
654
|
"""
|
|
476
655
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
477
|
-
|
|
656
|
+
|
|
657
|
+
https://docs.kraken.com/api/docs/websocket-v2/ticker
|
|
658
|
+
|
|
659
|
+
:param str[] symbols:
|
|
478
660
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
479
661
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
480
662
|
"""
|
|
@@ -487,10 +669,32 @@ class kraken(ccxt.async_support.kraken):
|
|
|
487
669
|
return result
|
|
488
670
|
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
|
489
671
|
|
|
672
|
+
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
|
673
|
+
"""
|
|
674
|
+
watches best bid & ask for symbols
|
|
675
|
+
|
|
676
|
+
https://docs.kraken.com/api/docs/websocket-v2/ticker
|
|
677
|
+
|
|
678
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
679
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
680
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
681
|
+
"""
|
|
682
|
+
await self.load_markets()
|
|
683
|
+
symbols = self.market_symbols(symbols, None, False)
|
|
684
|
+
params['event_trigger'] = 'bbo'
|
|
685
|
+
ticker = await self.watch_multi_helper('bidask', 'ticker', symbols, None, params)
|
|
686
|
+
if self.newUpdates:
|
|
687
|
+
result: dict = {}
|
|
688
|
+
result[ticker['symbol']] = ticker
|
|
689
|
+
return result
|
|
690
|
+
return self.filter_by_array(self.bidsasks, 'symbol', symbols)
|
|
691
|
+
|
|
490
692
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
491
693
|
"""
|
|
492
694
|
get the list of most recent trades for a particular symbol
|
|
493
|
-
|
|
695
|
+
|
|
696
|
+
https://docs.kraken.com/api/docs/websocket-v2/trade
|
|
697
|
+
|
|
494
698
|
:param str symbol: unified symbol of the market to fetch trades for
|
|
495
699
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
|
496
700
|
:param int [limit]: the maximum amount of trades to fetch
|
|
@@ -501,8 +705,10 @@ class kraken(ccxt.async_support.kraken):
|
|
|
501
705
|
|
|
502
706
|
async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
503
707
|
"""
|
|
504
|
-
:see: https://docs.kraken.com/websockets/#message-trade
|
|
505
708
|
get the list of most recent trades for a list of symbols
|
|
709
|
+
|
|
710
|
+
https://docs.kraken.com/api/docs/websocket-v2/trade
|
|
711
|
+
|
|
506
712
|
:param str[] symbols: unified symbol of the market to fetch trades for
|
|
507
713
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
|
508
714
|
:param int [limit]: the maximum amount of trades to fetch
|
|
@@ -519,7 +725,9 @@ class kraken(ccxt.async_support.kraken):
|
|
|
519
725
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
|
520
726
|
"""
|
|
521
727
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
522
|
-
|
|
728
|
+
|
|
729
|
+
https://docs.kraken.com/api/docs/websocket-v2/book
|
|
730
|
+
|
|
523
731
|
:param str symbol: unified symbol of the market to fetch the order book for
|
|
524
732
|
:param int [limit]: the maximum amount of order book entries to return
|
|
525
733
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -530,26 +738,29 @@ class kraken(ccxt.async_support.kraken):
|
|
|
530
738
|
async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
|
|
531
739
|
"""
|
|
532
740
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
533
|
-
|
|
741
|
+
|
|
742
|
+
https://docs.kraken.com/api/docs/websocket-v2/book
|
|
743
|
+
|
|
534
744
|
:param str[] symbols: unified array of symbols
|
|
535
745
|
:param int [limit]: the maximum amount of order book entries to return
|
|
536
746
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
537
747
|
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
|
538
748
|
"""
|
|
539
|
-
|
|
749
|
+
requiredParams: dict = {}
|
|
540
750
|
if limit is not None:
|
|
541
751
|
if self.in_array(limit, [10, 25, 100, 500, 1000]):
|
|
542
|
-
|
|
543
|
-
'depth': limit, # default 10, valid options 10, 25, 100, 500, 1000
|
|
544
|
-
}
|
|
752
|
+
requiredParams['depth'] = limit # default 10, valid options 10, 25, 100, 500, 1000
|
|
545
753
|
else:
|
|
546
754
|
raise NotSupported(self.id + ' watchOrderBook accepts limit values of 10, 25, 100, 500 and 1000 only')
|
|
547
|
-
orderbook = await self.watch_multi_helper('orderbook', 'book', symbols, {'limit': limit}, self.extend(
|
|
755
|
+
orderbook = await self.watch_multi_helper('orderbook', 'book', symbols, {'limit': limit}, self.extend(requiredParams, params))
|
|
548
756
|
return orderbook.limit()
|
|
549
757
|
|
|
550
758
|
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
|
551
759
|
"""
|
|
552
760
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
761
|
+
|
|
762
|
+
https://docs.kraken.com/api/docs/websocket-v1/ohlc
|
|
763
|
+
|
|
553
764
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
|
554
765
|
:param str timeframe: the length of time each candle represents
|
|
555
766
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
|
@@ -590,18 +801,25 @@ class kraken(ccxt.async_support.kraken):
|
|
|
590
801
|
for i in range(0, len(self.symbols)):
|
|
591
802
|
symbol = self.symbols[i]
|
|
592
803
|
market = self.markets[symbol]
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
wsName = altname[0:3] + '/' + altname[3:]
|
|
597
|
-
marketsByWsName[wsName] = market
|
|
598
|
-
else:
|
|
599
|
-
info = self.safe_value(market, 'info', {})
|
|
600
|
-
wsName = self.safe_string(info, 'wsname')
|
|
601
|
-
marketsByWsName[wsName] = market
|
|
804
|
+
info = self.safe_value(market, 'info', {})
|
|
805
|
+
wsName = self.safe_string(info, 'wsname')
|
|
806
|
+
marketsByWsName[wsName] = market
|
|
602
807
|
self.options['marketsByWsName'] = marketsByWsName
|
|
603
808
|
return markets
|
|
604
809
|
|
|
810
|
+
def ping(self, client: Client):
|
|
811
|
+
url = client.url
|
|
812
|
+
request = {}
|
|
813
|
+
if url.find('v2') >= 0:
|
|
814
|
+
request['method'] = 'ping'
|
|
815
|
+
else:
|
|
816
|
+
request['event'] = 'ping'
|
|
817
|
+
return request
|
|
818
|
+
|
|
819
|
+
def handle_pong(self, client: Client, message):
|
|
820
|
+
client.lastPong = self.milliseconds()
|
|
821
|
+
return message
|
|
822
|
+
|
|
605
823
|
async def watch_heartbeat(self, params={}):
|
|
606
824
|
await self.load_markets()
|
|
607
825
|
event = 'heartbeat'
|
|
@@ -617,157 +835,151 @@ class kraken(ccxt.async_support.kraken):
|
|
|
617
835
|
event = self.safe_string(message, 'event')
|
|
618
836
|
client.resolve(message, event)
|
|
619
837
|
|
|
620
|
-
def handle_order_book(self, client: Client, message
|
|
838
|
+
def handle_order_book(self, client: Client, message):
|
|
621
839
|
#
|
|
622
840
|
# first message(snapshot)
|
|
623
841
|
#
|
|
624
|
-
#
|
|
625
|
-
#
|
|
626
|
-
#
|
|
627
|
-
#
|
|
628
|
-
#
|
|
629
|
-
#
|
|
630
|
-
#
|
|
631
|
-
#
|
|
632
|
-
#
|
|
633
|
-
#
|
|
634
|
-
#
|
|
635
|
-
#
|
|
636
|
-
#
|
|
637
|
-
#
|
|
638
|
-
#
|
|
639
|
-
#
|
|
640
|
-
#
|
|
842
|
+
# {
|
|
843
|
+
# "channel": "book",
|
|
844
|
+
# "type": "snapshot",
|
|
845
|
+
# "data": [
|
|
846
|
+
# {
|
|
847
|
+
# "symbol": "MATIC/USD",
|
|
848
|
+
# "bids": [
|
|
849
|
+
# {
|
|
850
|
+
# "price": 0.5666,
|
|
851
|
+
# "qty": 4831.75496356
|
|
852
|
+
# },
|
|
853
|
+
# {
|
|
854
|
+
# "price": 0.5665,
|
|
855
|
+
# "qty": 6658.22734739
|
|
856
|
+
# }
|
|
857
|
+
# ],
|
|
858
|
+
# "asks": [
|
|
859
|
+
# {
|
|
860
|
+
# "price": 0.5668,
|
|
861
|
+
# "qty": 4410.79769741
|
|
862
|
+
# },
|
|
863
|
+
# {
|
|
864
|
+
# "price": 0.5669,
|
|
865
|
+
# "qty": 4655.40412487
|
|
866
|
+
# }
|
|
867
|
+
# ],
|
|
868
|
+
# "checksum": 2439117997
|
|
869
|
+
# }
|
|
870
|
+
# ]
|
|
871
|
+
# }
|
|
641
872
|
#
|
|
642
873
|
# subsequent updates
|
|
643
874
|
#
|
|
644
|
-
#
|
|
645
|
-
#
|
|
646
|
-
#
|
|
647
|
-
#
|
|
648
|
-
#
|
|
649
|
-
#
|
|
650
|
-
#
|
|
651
|
-
#
|
|
652
|
-
#
|
|
653
|
-
#
|
|
654
|
-
#
|
|
655
|
-
#
|
|
656
|
-
#
|
|
657
|
-
#
|
|
658
|
-
#
|
|
659
|
-
#
|
|
875
|
+
# {
|
|
876
|
+
# "channel": "book",
|
|
877
|
+
# "type": "update",
|
|
878
|
+
# "data": [
|
|
879
|
+
# {
|
|
880
|
+
# "symbol": "MATIC/USD",
|
|
881
|
+
# "bids": [
|
|
882
|
+
# {
|
|
883
|
+
# "price": 0.5657,
|
|
884
|
+
# "qty": 1098.3947558
|
|
885
|
+
# }
|
|
886
|
+
# ],
|
|
887
|
+
# "asks": [],
|
|
888
|
+
# "checksum": 2114181697,
|
|
889
|
+
# "timestamp": "2023-10-06T17:35:55.440295Z"
|
|
890
|
+
# }
|
|
891
|
+
# ]
|
|
892
|
+
# }
|
|
660
893
|
#
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
timestamp = None
|
|
894
|
+
type = self.safe_string(message, 'type')
|
|
895
|
+
data = self.safe_list(message, 'data', [])
|
|
896
|
+
first = self.safe_dict(data, 0, {})
|
|
897
|
+
symbol = self.safe_string(first, 'symbol')
|
|
898
|
+
a = self.safe_value(first, 'asks', [])
|
|
899
|
+
b = self.safe_value(first, 'bids', [])
|
|
900
|
+
c = self.safe_integer(first, 'checksum')
|
|
669
901
|
messageHash = self.get_message_hash('orderbook', None, symbol)
|
|
670
|
-
|
|
671
|
-
if '
|
|
672
|
-
# todo get depth from marketsByWsName
|
|
673
|
-
self.orderbooks[symbol] = self.order_book({}, depth)
|
|
902
|
+
orderbook = None
|
|
903
|
+
if type == 'update':
|
|
674
904
|
orderbook = self.orderbooks[symbol]
|
|
675
|
-
sides: dict = {
|
|
676
|
-
'as': 'asks',
|
|
677
|
-
'bs': 'bids',
|
|
678
|
-
}
|
|
679
|
-
keys = list(sides.keys())
|
|
680
|
-
for i in range(0, len(keys)):
|
|
681
|
-
key = keys[i]
|
|
682
|
-
side = sides[key]
|
|
683
|
-
bookside = orderbook[side]
|
|
684
|
-
deltas = self.safe_value(message[1], key, [])
|
|
685
|
-
timestamp = self.custom_handle_deltas(bookside, deltas, timestamp)
|
|
686
|
-
orderbook['symbol'] = symbol
|
|
687
|
-
orderbook['timestamp'] = timestamp
|
|
688
|
-
orderbook['datetime'] = self.iso8601(timestamp)
|
|
689
|
-
client.resolve(orderbook, messageHash)
|
|
690
|
-
else:
|
|
691
|
-
orderbook = self.orderbooks[symbol]
|
|
692
|
-
# else, if self is an orderbook update
|
|
693
|
-
a = None
|
|
694
|
-
b = None
|
|
695
|
-
c = None
|
|
696
|
-
if messageLength == 5:
|
|
697
|
-
a = self.safe_value(message[1], 'a', [])
|
|
698
|
-
b = self.safe_value(message[2], 'b', [])
|
|
699
|
-
c = self.safe_integer(message[1], 'c')
|
|
700
|
-
c = self.safe_integer(message[2], 'c', c)
|
|
701
|
-
else:
|
|
702
|
-
c = self.safe_integer(message[1], 'c')
|
|
703
|
-
if 'a' in message[1]:
|
|
704
|
-
a = self.safe_value(message[1], 'a', [])
|
|
705
|
-
else:
|
|
706
|
-
b = self.safe_value(message[1], 'b', [])
|
|
707
905
|
storedAsks = orderbook['asks']
|
|
708
906
|
storedBids = orderbook['bids']
|
|
709
|
-
example = None
|
|
710
907
|
if a is not None:
|
|
711
|
-
|
|
712
|
-
example = self.safe_value(a, 0)
|
|
908
|
+
self.custom_handle_deltas(storedAsks, a)
|
|
713
909
|
if b is not None:
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
orderbook.
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
for i in range(0, 10):
|
|
732
|
-
formatted = self.format_number(storedBids[i][0], priceLength) + self.format_number(storedBids[i][1], amountLength)
|
|
733
|
-
payloadArray.append(formatted)
|
|
734
|
-
payload = ''.join(payloadArray)
|
|
735
|
-
localChecksum = self.crc32(payload, False)
|
|
736
|
-
if localChecksum != c:
|
|
737
|
-
error = InvalidNonce(self.id + ' invalid checksum')
|
|
738
|
-
del client.subscriptions[messageHash]
|
|
739
|
-
del self.orderbooks[symbol]
|
|
740
|
-
client.reject(error, messageHash)
|
|
741
|
-
return
|
|
910
|
+
self.custom_handle_deltas(storedBids, b)
|
|
911
|
+
datetime = self.safe_string(first, 'timestamp')
|
|
912
|
+
orderbook['symbol'] = symbol
|
|
913
|
+
orderbook['timestamp'] = self.parse8601(datetime)
|
|
914
|
+
orderbook['datetime'] = datetime
|
|
915
|
+
else:
|
|
916
|
+
# snapshot
|
|
917
|
+
depth = len(a)
|
|
918
|
+
self.orderbooks[symbol] = self.order_book({}, depth)
|
|
919
|
+
orderbook = self.orderbooks[symbol]
|
|
920
|
+
keys = ['asks', 'bids']
|
|
921
|
+
for i in range(0, len(keys)):
|
|
922
|
+
key = keys[i]
|
|
923
|
+
bookside = orderbook[key]
|
|
924
|
+
deltas = self.safe_value(first, key, [])
|
|
925
|
+
if len(deltas) > 0:
|
|
926
|
+
self.custom_handle_deltas(bookside, deltas)
|
|
742
927
|
orderbook['symbol'] = symbol
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
928
|
+
orderbook.limit()
|
|
929
|
+
# checksum temporarily disabled because the exchange checksum was not reliable
|
|
930
|
+
checksum = self.handle_option('watchOrderBook', 'checksum', False)
|
|
931
|
+
if checksum:
|
|
932
|
+
payloadArray = []
|
|
933
|
+
if c is not None:
|
|
934
|
+
checkAsks = orderbook['asks']
|
|
935
|
+
checkBids = orderbook['bids']
|
|
936
|
+
# checkAsks = asks.map((elem) => [elem['price'], elem['qty']])
|
|
937
|
+
# checkBids = bids.map((elem) => [elem['price'], elem['qty']])
|
|
938
|
+
for i in range(0, 10):
|
|
939
|
+
currentAsk = self.safe_value(checkAsks, i, {})
|
|
940
|
+
formattedAsk = self.format_number(currentAsk[0]) + self.format_number(currentAsk[1])
|
|
941
|
+
payloadArray.append(formattedAsk)
|
|
942
|
+
for i in range(0, 10):
|
|
943
|
+
currentBid = self.safe_value(checkBids, i, {})
|
|
944
|
+
formattedBid = self.format_number(currentBid[0]) + self.format_number(currentBid[1])
|
|
945
|
+
payloadArray.append(formattedBid)
|
|
946
|
+
payload = ''.join(payloadArray)
|
|
947
|
+
localChecksum = self.crc32(payload, False)
|
|
948
|
+
if localChecksum != c:
|
|
949
|
+
error = ChecksumError(self.id + ' ' + self.orderbook_checksum_message(symbol))
|
|
950
|
+
del client.subscriptions[messageHash]
|
|
951
|
+
del self.orderbooks[symbol]
|
|
952
|
+
client.reject(error, messageHash)
|
|
953
|
+
return
|
|
954
|
+
client.resolve(orderbook, messageHash)
|
|
746
955
|
|
|
747
|
-
def
|
|
748
|
-
|
|
749
|
-
|
|
956
|
+
def custom_handle_deltas(self, bookside, deltas):
|
|
957
|
+
# sortOrder = True if (key == 'bids') else False
|
|
958
|
+
for j in range(0, len(deltas)):
|
|
959
|
+
delta = deltas[j]
|
|
960
|
+
price = self.safe_number(delta, 'price')
|
|
961
|
+
amount = self.safe_number(delta, 'qty')
|
|
962
|
+
bookside.store(price, amount)
|
|
963
|
+
# if amount == 0:
|
|
964
|
+
# index = bookside.findIndex((x: Int) => x[0] == price)
|
|
965
|
+
# bookside.splice(index, 1)
|
|
966
|
+
# else:
|
|
967
|
+
# bookside.store(price, amount)
|
|
968
|
+
# }
|
|
969
|
+
# bookside = self.sort_by(bookside, 0, sortOrder)
|
|
970
|
+
# bookside[0:9]
|
|
971
|
+
|
|
972
|
+
def format_number(self, data):
|
|
973
|
+
parts = data.split('.')
|
|
750
974
|
integer = self.safe_string(parts, 0)
|
|
751
975
|
decimals = self.safe_string(parts, 1, '')
|
|
752
|
-
|
|
753
|
-
joined = integer + paddedDecimals
|
|
976
|
+
joinedResult = integer + decimals
|
|
754
977
|
i = 0
|
|
755
|
-
while(
|
|
978
|
+
while(joinedResult[i] == '0'):
|
|
756
979
|
i += 1
|
|
757
980
|
if i > 0:
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
return joined
|
|
761
|
-
|
|
762
|
-
def custom_handle_deltas(self, bookside, deltas, timestamp=None):
|
|
763
|
-
for j in range(0, len(deltas)):
|
|
764
|
-
delta = deltas[j]
|
|
765
|
-
price = self.parse_number(delta[0])
|
|
766
|
-
amount = self.parse_number(delta[1])
|
|
767
|
-
oldTimestamp = timestamp if timestamp else 0
|
|
768
|
-
timestamp = max(oldTimestamp, self.parse_to_int(float(delta[2]) * 1000))
|
|
769
|
-
bookside.store(price, amount)
|
|
770
|
-
return timestamp
|
|
981
|
+
joinedResult = joinedResult[i:]
|
|
982
|
+
return joinedResult
|
|
771
983
|
|
|
772
984
|
def handle_system_status(self, client: Client, message):
|
|
773
985
|
#
|
|
@@ -782,6 +994,20 @@ class kraken(ccxt.async_support.kraken):
|
|
|
782
994
|
# "version": "0.2.0"
|
|
783
995
|
# }
|
|
784
996
|
#
|
|
997
|
+
# v2
|
|
998
|
+
# {
|
|
999
|
+
# channel: 'status',
|
|
1000
|
+
# type: 'update',
|
|
1001
|
+
# data: [
|
|
1002
|
+
# {
|
|
1003
|
+
# version: '2.0.10',
|
|
1004
|
+
# system: 'online',
|
|
1005
|
+
# api_version: 'v2',
|
|
1006
|
+
# connection_id: 6447481662169813000
|
|
1007
|
+
# }
|
|
1008
|
+
# ]
|
|
1009
|
+
# }
|
|
1010
|
+
#
|
|
785
1011
|
return message
|
|
786
1012
|
|
|
787
1013
|
async def authenticate(self, params={}):
|
|
@@ -789,7 +1015,11 @@ class kraken(ccxt.async_support.kraken):
|
|
|
789
1015
|
client = self.client(url)
|
|
790
1016
|
authenticated = 'authenticated'
|
|
791
1017
|
subscription = self.safe_value(client.subscriptions, authenticated)
|
|
792
|
-
|
|
1018
|
+
now = self.seconds()
|
|
1019
|
+
start = self.safe_integer(subscription, 'start')
|
|
1020
|
+
expires = self.safe_integer(subscription, 'expires')
|
|
1021
|
+
if (subscription is None) or ((subscription is not None) and (start + expires) <= now):
|
|
1022
|
+
# https://docs.kraken.com/api/docs/rest-api/get-websockets-token
|
|
793
1023
|
response = await self.privatePostGetWebSocketsToken(params)
|
|
794
1024
|
#
|
|
795
1025
|
# {
|
|
@@ -800,7 +1030,8 @@ class kraken(ccxt.async_support.kraken):
|
|
|
800
1030
|
# }
|
|
801
1031
|
# }
|
|
802
1032
|
#
|
|
803
|
-
subscription = self.
|
|
1033
|
+
subscription = self.safe_dict(response, 'result')
|
|
1034
|
+
subscription['start'] = now
|
|
804
1035
|
client.subscriptions[authenticated] = subscription
|
|
805
1036
|
return self.safe_string(subscription, 'token')
|
|
806
1037
|
|
|
@@ -831,11 +1062,14 @@ class kraken(ccxt.async_support.kraken):
|
|
|
831
1062
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
832
1063
|
"""
|
|
833
1064
|
watches information on multiple trades made by the user
|
|
1065
|
+
|
|
1066
|
+
https://docs.kraken.com/api/docs/websocket-v1/owntrades
|
|
1067
|
+
|
|
834
1068
|
:param str symbol: unified market symbol of the market trades were made in
|
|
835
1069
|
:param int [since]: the earliest time in ms to fetch trades for
|
|
836
1070
|
:param int [limit]: the maximum number of trade structures to retrieve
|
|
837
1071
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
838
|
-
:returns dict[]: a list of
|
|
1072
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
|
839
1073
|
"""
|
|
840
1074
|
return await self.watch_private('ownTrades', symbol, since, limit, params)
|
|
841
1075
|
|
|
@@ -979,7 +1213,9 @@ class kraken(ccxt.async_support.kraken):
|
|
|
979
1213
|
|
|
980
1214
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
981
1215
|
"""
|
|
982
|
-
|
|
1216
|
+
|
|
1217
|
+
https://docs.kraken.com/api/docs/websocket-v1/openorders
|
|
1218
|
+
|
|
983
1219
|
watches information on multiple orders made by the user
|
|
984
1220
|
:param str symbol: unified market symbol of the market orders were made in
|
|
985
1221
|
:param int [since]: the earliest time in ms to fetch orders for
|
|
@@ -1229,23 +1465,86 @@ class kraken(ccxt.async_support.kraken):
|
|
|
1229
1465
|
symbols = self.market_symbols(symbols, None, False, True, False)
|
|
1230
1466
|
messageHashes = []
|
|
1231
1467
|
for i in range(0, len(symbols)):
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
wsMarketId = self.safe_string(markets[i]['info'], 'wsname')
|
|
1238
|
-
wsMarketIds.append(wsMarketId)
|
|
1468
|
+
eventTrigger = self.safe_string(params, 'event_trigger')
|
|
1469
|
+
if eventTrigger is not None:
|
|
1470
|
+
messageHashes.append(self.get_message_hash(channelName, None, self.symbol(symbols[i])))
|
|
1471
|
+
else:
|
|
1472
|
+
messageHashes.append(self.get_message_hash(unifiedName, None, self.symbol(symbols[i])))
|
|
1239
1473
|
request: dict = {
|
|
1240
|
-
'
|
|
1241
|
-
'
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
'name': channelName,
|
|
1474
|
+
'method': 'subscribe',
|
|
1475
|
+
'params': {
|
|
1476
|
+
'channel': channelName,
|
|
1477
|
+
'symbol': symbols,
|
|
1245
1478
|
},
|
|
1479
|
+
'req_id': self.request_id(),
|
|
1246
1480
|
}
|
|
1247
|
-
|
|
1248
|
-
|
|
1481
|
+
request['params'] = self.deep_extend(request['params'], params)
|
|
1482
|
+
url = self.urls['api']['ws']['publicV2']
|
|
1483
|
+
return await self.watch_multiple(url, messageHashes, request, messageHashes, subscriptionArgs)
|
|
1484
|
+
|
|
1485
|
+
async def watch_balance(self, params={}) -> Balances:
|
|
1486
|
+
"""
|
|
1487
|
+
watch balance and get the amount of funds available for trading or funds locked in orders
|
|
1488
|
+
|
|
1489
|
+
https://docs.kraken.com/api/docs/websocket-v2/balances
|
|
1490
|
+
|
|
1491
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1492
|
+
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
|
1493
|
+
"""
|
|
1494
|
+
await self.load_markets()
|
|
1495
|
+
token = await self.authenticate()
|
|
1496
|
+
messageHash = 'balances'
|
|
1497
|
+
url = self.urls['api']['ws']['privateV2']
|
|
1498
|
+
requestId = self.request_id()
|
|
1499
|
+
subscribe: dict = {
|
|
1500
|
+
'method': 'subscribe',
|
|
1501
|
+
'req_id': requestId,
|
|
1502
|
+
'params': {
|
|
1503
|
+
'channel': 'balances',
|
|
1504
|
+
'token': token,
|
|
1505
|
+
},
|
|
1506
|
+
}
|
|
1507
|
+
request = self.deep_extend(subscribe, params)
|
|
1508
|
+
return await self.watch(url, messageHash, request, messageHash)
|
|
1509
|
+
|
|
1510
|
+
def handle_balance(self, client: Client, message):
|
|
1511
|
+
#
|
|
1512
|
+
# {
|
|
1513
|
+
# "channel": "balances",
|
|
1514
|
+
# "data": [
|
|
1515
|
+
# {
|
|
1516
|
+
# "asset": "BTC",
|
|
1517
|
+
# "asset_class": "currency",
|
|
1518
|
+
# "balance": 1.2,
|
|
1519
|
+
# "wallets": [
|
|
1520
|
+
# {
|
|
1521
|
+
# "type": "spot",
|
|
1522
|
+
# "id": "main",
|
|
1523
|
+
# "balance": 1.2
|
|
1524
|
+
# }
|
|
1525
|
+
# ]
|
|
1526
|
+
# }
|
|
1527
|
+
# ],
|
|
1528
|
+
# "type": "snapshot",
|
|
1529
|
+
# "sequence": 1
|
|
1530
|
+
# }
|
|
1531
|
+
#
|
|
1532
|
+
data = self.safe_list(message, 'data', [])
|
|
1533
|
+
result: dict = {'info': message}
|
|
1534
|
+
for i in range(0, len(data)):
|
|
1535
|
+
currencyId = self.safe_string(data[i], 'asset')
|
|
1536
|
+
code = self.safe_currency_code(currencyId)
|
|
1537
|
+
account = self.account()
|
|
1538
|
+
eq = self.safe_string(data[i], 'balance')
|
|
1539
|
+
account['total'] = eq
|
|
1540
|
+
result[code] = account
|
|
1541
|
+
type = 'spot'
|
|
1542
|
+
balance = self.safe_balance(result)
|
|
1543
|
+
oldBalance = self.safe_value(self.balance, type, {})
|
|
1544
|
+
newBalance = self.deep_extend(oldBalance, balance)
|
|
1545
|
+
self.balance[type] = self.safe_balance(newBalance)
|
|
1546
|
+
channel = self.safe_string(message, 'channel')
|
|
1547
|
+
client.resolve(self.balance[type], channel)
|
|
1249
1548
|
|
|
1250
1549
|
def get_message_hash(self, unifiedElementName: str, subChannelName: Str = None, symbol: Str = None):
|
|
1251
1550
|
# unifiedElementName can be : orderbook, trade, ticker, bidask ...
|
|
@@ -1292,7 +1591,7 @@ class kraken(ccxt.async_support.kraken):
|
|
|
1292
1591
|
# del client.futures[requestId]
|
|
1293
1592
|
# }
|
|
1294
1593
|
|
|
1295
|
-
def handle_error_message(self, client: Client, message):
|
|
1594
|
+
def handle_error_message(self, client: Client, message) -> Bool:
|
|
1296
1595
|
#
|
|
1297
1596
|
# {
|
|
1298
1597
|
# "errorMessage": "Currency pair not in ISO 4217-A3 format foobar",
|
|
@@ -1303,19 +1602,31 @@ class kraken(ccxt.async_support.kraken):
|
|
|
1303
1602
|
# "subscription": {name: "ticker"}
|
|
1304
1603
|
# }
|
|
1305
1604
|
#
|
|
1306
|
-
|
|
1605
|
+
# v2
|
|
1606
|
+
# {
|
|
1607
|
+
# "error": "Unsupported field: 'price' for the given msg type: add order",
|
|
1608
|
+
# "method": "add_order",
|
|
1609
|
+
# "success": False,
|
|
1610
|
+
# "time_in": "2025-05-13T08:59:44.803511Z",
|
|
1611
|
+
# "time_out": "2025-05-13T08:59:44.803542Z'
|
|
1612
|
+
# }
|
|
1613
|
+
#
|
|
1614
|
+
errorMessage = self.safe_string_2(message, 'errorMessage', 'error')
|
|
1307
1615
|
if errorMessage is not None:
|
|
1308
|
-
requestId = self.
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1616
|
+
# requestId = self.safe_value_2(message, 'reqid', 'req_id')
|
|
1617
|
+
broad = self.exceptions['ws']['broad']
|
|
1618
|
+
broadKey = self.find_broadly_matched_key(broad, errorMessage)
|
|
1619
|
+
exception = None
|
|
1620
|
+
if broadKey is None:
|
|
1621
|
+
exception = ExchangeError(errorMessage) # c# requirement to convert the errorMessage to string
|
|
1622
|
+
else:
|
|
1623
|
+
exception = broad[broadKey](errorMessage)
|
|
1624
|
+
# if requestId is not None:
|
|
1625
|
+
# client.reject(exception, requestId)
|
|
1626
|
+
# else:
|
|
1627
|
+
client.reject(exception)
|
|
1628
|
+
# }
|
|
1629
|
+
return False
|
|
1319
1630
|
return True
|
|
1320
1631
|
|
|
1321
1632
|
def handle_message(self, client: Client, message):
|
|
@@ -1328,10 +1639,7 @@ class kraken(ccxt.async_support.kraken):
|
|
|
1328
1639
|
name = self.safe_string(info, 'name')
|
|
1329
1640
|
methods: dict = {
|
|
1330
1641
|
# public
|
|
1331
|
-
'book': self.handle_order_book,
|
|
1332
1642
|
'ohlc': self.handle_ohlcv,
|
|
1333
|
-
'ticker': self.handle_ticker,
|
|
1334
|
-
'trade': self.handle_trades,
|
|
1335
1643
|
# private
|
|
1336
1644
|
'openOrders': self.handle_orders,
|
|
1337
1645
|
'ownTrades': self.handle_my_trades,
|
|
@@ -1340,16 +1648,28 @@ class kraken(ccxt.async_support.kraken):
|
|
|
1340
1648
|
if method is not None:
|
|
1341
1649
|
method(client, message, subscription)
|
|
1342
1650
|
else:
|
|
1651
|
+
channel = self.safe_string(message, 'channel')
|
|
1652
|
+
if channel is not None:
|
|
1653
|
+
methods: dict = {
|
|
1654
|
+
'balances': self.handle_balance,
|
|
1655
|
+
'book': self.handle_order_book,
|
|
1656
|
+
'ticker': self.handle_ticker,
|
|
1657
|
+
'trade': self.handle_trades,
|
|
1658
|
+
}
|
|
1659
|
+
method = self.safe_value(methods, channel)
|
|
1660
|
+
if method is not None:
|
|
1661
|
+
method(client, message)
|
|
1343
1662
|
if self.handle_error_message(client, message):
|
|
1344
|
-
event = self.
|
|
1663
|
+
event = self.safe_string_2(message, 'event', 'method')
|
|
1345
1664
|
methods: dict = {
|
|
1346
1665
|
'heartbeat': self.handle_heartbeat,
|
|
1347
1666
|
'systemStatus': self.handle_system_status,
|
|
1348
1667
|
'subscriptionStatus': self.handle_subscription_status,
|
|
1349
|
-
'
|
|
1350
|
-
'
|
|
1351
|
-
'
|
|
1352
|
-
'
|
|
1668
|
+
'add_order': self.handle_create_edit_order,
|
|
1669
|
+
'amend_order': self.handle_create_edit_order,
|
|
1670
|
+
'cancel_order': self.handle_cancel_order,
|
|
1671
|
+
'cancel_all': self.handle_cancel_all_orders,
|
|
1672
|
+
'pong': self.handle_pong,
|
|
1353
1673
|
}
|
|
1354
1674
|
method = self.safe_value(methods, event)
|
|
1355
1675
|
if method is not None:
|