ccxt 4.2.77__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 +24 -0
- ccxt/abstract/kucoinfutures.py +34 -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 +3030 -1087
- 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 +3104 -880
- 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 +238 -49
- ccxt/async_support/bitget.py +1513 -563
- ccxt/async_support/bithumb.py +199 -65
- 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 +392 -148
- 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 +2231 -1193
- ccxt/async_support/cex.py +1409 -1329
- ccxt/async_support/coinbase.py +1454 -287
- 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 +404 -109
- ccxt/async_support/deribit.py +557 -323
- 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 +1472 -463
- 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 +1633 -268
- 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 +917 -357
- 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 +1776 -454
- 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 +1137 -296
- 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 +1722 -480
- 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 +3030 -1087
- ccxt/binancecoinm.py +2 -1
- ccxt/binanceus.py +12 -1
- ccxt/binanceusdm.py +3 -1
- ccxt/bingx.py +3104 -880
- 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 +238 -49
- ccxt/bitget.py +1513 -563
- ccxt/bithumb.py +198 -65
- 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 +392 -148
- ccxt/btcalpha.py +161 -55
- ccxt/btcbox.py +250 -34
- ccxt/btcmarkets.py +232 -85
- ccxt/btcturk.py +159 -60
- ccxt/bybit.py +2231 -1193
- ccxt/cex.py +1408 -1329
- ccxt/coinbase.py +1454 -287
- 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 +404 -109
- ccxt/deribit.py +557 -323
- ccxt/digifinex.py +340 -223
- ccxt/ellipx.py +1826 -0
- ccxt/exmo.py +259 -128
- ccxt/gate.py +1472 -463
- 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 +1632 -268
- 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 +917 -357
- 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 +1776 -454
- 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 +62 -14
- 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 +203 -81
- 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 +965 -665
- 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 +167 -31
- ccxt/pro/exmo.py +252 -20
- 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 +92 -33
- ccxt/pro/poloniex.py +128 -49
- ccxt/pro/poloniexfutures.py +53 -32
- ccxt/pro/probit.py +92 -85
- 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 +437 -65
- 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} +456 -391
- ccxt/test/tests_helpers.py +285 -0
- ccxt/test/tests_init.py +39 -0
- ccxt/test/{test_sync.py → tests_sync.py} +456 -393
- 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 +1137 -296
- 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.77.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.77.dist-info/METADATA +0 -626
- ccxt-4.2.77.dist-info/RECORD +0 -534
- {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
ccxt/async_support/kucoin.py
CHANGED
@@ -9,9 +9,10 @@ import asyncio
|
|
9
9
|
import hashlib
|
10
10
|
import math
|
11
11
|
import json
|
12
|
-
from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
12
|
+
from ccxt.base.types import Account, Balances, BorrowInterest, Bool, Currencies, Currency, DepositAddress, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
|
13
13
|
from typing import List
|
14
14
|
from ccxt.base.errors import ExchangeError
|
15
|
+
from ccxt.base.errors import AuthenticationError
|
15
16
|
from ccxt.base.errors import PermissionDenied
|
16
17
|
from ccxt.base.errors import AccountSuspended
|
17
18
|
from ccxt.base.errors import ArgumentsRequired
|
@@ -25,7 +26,7 @@ from ccxt.base.errors import NotSupported
|
|
25
26
|
from ccxt.base.errors import RateLimitExceeded
|
26
27
|
from ccxt.base.errors import ExchangeNotAvailable
|
27
28
|
from ccxt.base.errors import InvalidNonce
|
28
|
-
from ccxt.base.
|
29
|
+
from ccxt.base.decimal_to_precision import TRUNCATE
|
29
30
|
from ccxt.base.decimal_to_precision import TICK_SIZE
|
30
31
|
from ccxt.base.precise import Precise
|
31
32
|
|
@@ -78,6 +79,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
78
79
|
'fetchCrossBorrowRates': False,
|
79
80
|
'fetchCurrencies': True,
|
80
81
|
'fetchDepositAddress': True,
|
82
|
+
'fetchDepositAddresses': False,
|
81
83
|
'fetchDepositAddressesByNetwork': True,
|
82
84
|
'fetchDeposits': True,
|
83
85
|
'fetchDepositWithdrawFee': True,
|
@@ -92,10 +94,13 @@ class kucoin(Exchange, ImplicitAPI):
|
|
92
94
|
'fetchL3OrderBook': True,
|
93
95
|
'fetchLedger': True,
|
94
96
|
'fetchLeverageTiers': False,
|
97
|
+
'fetchMarginAdjustmentHistory': False,
|
95
98
|
'fetchMarginMode': False,
|
96
99
|
'fetchMarketLeverageTiers': False,
|
97
100
|
'fetchMarkets': True,
|
98
101
|
'fetchMarkOHLCV': False,
|
102
|
+
'fetchMarkPrice': True,
|
103
|
+
'fetchMarkPrices': True,
|
99
104
|
'fetchMyTrades': True,
|
100
105
|
'fetchOHLCV': True,
|
101
106
|
'fetchOpenInterest': False,
|
@@ -106,7 +111,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
106
111
|
'fetchOrderBooks': False,
|
107
112
|
'fetchOrdersByStatus': True,
|
108
113
|
'fetchOrderTrades': True,
|
114
|
+
'fetchPositionHistory': False,
|
109
115
|
'fetchPositionMode': False,
|
116
|
+
'fetchPositionsHistory': False,
|
110
117
|
'fetchPremiumIndexOHLCV': False,
|
111
118
|
'fetchStatus': True,
|
112
119
|
'fetchTicker': True,
|
@@ -120,7 +127,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
120
127
|
'fetchWithdrawals': True,
|
121
128
|
'repayCrossMargin': True,
|
122
129
|
'repayIsolatedMargin': True,
|
123
|
-
'setLeverage':
|
130
|
+
'setLeverage': True,
|
124
131
|
'setMarginMode': False,
|
125
132
|
'setPositionMode': False,
|
126
133
|
'signIn': False,
|
@@ -137,6 +144,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
137
144
|
'futuresPublic': 'https://api-futures.kucoin.com',
|
138
145
|
'webExchange': 'https://kucoin.com/_api',
|
139
146
|
'broker': 'https://api-broker.kucoin.com',
|
147
|
+
'earn': 'https://api.kucoin.com',
|
140
148
|
},
|
141
149
|
'www': 'https://www.kucoin.com',
|
142
150
|
'doc': [
|
@@ -174,7 +182,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
174
182
|
'status': 4.5, # 3PW
|
175
183
|
# margin trading
|
176
184
|
'mark-price/{symbol}/current': 3, # 2PW
|
185
|
+
'mark-price/all-symbols': 3,
|
177
186
|
'margin/config': 25, # 25SW
|
187
|
+
'announcements': 20, # 20W
|
178
188
|
},
|
179
189
|
'post': {
|
180
190
|
# ws
|
@@ -213,8 +223,10 @@ class kucoin(Exchange, ImplicitAPI):
|
|
213
223
|
'market/orderbook/level{level}': 3, # 3SW
|
214
224
|
'market/orderbook/level2': 3, # 3SW
|
215
225
|
'market/orderbook/level3': 3, # 3SW
|
226
|
+
'hf/accounts/opened': 2, #
|
216
227
|
'hf/orders/active': 2, # 2SW
|
217
228
|
'hf/orders/active/symbols': 2, # 2SW
|
229
|
+
'hf/margin/order/active/symbols': 2, # 2SW
|
218
230
|
'hf/orders/done': 2, # 2SW
|
219
231
|
'hf/orders/{orderId}': 2, # 2SW
|
220
232
|
'hf/orders/client-order/{clientOid}': 2, # 2SW
|
@@ -243,6 +255,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
243
255
|
'margin/currencies': 20, # 20SW
|
244
256
|
'risk/limit/strategy': 20, # 20SW(Deprecate)
|
245
257
|
'isolated/symbols': 20, # 20SW
|
258
|
+
'margin/symbols': 5,
|
246
259
|
'isolated/account/{symbol}': 50, # 50SW
|
247
260
|
'margin/borrow': 15, # 15SW
|
248
261
|
'margin/repay': 15, # 15SW
|
@@ -253,6 +266,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
253
266
|
'purchase/orders': 10, # 10SW
|
254
267
|
# broker
|
255
268
|
'broker/api/rebase/download': 3,
|
269
|
+
'migrate/user/account/status': 3,
|
270
|
+
# affiliate
|
271
|
+
'affiliate/inviter/statistics': 30,
|
256
272
|
},
|
257
273
|
'post': {
|
258
274
|
# account
|
@@ -292,6 +308,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
292
308
|
'lend/purchase/update': 10, # 10SW
|
293
309
|
# ws
|
294
310
|
'bullet-private': 10, # 10SW
|
311
|
+
'position/update-user-leverage': 5,
|
312
|
+
'deposit-address/create': 20,
|
295
313
|
},
|
296
314
|
'delete': {
|
297
315
|
# account
|
@@ -404,6 +422,10 @@ class kucoin(Exchange, ImplicitAPI):
|
|
404
422
|
'broker/nd/account': 2,
|
405
423
|
'broker/nd/account/apikey': 2,
|
406
424
|
'broker/nd/rebase/download': 3,
|
425
|
+
'asset/ndbroker/deposit/list': 1,
|
426
|
+
'broker/nd/transfer/detail': 1,
|
427
|
+
'broker/nd/deposit/detail': 1,
|
428
|
+
'broker/nd/withdraw/detail': 1,
|
407
429
|
},
|
408
430
|
'post': {
|
409
431
|
'broker/nd/transfer': 1,
|
@@ -415,6 +437,25 @@ class kucoin(Exchange, ImplicitAPI):
|
|
415
437
|
'broker/nd/account/apikey': 3,
|
416
438
|
},
|
417
439
|
},
|
440
|
+
'earn': {
|
441
|
+
'get': {
|
442
|
+
'otc-loan/loan': 1,
|
443
|
+
'otc-loan/accounts': 1,
|
444
|
+
'earn/redeem-preview': 7.5, # 5EW
|
445
|
+
'earn/saving/products': 7.5, # 5EW
|
446
|
+
'earn/hold-assets': 7.5, # 5EW
|
447
|
+
'earn/promotion/products': 7.5, # 5EW
|
448
|
+
'earn/kcs-staking/products': 7.5, # 5EW
|
449
|
+
'earn/staking/products': 7.5, # 5EW
|
450
|
+
'earn/eth-staking/products': 7.5, # 5EW
|
451
|
+
},
|
452
|
+
'post': {
|
453
|
+
'earn/orders': 7.5, # 5EW
|
454
|
+
},
|
455
|
+
'delete': {
|
456
|
+
'earn/orders': 7.5, # 5EW
|
457
|
+
},
|
458
|
+
},
|
418
459
|
},
|
419
460
|
'timeframes': {
|
420
461
|
'1m': '1min',
|
@@ -435,6 +476,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
435
476
|
'precisionMode': TICK_SIZE,
|
436
477
|
'exceptions': {
|
437
478
|
'exact': {
|
479
|
+
'The order does not exist.': OrderNotFound,
|
438
480
|
'order not exist': OrderNotFound,
|
439
481
|
'order not exist.': OrderNotFound, # duplicated error temporarily
|
440
482
|
'order_not_exist': OrderNotFound, # {"code":"order_not_exist","msg":"order_not_exist"} ¯\_(ツ)_/¯
|
@@ -442,6 +484,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
442
484
|
'Order size below the minimum requirement.': InvalidOrder, # {"code":"400100","msg":"Order size below the minimum requirement."}
|
443
485
|
'The withdrawal amount is below the minimum requirement.': ExchangeError, # {"code":"400100","msg":"The withdrawal amount is below the minimum requirement."}
|
444
486
|
'Unsuccessful! Exceeded the max. funds out-transfer limit': InsufficientFunds, # {"code":"200000","msg":"Unsuccessful! Exceeded the max. funds out-transfer limit"}
|
487
|
+
'The amount increment is invalid.': BadRequest,
|
488
|
+
'The quantity is below the minimum requirement.': InvalidOrder, # {"msg":"The quantity is below the minimum requirement.","code":"400100"}
|
445
489
|
'400': BadRequest,
|
446
490
|
'401': AuthenticationError,
|
447
491
|
'403': NotSupported,
|
@@ -465,6 +509,56 @@ class kucoin(Exchange, ImplicitAPI):
|
|
465
509
|
'130202': ExchangeError, # The system is renewing the loan automatically. Please try again later
|
466
510
|
'130203': InsufficientFunds, # Insufficient account balance
|
467
511
|
'130204': BadRequest, # As the total lending amount for platform leverage reaches the platform's maximum position limit, the system suspends the borrowing function of leverage
|
512
|
+
'130301': InsufficientFunds, # Insufficient account balance
|
513
|
+
'130302': PermissionDenied, # Your relevant permission rights have been restricted, you can contact customer service for processing
|
514
|
+
'130303': NotSupported, # The current trading pair does not support isolated positions
|
515
|
+
'130304': NotSupported, # The trading function of the current trading pair is not enabled
|
516
|
+
'130305': NotSupported, # The current trading pair does not support cross position
|
517
|
+
'130306': NotSupported, # The account has not opened leveraged trading
|
518
|
+
'130307': NotSupported, # Please reopen the leverage agreement
|
519
|
+
'130308': InvalidOrder, # Position renewal freeze
|
520
|
+
'130309': InvalidOrder, # Position forced liquidation freeze
|
521
|
+
'130310': ExchangeError, # Abnormal leverage account status
|
522
|
+
'130311': InvalidOrder, # Failed to place an order, triggering buy limit
|
523
|
+
'130312': InvalidOrder, # Trigger global position limit, suspend buying
|
524
|
+
'130313': InvalidOrder, # Trigger global position limit, suspend selling
|
525
|
+
'130314': InvalidOrder, # Trigger the global position limit and prompt the remaining quantity available for purchase
|
526
|
+
'130315': NotSupported, # This feature has been suspended due to country restrictions
|
527
|
+
'126000': ExchangeError, # Abnormal margin trading
|
528
|
+
'126001': NotSupported, # Users currently do not support high frequency
|
529
|
+
'126002': ExchangeError, # There is a risk problem in your account and transactions are temporarily not allowed!
|
530
|
+
'126003': InvalidOrder, # The commission amount is less than the minimum transaction amount for a single commission
|
531
|
+
'126004': ExchangeError, # Trading pair does not exist or is prohibited
|
532
|
+
'126005': PermissionDenied, # This trading pair requires advanced KYC certification before trading
|
533
|
+
'126006': ExchangeError, # Trading pair is not available
|
534
|
+
'126007': ExchangeError, # Trading pair suspended
|
535
|
+
'126009': ExchangeError, # Trading pair is suspended from creating orders
|
536
|
+
'126010': ExchangeError, # Trading pair suspended order cancellation
|
537
|
+
'126011': ExchangeError, # There are too many orders in the order
|
538
|
+
'126013': InsufficientFunds, # Insufficient account balance
|
539
|
+
'126015': ExchangeError, # It is prohibited to place orders on self trading pair
|
540
|
+
'126021': NotSupported, # This digital asset does not support user participation in your region, thank you for your understanding!
|
541
|
+
'126022': InvalidOrder, # The final transaction price of your order will trigger the price protection strategy. To protect the price from deviating too much, please place an order again.
|
542
|
+
'126027': InvalidOrder, # Only limit orders are supported
|
543
|
+
'126028': InvalidOrder, # Only limit orders are supported before the specified time
|
544
|
+
'126029': InvalidOrder, # The maximum order price is: xxx
|
545
|
+
'126030': InvalidOrder, # The minimum order price is: xxx
|
546
|
+
'126033': InvalidOrder, # Duplicate order
|
547
|
+
'126034': InvalidOrder, # Failed to create take profit and stop loss order
|
548
|
+
'126036': InvalidOrder, # Failed to create margin order
|
549
|
+
'126037': ExchangeError, # Due to country and region restrictions, self function has been suspended!
|
550
|
+
'126038': ExchangeError, # Third-party service call failed(internal exception)
|
551
|
+
'126039': ExchangeError, # Third-party service call failed, reason: xxx
|
552
|
+
'126041': ExchangeError, # clientTimestamp parameter error
|
553
|
+
'126042': ExchangeError, # Exceeded maximum position limit
|
554
|
+
'126043': OrderNotFound, # Order does not exist
|
555
|
+
'126044': InvalidOrder, # clientOid duplicate
|
556
|
+
'126045': NotSupported, # This digital asset does not support user participation in your region, thank you for your understanding!
|
557
|
+
'126046': NotSupported, # This digital asset does not support your IP region, thank you for your understanding!
|
558
|
+
'126047': PermissionDenied, # Please complete identity verification
|
559
|
+
'126048': PermissionDenied, # Please complete authentication for the master account
|
560
|
+
'135005': ExchangeError, # Margin order query business abnormality
|
561
|
+
'135018': ExchangeError, # Margin order query service abnormality
|
468
562
|
'200004': InsufficientFunds,
|
469
563
|
'210014': InvalidOrder, # {"code":"210014","msg":"Exceeds the max. borrowing amount, the remaining amount you can borrow: 0USDT"}
|
470
564
|
'210021': InsufficientFunds, # {"code":"210021","msg":"Balance not enough"}
|
@@ -481,20 +575,25 @@ class kucoin(Exchange, ImplicitAPI):
|
|
481
575
|
'400006': AuthenticationError,
|
482
576
|
'400007': AuthenticationError,
|
483
577
|
'400008': NotSupported,
|
484
|
-
'400100': InsufficientFunds, # {"msg":"account.available.amount","code":"400100"}
|
578
|
+
'400100': InsufficientFunds, # {"msg":"account.available.amount","code":"400100"} or {"msg":"Withdrawal amount is below the minimum requirement.","code":"400100"}
|
485
579
|
'400200': InvalidOrder, # {"code":"400200","msg":"Forbidden to place an order"}
|
580
|
+
'400330': InvalidOrder, # {"msg":"Order price can't deviate from NAV by 50%","code":"400330"}
|
486
581
|
'400350': InvalidOrder, # {"code":"400350","msg":"Upper limit for holding: 10,000USDT, you can still buy 10,000USDT worth of coin."}
|
487
582
|
'400370': InvalidOrder, # {"code":"400370","msg":"Max. price: 0.02500000000000000000"}
|
488
583
|
'400400': BadRequest, # Parameter error
|
584
|
+
'400401': AuthenticationError, # User is not logged in
|
489
585
|
'400500': InvalidOrder, # {"code":"400500","msg":"Your located country/region is currently not supported for the trading of self token"}
|
490
586
|
'400600': BadSymbol, # {"code":"400600","msg":"validation.createOrder.symbolNotAvailable"}
|
491
587
|
'400760': InvalidOrder, # {"code":"400760","msg":"order price should be more than XX"}
|
492
588
|
'401000': BadRequest, # {"code":"401000","msg":"The interface has been deprecated"}
|
589
|
+
'408000': BadRequest, # Network timeout, please try again later
|
493
590
|
'411100': AccountSuspended,
|
494
591
|
'415000': BadRequest, # {"code":"415000","msg":"Unsupported Media Type"}
|
495
592
|
'400303': PermissionDenied, # {"msg":"To enjoy the full range of our products and services, we kindly request you complete the identity verification process.","code":"400303"}
|
496
593
|
'500000': ExchangeNotAvailable, # {"code":"500000","msg":"Internal Server Error"}
|
497
594
|
'260220': InvalidAddress, # {"code": "260220", "msg": "deposit.address.not.exists"}
|
595
|
+
'600100': InsufficientFunds, # {"msg":"Funds below the minimum requirement.","code":"600100"}
|
596
|
+
'600101': InvalidOrder, # {"msg":"The order funds should more then 0.1 USDT.","code":"600101"}
|
498
597
|
'900014': BadRequest, # {"code":"900014","msg":"Invalid chainId"}
|
499
598
|
},
|
500
599
|
'broad': {
|
@@ -552,11 +651,17 @@ class kucoin(Exchange, ImplicitAPI):
|
|
552
651
|
'BIFI': 'BIFIF',
|
553
652
|
'VAI': 'VAIOT',
|
554
653
|
'WAX': 'WAXP',
|
654
|
+
'ALT': 'APTOSLAUNCHTOKEN',
|
655
|
+
'KALT': 'ALT', # ALTLAYER
|
656
|
+
'FUD': 'FTX Users\' Debt',
|
555
657
|
},
|
556
658
|
'options': {
|
659
|
+
'hf': None, # would be auto set to `true/false` after first load
|
557
660
|
'version': 'v1',
|
558
661
|
'symbolSeparator': '-',
|
559
662
|
'fetchMyTradesMethod': 'private_get_fills',
|
663
|
+
'timeDifference': 0, # the difference between system clock and Binance clock
|
664
|
+
'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
|
560
665
|
'fetchCurrencies': {
|
561
666
|
'webApiEnable': True, # fetches from WEB
|
562
667
|
'webApiRetries': 1,
|
@@ -576,6 +681,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
576
681
|
'currencies': 'v3',
|
577
682
|
'currencies/{currency}': 'v3',
|
578
683
|
'symbols': 'v2',
|
684
|
+
'mark-price/all-symbols': 'v3',
|
685
|
+
'announcements': 'v3',
|
579
686
|
},
|
580
687
|
},
|
581
688
|
'private': {
|
@@ -600,6 +707,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
600
707
|
'oco/orders': 'v3',
|
601
708
|
# margin trading
|
602
709
|
'hf/margin/orders/active': 'v3',
|
710
|
+
'hf/margin/order/active/symbols': 'v3',
|
603
711
|
'hf/margin/orders/done': 'v3',
|
604
712
|
'hf/margin/orders/{orderId}': 'v3',
|
605
713
|
'hf/margin/orders/client-order/{clientOid}': 'v3',
|
@@ -613,6 +721,10 @@ class kucoin(Exchange, ImplicitAPI):
|
|
613
721
|
'project/marketInterestRate': 'v3',
|
614
722
|
'redeem/orders': 'v3',
|
615
723
|
'purchase/orders': 'v3',
|
724
|
+
'migrate/user/account/status': 'v3',
|
725
|
+
'margin/symbols': 'v3',
|
726
|
+
'affiliate/inviter/statistics': 'v2',
|
727
|
+
'asset/ndbroker/deposit/list': 'v1',
|
616
728
|
},
|
617
729
|
'POST': {
|
618
730
|
# account
|
@@ -622,6 +734,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
622
734
|
'accounts/sub-transfer': 'v2',
|
623
735
|
'accounts/inner-transfer': 'v2',
|
624
736
|
'transfer-out': 'v3',
|
737
|
+
'deposit-address/create': 'v3',
|
625
738
|
# spot trading
|
626
739
|
'oco/order': 'v3',
|
627
740
|
# margin trading
|
@@ -632,6 +745,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
632
745
|
'purchase': 'v3',
|
633
746
|
'redeem': 'v3',
|
634
747
|
'lend/purchase/update': 'v3',
|
748
|
+
'position/update-user-leverage': 'v3',
|
749
|
+
'withdrawals': 'v3',
|
635
750
|
},
|
636
751
|
'DELETE': {
|
637
752
|
# account
|
@@ -679,7 +794,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
679
794
|
'hf': 'trade_hf',
|
680
795
|
},
|
681
796
|
'networks': {
|
682
|
-
'
|
797
|
+
'BRC20': 'btc',
|
683
798
|
'BTCNATIVESEGWIT': 'bech32',
|
684
799
|
'ERC20': 'eth',
|
685
800
|
'TRC20': 'trx',
|
@@ -697,7 +812,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
697
812
|
'TLOS': 'tlos', # tlosevm is different
|
698
813
|
'CFX': 'cfx',
|
699
814
|
'ACA': 'aca',
|
700
|
-
'
|
815
|
+
'OP': 'optimism',
|
701
816
|
'ONT': 'ont',
|
702
817
|
'GLMR': 'glmr',
|
703
818
|
'CSPR': 'cspr',
|
@@ -816,6 +931,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
816
931
|
'TRUE': 'true',
|
817
932
|
'CS': 'cs',
|
818
933
|
'ORAI': 'orai',
|
934
|
+
'BASE': 'base',
|
819
935
|
# below will be uncommented after consensus
|
820
936
|
# 'BITCOINDIAMON': 'bcd',
|
821
937
|
# 'BITCOINGOLD': 'btg',
|
@@ -891,15 +1007,85 @@ class kucoin(Exchange, ImplicitAPI):
|
|
891
1007
|
'spot': 'TRADE',
|
892
1008
|
},
|
893
1009
|
},
|
1010
|
+
'features': {
|
1011
|
+
'spot': {
|
1012
|
+
'sandbox': False,
|
1013
|
+
'createOrder': {
|
1014
|
+
'marginMode': True,
|
1015
|
+
'triggerPrice': True,
|
1016
|
+
'triggerPriceType': None,
|
1017
|
+
'triggerDirection': False,
|
1018
|
+
'stopLossPrice': True,
|
1019
|
+
'takeProfitPrice': True,
|
1020
|
+
'attachedStopLossTakeProfit': None, # not supported
|
1021
|
+
'timeInForce': {
|
1022
|
+
'IOC': True,
|
1023
|
+
'FOK': True,
|
1024
|
+
'PO': True,
|
1025
|
+
'GTD': True,
|
1026
|
+
},
|
1027
|
+
'hedged': False,
|
1028
|
+
'trailing': False,
|
1029
|
+
'leverage': False,
|
1030
|
+
'marketBuyByCost': True,
|
1031
|
+
'marketBuyRequiresPrice': False,
|
1032
|
+
'selfTradePrevention': True, # todo implement
|
1033
|
+
'iceberg': True, # todo implement
|
1034
|
+
},
|
1035
|
+
'createOrders': {
|
1036
|
+
'max': 5,
|
1037
|
+
},
|
1038
|
+
'fetchMyTrades': {
|
1039
|
+
'marginMode': True,
|
1040
|
+
'limit': None,
|
1041
|
+
'daysBack': None,
|
1042
|
+
'untilDays': 7, # per implementation comments
|
1043
|
+
},
|
1044
|
+
'fetchOrder': {
|
1045
|
+
'marginMode': False,
|
1046
|
+
'trigger': True,
|
1047
|
+
'trailing': False,
|
1048
|
+
},
|
1049
|
+
'fetchOpenOrders': {
|
1050
|
+
'marginMode': True,
|
1051
|
+
'limit': 500,
|
1052
|
+
'trigger': True,
|
1053
|
+
'trailing': False,
|
1054
|
+
},
|
1055
|
+
'fetchOrders': None,
|
1056
|
+
'fetchClosedOrders': {
|
1057
|
+
'marginMode': True,
|
1058
|
+
'limit': 500,
|
1059
|
+
'daysBack': None,
|
1060
|
+
'daysBackCanceled': None,
|
1061
|
+
'untilDays': 7,
|
1062
|
+
'trigger': True,
|
1063
|
+
'trailing': False,
|
1064
|
+
},
|
1065
|
+
'fetchOHLCV': {
|
1066
|
+
'limit': 1500,
|
1067
|
+
},
|
1068
|
+
},
|
1069
|
+
'swap': {
|
1070
|
+
'linear': None,
|
1071
|
+
'inverse': None,
|
1072
|
+
},
|
1073
|
+
'future': {
|
1074
|
+
'linear': None,
|
1075
|
+
'inverse': None,
|
1076
|
+
},
|
1077
|
+
},
|
894
1078
|
})
|
895
1079
|
|
896
1080
|
def nonce(self):
|
897
|
-
return self.milliseconds()
|
1081
|
+
return self.milliseconds() - self.options['timeDifference']
|
898
1082
|
|
899
1083
|
async def fetch_time(self, params={}):
|
900
1084
|
"""
|
901
1085
|
fetches the current integer timestamp in milliseconds from the exchange server
|
902
|
-
|
1086
|
+
|
1087
|
+
https://docs.kucoin.com/#server-time
|
1088
|
+
|
903
1089
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
904
1090
|
:returns int: the current integer timestamp in milliseconds from the exchange server
|
905
1091
|
"""
|
@@ -916,7 +1102,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
916
1102
|
async def fetch_status(self, params={}):
|
917
1103
|
"""
|
918
1104
|
the latest known information on the availability of the exchange API
|
919
|
-
|
1105
|
+
|
1106
|
+
https://docs.kucoin.com/#service-status
|
1107
|
+
|
920
1108
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
921
1109
|
:returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
|
922
1110
|
"""
|
@@ -940,15 +1128,20 @@ class kucoin(Exchange, ImplicitAPI):
|
|
940
1128
|
'info': response,
|
941
1129
|
}
|
942
1130
|
|
943
|
-
async def fetch_markets(self, params={}):
|
1131
|
+
async def fetch_markets(self, params={}) -> List[Market]:
|
944
1132
|
"""
|
945
1133
|
retrieves data on all markets for kucoin
|
946
|
-
|
947
|
-
|
1134
|
+
|
1135
|
+
https://docs.kucoin.com/#get-symbols-list-deprecated
|
1136
|
+
https://docs.kucoin.com/#get-all-tickers
|
1137
|
+
|
948
1138
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
949
1139
|
:returns dict[]: an array of objects representing market data
|
950
1140
|
"""
|
951
|
-
|
1141
|
+
fetchTickersFees = None
|
1142
|
+
fetchTickersFees, params = self.handle_option_and_params(params, 'fetchMarkets', 'fetchTickersFees', True)
|
1143
|
+
promises = []
|
1144
|
+
promises.append(self.publicGetSymbols(params))
|
952
1145
|
#
|
953
1146
|
# {
|
954
1147
|
# "code": "200000",
|
@@ -971,59 +1164,102 @@ class kucoin(Exchange, ImplicitAPI):
|
|
971
1164
|
# "isMarginEnabled": True,
|
972
1165
|
# "enableTrading": True
|
973
1166
|
# },
|
974
|
-
# ]
|
975
|
-
# }
|
976
1167
|
#
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
1168
|
+
credentialsSet = self.check_required_credentials(False)
|
1169
|
+
requestMarginables = credentialsSet and self.safe_bool(params, 'marginables', True)
|
1170
|
+
if requestMarginables:
|
1171
|
+
promises.append(self.privateGetMarginSymbols(params)) # cross margin symbols
|
1172
|
+
#
|
1173
|
+
# {
|
1174
|
+
# "code": "200000",
|
1175
|
+
# "data": {
|
1176
|
+
# "timestamp": 1719393213421,
|
1177
|
+
# "items": [
|
1178
|
+
# {
|
1179
|
+
# # same object market, with one additional field:
|
1180
|
+
# "minFunds": "0.1"
|
1181
|
+
# },
|
1182
|
+
#
|
1183
|
+
promises.append(self.privateGetIsolatedSymbols(params)) # isolated margin symbols
|
1184
|
+
#
|
1185
|
+
# {
|
1186
|
+
# "code": "200000",
|
1187
|
+
# "data": [
|
1188
|
+
# {
|
1189
|
+
# "symbol": "NKN-USDT",
|
1190
|
+
# "symbolName": "NKN-USDT",
|
1191
|
+
# "baseCurrency": "NKN",
|
1192
|
+
# "quoteCurrency": "USDT",
|
1193
|
+
# "maxLeverage": 5,
|
1194
|
+
# "flDebtRatio": "0.97",
|
1195
|
+
# "tradeEnable": True,
|
1196
|
+
# "autoRenewMaxDebtRatio": "0.96",
|
1197
|
+
# "baseBorrowEnable": True,
|
1198
|
+
# "quoteBorrowEnable": True,
|
1199
|
+
# "baseTransferInEnable": True,
|
1200
|
+
# "quoteTransferInEnable": True,
|
1201
|
+
# "baseBorrowCoefficient": "1",
|
1202
|
+
# "quoteBorrowCoefficient": "1"
|
1203
|
+
# },
|
1204
|
+
#
|
981
1205
|
if fetchTickersFees:
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1206
|
+
promises.append(self.publicGetMarketAllTickers(params))
|
1207
|
+
#
|
1208
|
+
# {
|
1209
|
+
# "code": "200000",
|
1210
|
+
# "data": {
|
1211
|
+
# "time":1602832092060,
|
1212
|
+
# "ticker":[
|
1213
|
+
# {
|
1214
|
+
# "symbol": "BTC-USDT", # symbol
|
1215
|
+
# "symbolName":"BTC-USDT", # Name of trading pairs, it would change after renaming
|
1216
|
+
# "buy": "11328.9", # bestAsk
|
1217
|
+
# "sell": "11329", # bestBid
|
1218
|
+
# "changeRate": "-0.0055", # 24h change rate
|
1219
|
+
# "changePrice": "-63.6", # 24h change price
|
1220
|
+
# "high": "11610", # 24h highest price
|
1221
|
+
# "low": "11200", # 24h lowest price
|
1222
|
+
# "vol": "2282.70993217", # 24h volume,the aggregated trading volume in BTC
|
1223
|
+
# "volValue": "25984946.157790431", # 24h total, the trading volume in quote currency of last 24 hours
|
1224
|
+
# "last": "11328.9", # last price
|
1225
|
+
# "averagePrice": "11360.66065903", # 24h average transaction price yesterday
|
1226
|
+
# "takerFeeRate": "0.001", # Basic Taker Fee
|
1227
|
+
# "makerFeeRate": "0.001", # Basic Maker Fee
|
1228
|
+
# "takerCoefficient": "1", # Taker Fee Coefficient
|
1229
|
+
# "makerCoefficient": "1" # Maker Fee Coefficient
|
1230
|
+
# }
|
1231
|
+
#
|
1232
|
+
if credentialsSet:
|
1233
|
+
# load migration status for account
|
1234
|
+
promises.append(self.load_migration_status())
|
1235
|
+
responses = await asyncio.gather(*promises)
|
1236
|
+
symbolsData = self.safe_list(responses[0], 'data')
|
1237
|
+
crossData = self.safe_dict(responses[1], 'data', {}) if requestMarginables else {}
|
1238
|
+
crossItems = self.safe_list(crossData, 'items', [])
|
1239
|
+
crossById = self.index_by(crossItems, 'symbol')
|
1240
|
+
isolatedData = responses[2] if requestMarginables else {}
|
1241
|
+
isolatedItems = self.safe_list(isolatedData, 'data', [])
|
1242
|
+
isolatedById = self.index_by(isolatedItems, 'symbol')
|
1243
|
+
tickersIdx = 3 if requestMarginables else 1
|
1244
|
+
tickersResponse = self.safe_dict(responses, tickersIdx, {})
|
1245
|
+
tickerItems = self.safe_list(self.safe_dict(tickersResponse, 'data', {}), 'ticker', [])
|
1246
|
+
tickersById = self.index_by(tickerItems, 'symbol')
|
1014
1247
|
result = []
|
1015
|
-
for i in range(0, len(
|
1016
|
-
market =
|
1248
|
+
for i in range(0, len(symbolsData)):
|
1249
|
+
market = symbolsData[i]
|
1017
1250
|
id = self.safe_string(market, 'symbol')
|
1018
1251
|
baseId, quoteId = id.split('-')
|
1019
1252
|
base = self.safe_currency_code(baseId)
|
1020
1253
|
quote = self.safe_currency_code(quoteId)
|
1021
1254
|
# quoteIncrement = self.safe_number(market, 'quoteIncrement')
|
1022
|
-
ticker = self.safe_dict(
|
1255
|
+
ticker = self.safe_dict(tickersById, id, {})
|
1023
1256
|
makerFeeRate = self.safe_string(ticker, 'makerFeeRate')
|
1024
1257
|
takerFeeRate = self.safe_string(ticker, 'takerFeeRate')
|
1025
1258
|
makerCoefficient = self.safe_string(ticker, 'makerCoefficient')
|
1026
1259
|
takerCoefficient = self.safe_string(ticker, 'takerCoefficient')
|
1260
|
+
hasCrossMargin = (id in crossById)
|
1261
|
+
hasIsolatedMargin = (id in isolatedById)
|
1262
|
+
isMarginable = self.safe_bool(market, 'isMarginEnabled', False) or hasCrossMargin or hasIsolatedMargin
|
1027
1263
|
result.append({
|
1028
1264
|
'id': id,
|
1029
1265
|
'symbol': base + '/' + quote,
|
@@ -1035,7 +1271,11 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1035
1271
|
'settleId': None,
|
1036
1272
|
'type': 'spot',
|
1037
1273
|
'spot': True,
|
1038
|
-
'margin':
|
1274
|
+
'margin': isMarginable,
|
1275
|
+
'marginModes': {
|
1276
|
+
'cross': hasCrossMargin,
|
1277
|
+
'isolated': hasIsolatedMargin,
|
1278
|
+
},
|
1039
1279
|
'swap': False,
|
1040
1280
|
'future': False,
|
1041
1281
|
'option': False,
|
@@ -1075,12 +1315,40 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1075
1315
|
'created': None,
|
1076
1316
|
'info': market,
|
1077
1317
|
})
|
1318
|
+
if self.options['adjustForTimeDifference']:
|
1319
|
+
await self.load_time_difference()
|
1078
1320
|
return result
|
1079
1321
|
|
1080
|
-
async def
|
1322
|
+
async def load_migration_status(self, force: bool = False):
|
1323
|
+
"""
|
1324
|
+
:param boolean force: load account state for non hf
|
1325
|
+
loads the migration status for the account(hf or not)
|
1326
|
+
|
1327
|
+
https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/get-user-type
|
1328
|
+
|
1329
|
+
"""
|
1330
|
+
if not ('hf' in self.options) or (self.options['hf'] is None) or force:
|
1331
|
+
result: dict = await self.privateGetHfAccountsOpened()
|
1332
|
+
self.options['hf'] = self.safe_bool(result, 'data')
|
1333
|
+
|
1334
|
+
def handle_hf_and_params(self, params={}):
|
1335
|
+
migrated: Bool = self.safe_bool(self.options, 'hf', False)
|
1336
|
+
loadedHf: Bool = None
|
1337
|
+
if migrated is not None:
|
1338
|
+
if migrated:
|
1339
|
+
loadedHf = True
|
1340
|
+
else:
|
1341
|
+
loadedHf = False
|
1342
|
+
hf: Bool = self.safe_bool(params, 'hf', loadedHf)
|
1343
|
+
params = self.omit(params, 'hf')
|
1344
|
+
return [hf, params]
|
1345
|
+
|
1346
|
+
async def fetch_currencies(self, params={}) -> Currencies:
|
1081
1347
|
"""
|
1082
1348
|
fetches all available currencies on an exchange
|
1083
|
-
|
1349
|
+
|
1350
|
+
https://docs.kucoin.com/#get-currencies
|
1351
|
+
|
1084
1352
|
:param dict params: extra parameters specific to the exchange API endpoint
|
1085
1353
|
:returns dict: an associative dictionary of currencies
|
1086
1354
|
"""
|
@@ -1102,8 +1370,10 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1102
1370
|
# "chains":[
|
1103
1371
|
# {
|
1104
1372
|
# "chainName":"ERC20",
|
1105
|
-
# "
|
1373
|
+
# "chainId": "eth"
|
1106
1374
|
# "withdrawalMinSize":"2999",
|
1375
|
+
# "depositMinSize":null,
|
1376
|
+
# "withdrawFeeRate":"0",
|
1107
1377
|
# "withdrawalMinFee":"2999",
|
1108
1378
|
# "isWithdrawEnabled":false,
|
1109
1379
|
# "isDepositEnabled":false,
|
@@ -1152,12 +1422,12 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1152
1422
|
# }
|
1153
1423
|
#
|
1154
1424
|
responses = await asyncio.gather(*promises)
|
1155
|
-
currenciesResponse = self.
|
1156
|
-
currenciesData = self.
|
1157
|
-
additionalResponse = self.
|
1158
|
-
additionalData = self.
|
1425
|
+
currenciesResponse = self.safe_dict(responses, 0, {})
|
1426
|
+
currenciesData = self.safe_list(currenciesResponse, 'data', [])
|
1427
|
+
additionalResponse = self.safe_dict(responses, 1, {})
|
1428
|
+
additionalData = self.safe_list(additionalResponse, 'data', [])
|
1159
1429
|
additionalDataGrouped = self.group_by(additionalData, 'currency')
|
1160
|
-
result = {}
|
1430
|
+
result: dict = {}
|
1161
1431
|
for i in range(0, len(currenciesData)):
|
1162
1432
|
entry = currenciesData[i]
|
1163
1433
|
id = self.safe_string(entry, 'currency')
|
@@ -1165,9 +1435,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1165
1435
|
code = self.safe_currency_code(id)
|
1166
1436
|
isWithdrawEnabled = None
|
1167
1437
|
isDepositEnabled = None
|
1168
|
-
networks = {}
|
1438
|
+
networks: dict = {}
|
1169
1439
|
chains = self.safe_list(entry, 'chains', [])
|
1170
|
-
extraChainsData = self.index_by(self.
|
1440
|
+
extraChainsData = self.index_by(self.safe_list(additionalDataGrouped, id, []), 'chain')
|
1171
1441
|
rawPrecision = self.safe_string(entry, 'precision')
|
1172
1442
|
precision = self.parse_number(self.parse_precision(rawPrecision))
|
1173
1443
|
chainsLength = len(chains)
|
@@ -1178,7 +1448,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1178
1448
|
for j in range(0, chainsLength):
|
1179
1449
|
chain = chains[j]
|
1180
1450
|
chainId = self.safe_string(chain, 'chainId')
|
1181
|
-
networkCode = self.network_id_to_code(chainId)
|
1451
|
+
networkCode = self.network_id_to_code(chainId, code)
|
1182
1452
|
chainWithdrawEnabled = self.safe_bool(chain, 'isWithdrawEnabled', False)
|
1183
1453
|
if isWithdrawEnabled is None:
|
1184
1454
|
isWithdrawEnabled = chainWithdrawEnabled
|
@@ -1206,7 +1476,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1206
1476
|
'max': None,
|
1207
1477
|
},
|
1208
1478
|
'deposit': {
|
1209
|
-
'min': self.safe_number(
|
1479
|
+
'min': self.safe_number(chain, 'depositMinSize'),
|
1210
1480
|
'max': None,
|
1211
1481
|
},
|
1212
1482
|
},
|
@@ -1232,7 +1502,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1232
1502
|
async def fetch_accounts(self, params={}) -> List[Account]:
|
1233
1503
|
"""
|
1234
1504
|
fetch all the accounts associated with a profile
|
1235
|
-
|
1505
|
+
|
1506
|
+
https://docs.kucoin.com/#list-accounts
|
1507
|
+
|
1236
1508
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1237
1509
|
:returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
|
1238
1510
|
"""
|
@@ -1280,14 +1552,16 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1280
1552
|
async def fetch_transaction_fee(self, code: str, params={}):
|
1281
1553
|
"""
|
1282
1554
|
*DEPRECATED* please use fetchDepositWithdrawFee instead
|
1283
|
-
|
1555
|
+
|
1556
|
+
https://docs.kucoin.com/#get-withdrawal-quotas
|
1557
|
+
|
1284
1558
|
:param str code: unified currency code
|
1285
1559
|
:param dict params: extra parameters specific to the exchange API endpoint
|
1286
1560
|
:returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
|
1287
1561
|
"""
|
1288
1562
|
await self.load_markets()
|
1289
1563
|
currency = self.currency(code)
|
1290
|
-
request = {
|
1564
|
+
request: dict = {
|
1291
1565
|
'currency': currency['id'],
|
1292
1566
|
}
|
1293
1567
|
networkCode = None
|
@@ -1295,8 +1569,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1295
1569
|
if networkCode is not None:
|
1296
1570
|
request['chain'] = self.network_code_to_id(networkCode).lower()
|
1297
1571
|
response = await self.privateGetWithdrawalsQuotas(self.extend(request, params))
|
1298
|
-
data = self.
|
1299
|
-
withdrawFees = {}
|
1572
|
+
data = self.safe_dict(response, 'data', {})
|
1573
|
+
withdrawFees: dict = {}
|
1300
1574
|
withdrawFees[code] = self.safe_number(data, 'withdrawMinFee')
|
1301
1575
|
return {
|
1302
1576
|
'info': response,
|
@@ -1307,7 +1581,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1307
1581
|
async def fetch_deposit_withdraw_fee(self, code: str, params={}):
|
1308
1582
|
"""
|
1309
1583
|
fetch the fee for deposits and withdrawals
|
1310
|
-
|
1584
|
+
|
1585
|
+
https://docs.kucoin.com/#get-withdrawal-quotas
|
1586
|
+
|
1311
1587
|
:param str code: unified currency code
|
1312
1588
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1313
1589
|
:param str [params.network]: The chain of currency. This only apply for multi-chain currency, and there is no need for single chain currency; you can query the chain through the response of the GET /api/v2/currencies/{currency} interface
|
@@ -1315,7 +1591,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1315
1591
|
"""
|
1316
1592
|
await self.load_markets()
|
1317
1593
|
currency = self.currency(code)
|
1318
|
-
request = {
|
1594
|
+
request: dict = {
|
1319
1595
|
'currency': currency['id'],
|
1320
1596
|
}
|
1321
1597
|
networkCode = None
|
@@ -1360,32 +1636,28 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1360
1636
|
# "chain": "ERC20"
|
1361
1637
|
# }
|
1362
1638
|
#
|
1363
|
-
|
1639
|
+
minWithdrawFee = self.safe_number(fee, 'withdrawMinFee')
|
1640
|
+
result: dict = {
|
1364
1641
|
'info': fee,
|
1365
1642
|
'withdraw': {
|
1643
|
+
'fee': minWithdrawFee,
|
1644
|
+
'percentage': False,
|
1645
|
+
},
|
1646
|
+
'deposit': {
|
1366
1647
|
'fee': None,
|
1367
1648
|
'percentage': None,
|
1368
1649
|
},
|
1650
|
+
'networks': {},
|
1651
|
+
}
|
1652
|
+
networkId = self.safe_string(fee, 'chain')
|
1653
|
+
networkCode = self.network_id_to_code(networkId, self.safe_string(currency, 'code'))
|
1654
|
+
result['networks'][networkCode] = {
|
1655
|
+
'withdraw': minWithdrawFee,
|
1369
1656
|
'deposit': {
|
1370
1657
|
'fee': None,
|
1371
1658
|
'percentage': None,
|
1372
1659
|
},
|
1373
|
-
'networks': {},
|
1374
1660
|
}
|
1375
|
-
isWithdrawEnabled = self.safe_bool(fee, 'isWithdrawEnabled')
|
1376
|
-
if isWithdrawEnabled:
|
1377
|
-
result['withdraw']['fee'] = self.safe_number_2(fee, 'withdrawalMinFee', 'withdrawMinFee')
|
1378
|
-
result['withdraw']['percentage'] = False
|
1379
|
-
networkId = self.safe_string(fee, 'chain')
|
1380
|
-
if networkId:
|
1381
|
-
networkCode = self.network_id_to_code(networkId, self.safe_string(currency, 'code'))
|
1382
|
-
result['networks'][networkCode] = {
|
1383
|
-
'withdraw': result['withdraw'],
|
1384
|
-
'deposit': {
|
1385
|
-
'fee': None,
|
1386
|
-
'percentage': None,
|
1387
|
-
},
|
1388
|
-
}
|
1389
1661
|
return result
|
1390
1662
|
|
1391
1663
|
def is_futures_method(self, methodName, params):
|
@@ -1405,7 +1677,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1405
1677
|
params = self.omit(params, 'type')
|
1406
1678
|
return(type == 'contract') or (type == 'future') or (type == 'futures') # * (type == 'futures') deprecated, use(type == 'future')
|
1407
1679
|
|
1408
|
-
def parse_ticker(self, ticker, market: Market = None) -> Ticker:
|
1680
|
+
def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
|
1409
1681
|
#
|
1410
1682
|
# {
|
1411
1683
|
# "symbol": "BTC-USDT", # symbol
|
@@ -1471,7 +1743,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1471
1743
|
symbol = market['symbol']
|
1472
1744
|
baseVolume = self.safe_string(ticker, 'vol')
|
1473
1745
|
quoteVolume = self.safe_string(ticker, 'volValue')
|
1474
|
-
timestamp = self.
|
1746
|
+
timestamp = self.safe_integer_n(ticker, ['time', 'datetime', 'timePoint'])
|
1475
1747
|
return self.safe_ticker({
|
1476
1748
|
'symbol': symbol,
|
1477
1749
|
'timestamp': timestamp,
|
@@ -1492,13 +1764,16 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1492
1764
|
'average': self.safe_string(ticker, 'averagePrice'),
|
1493
1765
|
'baseVolume': baseVolume,
|
1494
1766
|
'quoteVolume': quoteVolume,
|
1767
|
+
'markPrice': self.safe_string(ticker, 'value'),
|
1495
1768
|
'info': ticker,
|
1496
1769
|
}, market)
|
1497
1770
|
|
1498
1771
|
async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
1499
1772
|
"""
|
1500
1773
|
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
1501
|
-
|
1774
|
+
|
1775
|
+
https://docs.kucoin.com/#get-all-tickers
|
1776
|
+
|
1502
1777
|
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
1503
1778
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1504
1779
|
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -1537,7 +1812,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1537
1812
|
data = self.safe_dict(response, 'data', {})
|
1538
1813
|
tickers = self.safe_list(data, 'ticker', [])
|
1539
1814
|
time = self.safe_integer(data, 'time')
|
1540
|
-
result = {}
|
1815
|
+
result: dict = {}
|
1541
1816
|
for i in range(0, len(tickers)):
|
1542
1817
|
tickers[i]['time'] = time
|
1543
1818
|
ticker = self.parse_ticker(tickers[i])
|
@@ -1546,17 +1821,35 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1546
1821
|
result[symbol] = ticker
|
1547
1822
|
return self.filter_by_array_tickers(result, 'symbol', symbols)
|
1548
1823
|
|
1824
|
+
async def fetch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
|
1825
|
+
"""
|
1826
|
+
fetches the mark price for multiple markets
|
1827
|
+
|
1828
|
+
https://www.kucoin.com/docs/rest/margin-trading/margin-info/get-all-margin-trading-pairs-mark-prices
|
1829
|
+
|
1830
|
+
:param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
1831
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1832
|
+
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1833
|
+
"""
|
1834
|
+
await self.load_markets()
|
1835
|
+
symbols = self.market_symbols(symbols)
|
1836
|
+
response = await self.publicGetMarkPriceAllSymbols(params)
|
1837
|
+
data = self.safe_list(response, 'data', [])
|
1838
|
+
return self.parse_tickers(data)
|
1839
|
+
|
1549
1840
|
async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
|
1550
1841
|
"""
|
1551
1842
|
fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
1552
|
-
|
1843
|
+
|
1844
|
+
https://docs.kucoin.com/#get-24hr-stats
|
1845
|
+
|
1553
1846
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
1554
1847
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1555
1848
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1556
1849
|
"""
|
1557
1850
|
await self.load_markets()
|
1558
1851
|
market = self.market(symbol)
|
1559
|
-
request = {
|
1852
|
+
request: dict = {
|
1560
1853
|
'symbol': market['id'],
|
1561
1854
|
}
|
1562
1855
|
response = await self.publicGetMarketStats(self.extend(request, params))
|
@@ -1583,7 +1876,28 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1583
1876
|
# }
|
1584
1877
|
# }
|
1585
1878
|
#
|
1586
|
-
|
1879
|
+
data = self.safe_dict(response, 'data', {})
|
1880
|
+
return self.parse_ticker(data, market)
|
1881
|
+
|
1882
|
+
async def fetch_mark_price(self, symbol: str, params={}) -> Ticker:
|
1883
|
+
"""
|
1884
|
+
fetches the mark price for a specific market
|
1885
|
+
|
1886
|
+
https://www.kucoin.com/docs/rest/margin-trading/margin-info/get-mark-price
|
1887
|
+
|
1888
|
+
:param str symbol: unified symbol of the market to fetch the ticker for
|
1889
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1890
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1891
|
+
"""
|
1892
|
+
await self.load_markets()
|
1893
|
+
market = self.market(symbol)
|
1894
|
+
request: dict = {
|
1895
|
+
'symbol': market['id'],
|
1896
|
+
}
|
1897
|
+
response = await self.publicGetMarkPriceSymbolCurrent(self.extend(request, params))
|
1898
|
+
#
|
1899
|
+
data = self.safe_dict(response, 'data', {})
|
1900
|
+
return self.parse_ticker(data, market)
|
1587
1901
|
|
1588
1902
|
def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
|
1589
1903
|
#
|
@@ -1609,7 +1923,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1609
1923
|
async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
1610
1924
|
"""
|
1611
1925
|
fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
1612
|
-
|
1926
|
+
|
1927
|
+
https://docs.kucoin.com/#get-klines
|
1928
|
+
|
1613
1929
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
1614
1930
|
:param str timeframe: the length of time each candle represents
|
1615
1931
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
@@ -1625,7 +1941,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1625
1941
|
return await self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1500)
|
1626
1942
|
market = self.market(symbol)
|
1627
1943
|
marketId = market['id']
|
1628
|
-
request = {
|
1944
|
+
request: dict = {
|
1629
1945
|
'symbol': marketId,
|
1630
1946
|
'type': self.safe_string(self.timeframes, timeframe, timeframe),
|
1631
1947
|
}
|
@@ -1660,7 +1976,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1660
1976
|
|
1661
1977
|
async def create_deposit_address(self, code: str, params={}):
|
1662
1978
|
"""
|
1663
|
-
|
1979
|
+
|
1980
|
+
https://www.kucoin.com/docs/rest/funding/deposit/create-deposit-address-v3-
|
1981
|
+
|
1664
1982
|
create a currency deposit address
|
1665
1983
|
:param str code: unified currency code of the currency for the deposit address
|
1666
1984
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1669,24 +1987,38 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1669
1987
|
"""
|
1670
1988
|
await self.load_markets()
|
1671
1989
|
currency = self.currency(code)
|
1672
|
-
request = {
|
1990
|
+
request: dict = {
|
1673
1991
|
'currency': currency['id'],
|
1674
1992
|
}
|
1675
1993
|
networkCode = None
|
1676
1994
|
networkCode, params = self.handle_network_code_and_params(params)
|
1677
1995
|
if networkCode is not None:
|
1678
|
-
request['chain'] = self.network_code_to_id(networkCode)
|
1679
|
-
response = await self.
|
1996
|
+
request['chain'] = self.network_code_to_id(networkCode) # docs mention "chain-name", but seems "chain-id" is used, like in "fetchDepositAddress"
|
1997
|
+
response = await self.privatePostDepositAddressCreate(self.extend(request, params))
|
1680
1998
|
# {"code":"260000","msg":"Deposit address already exists."}
|
1681
|
-
#
|
1682
|
-
#
|
1999
|
+
#
|
2000
|
+
# {
|
2001
|
+
# "code": "200000",
|
2002
|
+
# "data": {
|
2003
|
+
# "address": "0x2336d1834faab10b2dac44e468f2627138417431",
|
2004
|
+
# "memo": null,
|
2005
|
+
# "chainId": "bsc",
|
2006
|
+
# "to": "MAIN",
|
2007
|
+
# "expirationDate": 0,
|
2008
|
+
# "currency": "BNB",
|
2009
|
+
# "chainName": "BEP20"
|
2010
|
+
# }
|
2011
|
+
# }
|
2012
|
+
#
|
1683
2013
|
data = self.safe_dict(response, 'data', {})
|
1684
2014
|
return self.parse_deposit_address(data, currency)
|
1685
2015
|
|
1686
|
-
async def fetch_deposit_address(self, code: str, params={}):
|
2016
|
+
async def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
|
1687
2017
|
"""
|
1688
2018
|
fetch the deposit address for a currency associated with self account
|
1689
|
-
|
2019
|
+
|
2020
|
+
https://docs.kucoin.com/#get-deposit-addresses-v2
|
2021
|
+
|
1690
2022
|
:param str code: unified currency code
|
1691
2023
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1692
2024
|
:param str [params.network]: the blockchain network name
|
@@ -1694,7 +2026,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1694
2026
|
"""
|
1695
2027
|
await self.load_markets()
|
1696
2028
|
currency = self.currency(code)
|
1697
|
-
request = {
|
2029
|
+
request: dict = {
|
1698
2030
|
'currency': currency['id'],
|
1699
2031
|
# for USDT - OMNI, ERC20, TRC20, default is ERC20
|
1700
2032
|
# for BTC - Native, Segwit, TRC20, the parameters are bech32, btc, trx, default is Native
|
@@ -1715,28 +2047,30 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1715
2047
|
raise ExchangeError(self.id + ' fetchDepositAddress() returned an empty response, you might try to run createDepositAddress() first and try again')
|
1716
2048
|
return self.parse_deposit_address(data, currency)
|
1717
2049
|
|
1718
|
-
def parse_deposit_address(self, depositAddress, currency: Currency = None):
|
2050
|
+
def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
|
1719
2051
|
address = self.safe_string(depositAddress, 'address')
|
1720
2052
|
# BCH/BSV is returned with a "bitcoincash:" prefix, which we cut off here and only keep the address
|
1721
2053
|
if address is not None:
|
1722
2054
|
address = address.replace('bitcoincash:', '')
|
1723
2055
|
code = None
|
1724
2056
|
if currency is not None:
|
1725
|
-
code = currency['id']
|
2057
|
+
code = self.safe_currency_code(currency['id'])
|
1726
2058
|
if code != 'NIM':
|
1727
2059
|
# contains spaces
|
1728
2060
|
self.check_address(address)
|
1729
2061
|
return {
|
1730
2062
|
'info': depositAddress,
|
1731
2063
|
'currency': code,
|
2064
|
+
'network': self.network_id_to_code(self.safe_string(depositAddress, 'chainId')),
|
1732
2065
|
'address': address,
|
1733
2066
|
'tag': self.safe_string(depositAddress, 'memo'),
|
1734
|
-
'network': self.network_id_to_code(self.safe_string(depositAddress, 'chain')),
|
1735
2067
|
}
|
1736
2068
|
|
1737
|
-
async def fetch_deposit_addresses_by_network(self, code: str, params={}):
|
2069
|
+
async def fetch_deposit_addresses_by_network(self, code: str, params={}) -> List[DepositAddress]:
|
1738
2070
|
"""
|
1739
|
-
|
2071
|
+
|
2072
|
+
https://docs.kucoin.com/#get-deposit-addresses-v2
|
2073
|
+
|
1740
2074
|
fetch the deposit address for a currency associated with self account
|
1741
2075
|
:param str code: unified currency code
|
1742
2076
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1744,7 +2078,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1744
2078
|
"""
|
1745
2079
|
await self.load_markets()
|
1746
2080
|
currency = self.currency(code)
|
1747
|
-
request = {
|
2081
|
+
request: dict = {
|
1748
2082
|
'currency': currency['id'],
|
1749
2083
|
}
|
1750
2084
|
version = self.options['versions']['private']['GET']['deposit-addresses']
|
@@ -1768,15 +2102,17 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1768
2102
|
self.options['versions']['private']['GET']['deposit-addresses'] = version
|
1769
2103
|
chains = self.safe_list(response, 'data', [])
|
1770
2104
|
parsed = self.parse_deposit_addresses(chains, [currency['code']], False, {
|
1771
|
-
'currency': currency['
|
2105
|
+
'currency': currency['code'],
|
1772
2106
|
})
|
1773
2107
|
return self.index_by(parsed, 'network')
|
1774
2108
|
|
1775
2109
|
async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
1776
2110
|
"""
|
1777
2111
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
1778
|
-
|
1779
|
-
|
2112
|
+
|
2113
|
+
https://www.kucoin.com/docs/rest/spot-trading/market-data/get-part-order-book-aggregated-
|
2114
|
+
https://www.kucoin.com/docs/rest/spot-trading/market-data/get-full-order-book-aggregated-
|
2115
|
+
|
1780
2116
|
:param str symbol: unified symbol of the market to fetch the order book for
|
1781
2117
|
:param int [limit]: the maximum amount of order book entries to return
|
1782
2118
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1785,7 +2121,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1785
2121
|
await self.load_markets()
|
1786
2122
|
market = self.market(symbol)
|
1787
2123
|
level = self.safe_integer(params, 'level', 2)
|
1788
|
-
request = {'symbol': market['id']}
|
2124
|
+
request: dict = {'symbol': market['id']}
|
1789
2125
|
isAuthenticated = self.check_required_credentials(False)
|
1790
2126
|
response = None
|
1791
2127
|
if not isAuthenticated or limit is not None:
|
@@ -1850,49 +2186,56 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1850
2186
|
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
1851
2187
|
"""
|
1852
2188
|
Create an order on the exchange
|
1853
|
-
|
1854
|
-
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
2189
|
+
|
2190
|
+
https://docs.kucoin.com/spot#place-a-new-order
|
2191
|
+
https://docs.kucoin.com/spot#place-a-new-order-2
|
2192
|
+
https://docs.kucoin.com/spot#place-a-margin-order
|
2193
|
+
https://docs.kucoin.com/spot-hf/#place-hf-order
|
2194
|
+
https://www.kucoin.com/docs/rest/spot-trading/orders/place-order-test
|
2195
|
+
https://www.kucoin.com/docs/rest/margin-trading/orders/place-margin-order-test
|
2196
|
+
https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/sync-place-hf-order
|
2197
|
+
|
1859
2198
|
:param str symbol: Unified CCXT market symbol
|
1860
2199
|
:param str type: 'limit' or 'market'
|
1861
2200
|
:param str side: 'buy' or 'sell'
|
1862
2201
|
:param float amount: the amount of currency to trade
|
1863
|
-
:param float [price]:
|
2202
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
1864
2203
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1865
2204
|
:param float [params.triggerPrice]: The price at which a trigger order is triggered at
|
1866
2205
|
:param str [params.marginMode]: 'cross', # cross(cross mode) and isolated(isolated mode), set to cross by default, the isolated mode will be released soon, stay tuned
|
1867
2206
|
:param str [params.timeInForce]: GTC, GTT, IOC, or FOK, default is GTC, limit orders only
|
1868
2207
|
:param str [params.postOnly]: Post only flag, invalid when timeInForce is IOC or FOK
|
1869
|
-
|
1870
|
-
|
2208
|
+
|
2209
|
+
EXCHANGE SPECIFIC PARAMETERS
|
1871
2210
|
:param str [params.clientOid]: client order id, defaults to uuid if not passed
|
1872
2211
|
:param str [params.remark]: remark for the order, length cannot exceed 100 utf8 characters
|
1873
2212
|
:param str [params.tradeType]: 'TRADE', # TRADE, MARGIN_TRADE # not used with margin orders
|
1874
|
-
|
2213
|
+
limit orders ---------------------------------------------------
|
1875
2214
|
:param float [params.cancelAfter]: long, # cancel after n seconds, requires timeInForce to be GTT
|
1876
2215
|
:param bool [params.hidden]: False, # Order will not be displayed in the order book
|
1877
2216
|
:param bool [params.iceberg]: False, # Only a portion of the order is displayed in the order book
|
1878
2217
|
:param str [params.visibleSize]: self.amount_to_precision(symbol, visibleSize), # The maximum visible size of an iceberg order
|
1879
|
-
|
2218
|
+
market orders --------------------------------------------------
|
1880
2219
|
:param str [params.funds]: # Amount of quote currency to use
|
1881
|
-
|
1882
|
-
:param str [params.stop]: Either loss or entry, the default is loss. Requires
|
1883
|
-
|
2220
|
+
stop orders ----------------------------------------------------
|
2221
|
+
:param str [params.stop]: Either loss or entry, the default is loss. Requires triggerPrice to be defined
|
2222
|
+
margin orders --------------------------------------------------
|
1884
2223
|
:param float [params.leverage]: Leverage size of the order
|
1885
2224
|
:param str [params.stp]: '', # self trade prevention, CN, CO, CB or DC
|
1886
2225
|
:param bool [params.autoBorrow]: False, # The system will first borrow you funds at the optimal interest rate and then place an order for you
|
1887
2226
|
:param bool [params.hf]: False, # True for hf order
|
1888
2227
|
:param bool [params.test]: set to True to test an order, no order will be created but the request will be validated
|
2228
|
+
:param bool [params.sync]: set to True to use the hf sync call
|
1889
2229
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1890
2230
|
"""
|
1891
2231
|
await self.load_markets()
|
1892
2232
|
market = self.market(symbol)
|
1893
2233
|
testOrder = self.safe_bool(params, 'test', False)
|
1894
2234
|
params = self.omit(params, 'test')
|
1895
|
-
|
2235
|
+
hf = None
|
2236
|
+
hf, params = self.handle_hf_and_params(params)
|
2237
|
+
useSync = False
|
2238
|
+
useSync, params = self.handle_option_and_params(params, 'createOrder', 'sync', False)
|
1896
2239
|
triggerPrice, stopLossPrice, takeProfitPrice = self.handle_trigger_prices(params)
|
1897
2240
|
tradeType = self.safe_string(params, 'tradeType') # keep it for backward compatibility
|
1898
2241
|
isTriggerOrder = (triggerPrice or stopLossPrice or takeProfitPrice)
|
@@ -1905,14 +2248,18 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1905
2248
|
if testOrder:
|
1906
2249
|
if isMarginOrder:
|
1907
2250
|
response = await self.privatePostMarginOrderTest(orderRequest)
|
2251
|
+
elif hf:
|
2252
|
+
response = await self.privatePostHfOrdersTest(orderRequest)
|
1908
2253
|
else:
|
1909
2254
|
response = await self.privatePostOrdersTest(orderRequest)
|
1910
|
-
elif isHf:
|
1911
|
-
response = await self.privatePostHfOrders(orderRequest)
|
1912
2255
|
elif isTriggerOrder:
|
1913
2256
|
response = await self.privatePostStopOrder(orderRequest)
|
1914
2257
|
elif isMarginOrder:
|
1915
2258
|
response = await self.privatePostMarginOrder(orderRequest)
|
2259
|
+
elif useSync:
|
2260
|
+
response = await self.privatePostHfOrdersSync(orderRequest)
|
2261
|
+
elif hf:
|
2262
|
+
response = await self.privatePostHfOrders(orderRequest)
|
1916
2263
|
else:
|
1917
2264
|
response = await self.privatePostOrders(orderRequest)
|
1918
2265
|
#
|
@@ -1929,7 +2276,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1929
2276
|
async def create_market_order_with_cost(self, symbol: str, side: OrderSide, cost: float, params={}):
|
1930
2277
|
"""
|
1931
2278
|
create a market order by providing the symbol, side and cost
|
1932
|
-
|
2279
|
+
|
2280
|
+
https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
|
2281
|
+
|
1933
2282
|
:param str symbol: unified symbol of the market to create an order in
|
1934
2283
|
:param str side: 'buy' or 'sell'
|
1935
2284
|
:param float cost: how much you want to trade in units of the quote currency
|
@@ -1937,13 +2286,17 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1937
2286
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1938
2287
|
"""
|
1939
2288
|
await self.load_markets()
|
1940
|
-
|
1941
|
-
|
2289
|
+
req = {
|
2290
|
+
'cost': cost,
|
2291
|
+
}
|
2292
|
+
return await self.create_order(symbol, 'market', side, 0, None, self.extend(req, params))
|
1942
2293
|
|
1943
2294
|
async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
|
1944
2295
|
"""
|
1945
2296
|
create a market buy order by providing the symbol and cost
|
1946
|
-
|
2297
|
+
|
2298
|
+
https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
|
2299
|
+
|
1947
2300
|
:param str symbol: unified symbol of the market to create an order in
|
1948
2301
|
:param float cost: how much you want to trade in units of the quote currency
|
1949
2302
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1955,7 +2308,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1955
2308
|
async def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}):
|
1956
2309
|
"""
|
1957
2310
|
create a market sell order by providing the symbol and cost
|
1958
|
-
|
2311
|
+
|
2312
|
+
https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
|
2313
|
+
|
1959
2314
|
:param str symbol: unified symbol of the market to create an order in
|
1960
2315
|
:param float cost: how much you want to trade in units of the quote currency
|
1961
2316
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1967,11 +2322,15 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1967
2322
|
async def create_orders(self, orders: List[OrderRequest], params={}):
|
1968
2323
|
"""
|
1969
2324
|
create a list of trade orders
|
1970
|
-
|
1971
|
-
|
2325
|
+
|
2326
|
+
https://www.kucoin.com/docs/rest/spot-trading/orders/place-multiple-orders
|
2327
|
+
https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/place-multiple-hf-orders
|
2328
|
+
https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/sync-place-multiple-hf-orders
|
2329
|
+
|
1972
2330
|
:param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
|
1973
2331
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1974
2332
|
:param bool [params.hf]: False, # True for hf orders
|
2333
|
+
:param bool [params.sync]: False, # True to use the hf sync call
|
1975
2334
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1976
2335
|
"""
|
1977
2336
|
await self.load_markets()
|
@@ -1995,14 +2354,18 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1995
2354
|
orderRequest = self.create_order_request(marketId, type, side, amount, price, orderParams)
|
1996
2355
|
ordersRequests.append(orderRequest)
|
1997
2356
|
market = self.market(symbol)
|
1998
|
-
request = {
|
2357
|
+
request: dict = {
|
1999
2358
|
'symbol': market['id'],
|
2000
2359
|
'orderList': ordersRequests,
|
2001
2360
|
}
|
2002
|
-
hf =
|
2003
|
-
params = self.
|
2361
|
+
hf = None
|
2362
|
+
hf, params = self.handle_hf_and_params(params)
|
2363
|
+
useSync = False
|
2364
|
+
useSync, params = self.handle_option_and_params(params, 'createOrders', 'sync', False)
|
2004
2365
|
response = None
|
2005
|
-
if
|
2366
|
+
if useSync:
|
2367
|
+
response = await self.privatePostHfOrdersMultiSync(self.extend(request, params))
|
2368
|
+
elif hf:
|
2006
2369
|
response = await self.privatePostHfOrdersMulti(self.extend(request, params))
|
2007
2370
|
else:
|
2008
2371
|
response = await self.privatePostOrdersMulti(self.extend(request, params))
|
@@ -2040,12 +2403,19 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2040
2403
|
data = self.safe_list(data, 'data', [])
|
2041
2404
|
return self.parse_orders(data)
|
2042
2405
|
|
2406
|
+
def market_order_amount_to_precision(self, symbol: str, amount):
|
2407
|
+
market = self.market(symbol)
|
2408
|
+
result = self.decimal_to_precision(amount, TRUNCATE, market['info']['quoteIncrement'], self.precisionMode, self.paddingMode)
|
2409
|
+
if result == '0':
|
2410
|
+
raise InvalidOrder(self.id + ' amount of ' + market['symbol'] + ' must be greater than minimum amount precision of ' + self.number_to_string(market['precision']['amount']))
|
2411
|
+
return result
|
2412
|
+
|
2043
2413
|
def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
2044
2414
|
market = self.market(symbol)
|
2045
2415
|
# required param, cannot be used twice
|
2046
2416
|
clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId', self.uuid())
|
2047
2417
|
params = self.omit(params, ['clientOid', 'clientOrderId'])
|
2048
|
-
request = {
|
2418
|
+
request: dict = {
|
2049
2419
|
'clientOid': clientOrderId,
|
2050
2420
|
'side': side,
|
2051
2421
|
'symbol': market['id'],
|
@@ -2060,7 +2430,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2060
2430
|
if quoteAmount is not None:
|
2061
2431
|
params = self.omit(params, ['cost', 'funds'])
|
2062
2432
|
# kucoin uses base precision even for quote values
|
2063
|
-
costString = self.
|
2433
|
+
costString = self.market_order_amount_to_precision(symbol, quoteAmount)
|
2064
2434
|
request['funds'] = costString
|
2065
2435
|
else:
|
2066
2436
|
amountString = self.amount_to_precision(symbol, amount)
|
@@ -2100,20 +2470,22 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2100
2470
|
async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
2101
2471
|
"""
|
2102
2472
|
edit an order, kucoin currently only supports the modification of HF orders
|
2103
|
-
|
2473
|
+
|
2474
|
+
https://docs.kucoin.com/spot-hf/#modify-order
|
2475
|
+
|
2104
2476
|
:param str id: order id
|
2105
2477
|
:param str symbol: unified symbol of the market to create an order in
|
2106
2478
|
:param str type: not used
|
2107
2479
|
:param str side: not used
|
2108
2480
|
:param float amount: how much of the currency you want to trade in units of the base currency
|
2109
|
-
:param float [price]: the price at which the order is to be
|
2481
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
2110
2482
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2111
2483
|
:param str [params.clientOrderId]: client order id, defaults to id if not passed
|
2112
2484
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2113
2485
|
"""
|
2114
2486
|
await self.load_markets()
|
2115
2487
|
market = self.market(symbol)
|
2116
|
-
request = {
|
2488
|
+
request: dict = {
|
2117
2489
|
'symbol': market['id'],
|
2118
2490
|
}
|
2119
2491
|
clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId')
|
@@ -2140,78 +2512,149 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2140
2512
|
async def cancel_order(self, id: str, symbol: Str = None, params={}):
|
2141
2513
|
"""
|
2142
2514
|
cancels an open order
|
2143
|
-
|
2144
|
-
|
2145
|
-
|
2146
|
-
|
2147
|
-
|
2148
|
-
|
2515
|
+
|
2516
|
+
https://docs.kucoin.com/spot#cancel-an-order
|
2517
|
+
https://docs.kucoin.com/spot#cancel-an-order-2
|
2518
|
+
https://docs.kucoin.com/spot#cancel-single-order-by-clientoid
|
2519
|
+
https://docs.kucoin.com/spot#cancel-single-order-by-clientoid-2
|
2520
|
+
https://docs.kucoin.com/spot-hf/#cancel-orders-by-orderid
|
2521
|
+
https://docs.kucoin.com/spot-hf/#cancel-order-by-clientoid
|
2522
|
+
https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/sync-cancel-hf-order-by-orderid
|
2523
|
+
https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/sync-cancel-hf-order-by-clientoid
|
2524
|
+
|
2149
2525
|
:param str id: order id
|
2150
2526
|
:param str symbol: unified symbol of the market the order was made in
|
2151
2527
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2152
|
-
:param bool [params.
|
2528
|
+
:param bool [params.trigger]: True if cancelling a stop order
|
2153
2529
|
:param bool [params.hf]: False, # True for hf order
|
2530
|
+
:param bool [params.sync]: False, # True to use the hf sync call
|
2154
2531
|
:returns: Response from the exchange
|
2155
2532
|
"""
|
2156
2533
|
await self.load_markets()
|
2157
|
-
request = {}
|
2534
|
+
request: dict = {}
|
2158
2535
|
clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId')
|
2159
|
-
|
2160
|
-
hf =
|
2161
|
-
|
2536
|
+
trigger = self.safe_bool_2(params, 'stop', 'trigger', False)
|
2537
|
+
hf = None
|
2538
|
+
hf, params = self.handle_hf_and_params(params)
|
2539
|
+
useSync = False
|
2540
|
+
useSync, params = self.handle_option_and_params(params, 'cancelOrder', 'sync', False)
|
2541
|
+
if hf or useSync:
|
2162
2542
|
if symbol is None:
|
2163
2543
|
raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol parameter for hf orders')
|
2164
2544
|
market = self.market(symbol)
|
2165
2545
|
request['symbol'] = market['id']
|
2166
2546
|
response = None
|
2167
|
-
params = self.omit(params, ['clientOid', 'clientOrderId', 'stop', '
|
2547
|
+
params = self.omit(params, ['clientOid', 'clientOrderId', 'stop', 'trigger'])
|
2168
2548
|
if clientOrderId is not None:
|
2169
2549
|
request['clientOid'] = clientOrderId
|
2170
|
-
if
|
2550
|
+
if trigger:
|
2171
2551
|
response = await self.privateDeleteStopOrderCancelOrderByClientOid(self.extend(request, params))
|
2552
|
+
#
|
2553
|
+
# {
|
2554
|
+
# code: '200000',
|
2555
|
+
# data: {
|
2556
|
+
# cancelledOrderId: 'vs8lgpiuao41iaft003khbbk',
|
2557
|
+
# clientOid: '123456'
|
2558
|
+
# }
|
2559
|
+
# }
|
2560
|
+
#
|
2561
|
+
elif useSync:
|
2562
|
+
response = await self.privateDeleteHfOrdersSyncClientOrderClientOid(self.extend(request, params))
|
2172
2563
|
elif hf:
|
2173
2564
|
response = await self.privateDeleteHfOrdersClientOrderClientOid(self.extend(request, params))
|
2565
|
+
#
|
2566
|
+
# {
|
2567
|
+
# "code": "200000",
|
2568
|
+
# "data": {
|
2569
|
+
# "clientOid": "6d539dc614db3"
|
2570
|
+
# }
|
2571
|
+
# }
|
2572
|
+
#
|
2174
2573
|
else:
|
2175
2574
|
response = await self.privateDeleteOrderClientOrderClientOid(self.extend(request, params))
|
2575
|
+
#
|
2576
|
+
# {
|
2577
|
+
# code: '200000',
|
2578
|
+
# data: {
|
2579
|
+
# cancelledOrderId: '665e580f6660500007aba341',
|
2580
|
+
# clientOid: '1234567',
|
2581
|
+
# cancelledOcoOrderIds: null
|
2582
|
+
# }
|
2583
|
+
# }
|
2584
|
+
#
|
2585
|
+
response = self.safe_dict(response, 'data')
|
2586
|
+
return self.parse_order(response)
|
2176
2587
|
else:
|
2177
2588
|
request['orderId'] = id
|
2178
|
-
if
|
2589
|
+
if trigger:
|
2179
2590
|
response = await self.privateDeleteStopOrderOrderId(self.extend(request, params))
|
2591
|
+
#
|
2592
|
+
# {
|
2593
|
+
# code: '200000',
|
2594
|
+
# data: {cancelledOrderIds: ['vs8lgpiuaco91qk8003vebu9']}
|
2595
|
+
# }
|
2596
|
+
#
|
2597
|
+
elif useSync:
|
2598
|
+
response = await self.privateDeleteHfOrdersSyncOrderId(self.extend(request, params))
|
2180
2599
|
elif hf:
|
2181
2600
|
response = await self.privateDeleteHfOrdersOrderId(self.extend(request, params))
|
2601
|
+
#
|
2602
|
+
# {
|
2603
|
+
# "code": "200000",
|
2604
|
+
# "data": {
|
2605
|
+
# "orderId": "630625dbd9180300014c8d52"
|
2606
|
+
# }
|
2607
|
+
# }
|
2608
|
+
#
|
2609
|
+
response = self.safe_dict(response, 'data')
|
2610
|
+
return self.parse_order(response)
|
2182
2611
|
else:
|
2183
2612
|
response = await self.privateDeleteOrdersOrderId(self.extend(request, params))
|
2184
|
-
|
2613
|
+
#
|
2614
|
+
# {
|
2615
|
+
# code: '200000',
|
2616
|
+
# data: {cancelledOrderIds: ['665e4fbe28051a0007245c41']}
|
2617
|
+
# }
|
2618
|
+
#
|
2619
|
+
data = self.safe_dict(response, 'data')
|
2620
|
+
orderIds = self.safe_list(data, 'cancelledOrderIds', [])
|
2621
|
+
orderId = self.safe_string(orderIds, 0)
|
2622
|
+
return self.safe_order({
|
2623
|
+
'info': data,
|
2624
|
+
'id': orderId,
|
2625
|
+
})
|
2185
2626
|
|
2186
2627
|
async def cancel_all_orders(self, symbol: Str = None, params={}):
|
2187
2628
|
"""
|
2188
2629
|
cancel all open orders
|
2189
|
-
|
2190
|
-
|
2191
|
-
|
2630
|
+
|
2631
|
+
https://docs.kucoin.com/spot#cancel-all-orders
|
2632
|
+
https://docs.kucoin.com/spot#cancel-orders
|
2633
|
+
https://docs.kucoin.com/spot-hf/#cancel-all-hf-orders-by-symbol
|
2634
|
+
|
2192
2635
|
:param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
|
2193
2636
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2194
|
-
:param bool [params.
|
2637
|
+
:param bool [params.trigger]: *invalid for isolated margin* True if cancelling all stop orders
|
2195
2638
|
:param str [params.marginMode]: 'cross' or 'isolated'
|
2196
2639
|
:param str [params.orderIds]: *stop orders only* Comma seperated order IDs
|
2197
|
-
:param bool [params.stop]: True if cancelling a stop order
|
2198
2640
|
:param bool [params.hf]: False, # True for hf order
|
2199
2641
|
:returns: Response from the exchange
|
2200
2642
|
"""
|
2201
2643
|
await self.load_markets()
|
2202
|
-
request = {}
|
2203
|
-
|
2204
|
-
hf =
|
2205
|
-
params = self.
|
2644
|
+
request: dict = {}
|
2645
|
+
trigger = self.safe_bool(params, 'stop', False)
|
2646
|
+
hf = None
|
2647
|
+
hf, params = self.handle_hf_and_params(params)
|
2648
|
+
params = self.omit(params, 'stop')
|
2206
2649
|
marginMode, query = self.handle_margin_mode_and_params('cancelAllOrders', params)
|
2207
2650
|
if symbol is not None:
|
2208
2651
|
request['symbol'] = self.market_id(symbol)
|
2209
2652
|
if marginMode is not None:
|
2210
2653
|
request['tradeType'] = self.options['marginModes'][marginMode]
|
2211
|
-
if marginMode == 'isolated' and
|
2654
|
+
if marginMode == 'isolated' and trigger:
|
2212
2655
|
raise BadRequest(self.id + ' cancelAllOrders does not support isolated margin for stop orders')
|
2213
2656
|
response = None
|
2214
|
-
if
|
2657
|
+
if trigger:
|
2215
2658
|
response = await self.privateDeleteStopOrderCancel(self.extend(request, query))
|
2216
2659
|
elif hf:
|
2217
2660
|
if symbol is None:
|
@@ -2225,38 +2668,42 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2225
2668
|
async def fetch_orders_by_status(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
2226
2669
|
"""
|
2227
2670
|
fetch a list of orders
|
2228
|
-
|
2229
|
-
|
2230
|
-
|
2231
|
-
|
2671
|
+
|
2672
|
+
https://docs.kucoin.com/spot#list-orders
|
2673
|
+
https://docs.kucoin.com/spot#list-stop-orders
|
2674
|
+
https://docs.kucoin.com/spot-hf/#obtain-list-of-active-hf-orders
|
2675
|
+
https://docs.kucoin.com/spot-hf/#obtain-list-of-filled-hf-orders
|
2676
|
+
|
2232
2677
|
:param str status: *not used for stop orders* 'open' or 'closed'
|
2233
2678
|
:param str symbol: unified market symbol
|
2234
2679
|
:param int [since]: timestamp in ms of the earliest order
|
2235
2680
|
:param int [limit]: max number of orders to return
|
2236
2681
|
:param dict [params]: exchange specific params
|
2237
2682
|
:param int [params.until]: end time in ms
|
2238
|
-
:param bool [params.stop]: True if fetching stop orders
|
2239
2683
|
:param str [params.side]: buy or sell
|
2240
2684
|
:param str [params.type]: limit, market, limit_stop or market_stop
|
2241
2685
|
:param str [params.tradeType]: TRADE for spot trading, MARGIN_TRADE for Margin Trading
|
2242
|
-
:param int [params.currentPage]: *
|
2243
|
-
:param str [params.orderIds]: *
|
2244
|
-
:param bool [params.
|
2686
|
+
:param int [params.currentPage]: *trigger orders only* current page
|
2687
|
+
:param str [params.orderIds]: *trigger orders only* comma seperated order ID list
|
2688
|
+
:param bool [params.trigger]: True if fetching a trigger order
|
2245
2689
|
:param bool [params.hf]: False, # True for hf order
|
2246
2690
|
:returns: An `array of order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
2247
2691
|
"""
|
2248
2692
|
await self.load_markets()
|
2249
2693
|
lowercaseStatus = status.lower()
|
2250
|
-
until = self.
|
2251
|
-
|
2252
|
-
hf =
|
2253
|
-
params = self.
|
2694
|
+
until = self.safe_integer(params, 'until')
|
2695
|
+
trigger = self.safe_bool_2(params, 'stop', 'trigger', False)
|
2696
|
+
hf = None
|
2697
|
+
hf, params = self.handle_hf_and_params(params)
|
2698
|
+
if hf and (symbol is None):
|
2699
|
+
raise ArgumentsRequired(self.id + ' fetchOrdersByStatus() requires a symbol parameter for hf orders')
|
2700
|
+
params = self.omit(params, ['stop', 'trigger', 'till', 'until'])
|
2254
2701
|
marginMode, query = self.handle_margin_mode_and_params('fetchOrdersByStatus', params)
|
2255
2702
|
if lowercaseStatus == 'open':
|
2256
2703
|
lowercaseStatus = 'active'
|
2257
2704
|
elif lowercaseStatus == 'closed':
|
2258
2705
|
lowercaseStatus = 'done'
|
2259
|
-
request = {
|
2706
|
+
request: dict = {
|
2260
2707
|
'status': lowercaseStatus,
|
2261
2708
|
}
|
2262
2709
|
market = None
|
@@ -2271,7 +2718,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2271
2718
|
request['endAt'] = until
|
2272
2719
|
request['tradeType'] = self.safe_string(self.options['marginModes'], marginMode, 'TRADE')
|
2273
2720
|
response = None
|
2274
|
-
if
|
2721
|
+
if trigger:
|
2275
2722
|
response = await self.privateGetStopOrder(self.extend(request, query))
|
2276
2723
|
elif hf:
|
2277
2724
|
if lowercaseStatus == 'active':
|
@@ -2323,26 +2770,31 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2323
2770
|
# ]
|
2324
2771
|
# }
|
2325
2772
|
# }
|
2773
|
+
listData = self.safe_list(response, 'data')
|
2774
|
+
if listData is not None:
|
2775
|
+
return self.parse_orders(listData, market, since, limit)
|
2326
2776
|
responseData = self.safe_dict(response, 'data', {})
|
2327
|
-
orders = self.
|
2777
|
+
orders = self.safe_list(responseData, 'items', [])
|
2328
2778
|
return self.parse_orders(orders, market, since, limit)
|
2329
2779
|
|
2330
2780
|
async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
2331
2781
|
"""
|
2332
2782
|
fetches information on multiple closed orders made by the user
|
2333
|
-
|
2334
|
-
|
2335
|
-
|
2336
|
-
|
2783
|
+
|
2784
|
+
https://docs.kucoin.com/spot#list-orders
|
2785
|
+
https://docs.kucoin.com/spot#list-stop-orders
|
2786
|
+
https://docs.kucoin.com/spot-hf/#obtain-list-of-active-hf-orders
|
2787
|
+
https://docs.kucoin.com/spot-hf/#obtain-list-of-filled-hf-orders
|
2788
|
+
|
2337
2789
|
:param str symbol: unified market symbol of the market orders were made in
|
2338
2790
|
:param int [since]: the earliest time in ms to fetch orders for
|
2339
2791
|
:param int [limit]: the maximum number of order structures to retrieve
|
2340
2792
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2341
|
-
:param int [params.
|
2793
|
+
:param int [params.until]: end time in ms
|
2342
2794
|
:param str [params.side]: buy or sell
|
2343
2795
|
:param str [params.type]: limit, market, limit_stop or market_stop
|
2344
2796
|
:param str [params.tradeType]: TRADE for spot trading, MARGIN_TRADE for Margin Trading
|
2345
|
-
:param bool [params.
|
2797
|
+
:param bool [params.trigger]: True if fetching a trigger order
|
2346
2798
|
:param bool [params.hf]: False, # True for hf order
|
2347
2799
|
:param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
2348
2800
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
@@ -2357,22 +2809,23 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2357
2809
|
async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
2358
2810
|
"""
|
2359
2811
|
fetch all unfilled currently open orders
|
2360
|
-
|
2361
|
-
|
2362
|
-
|
2363
|
-
|
2812
|
+
|
2813
|
+
https://docs.kucoin.com/spot#list-orders
|
2814
|
+
https://docs.kucoin.com/spot#list-stop-orders
|
2815
|
+
https://docs.kucoin.com/spot-hf/#obtain-list-of-active-hf-orders
|
2816
|
+
https://docs.kucoin.com/spot-hf/#obtain-list-of-filled-hf-orders
|
2817
|
+
|
2364
2818
|
:param str symbol: unified market symbol
|
2365
2819
|
:param int [since]: the earliest time in ms to fetch open orders for
|
2366
2820
|
:param int [limit]: the maximum number of open orders structures to retrieve
|
2367
2821
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2368
|
-
:param int [params.
|
2369
|
-
:param bool [params.
|
2822
|
+
:param int [params.until]: end time in ms
|
2823
|
+
:param bool [params.trigger]: True if fetching trigger orders
|
2370
2824
|
:param str [params.side]: buy or sell
|
2371
2825
|
:param str [params.type]: limit, market, limit_stop or market_stop
|
2372
2826
|
:param str [params.tradeType]: TRADE for spot trading, MARGIN_TRADE for Margin Trading
|
2373
|
-
:param int [params.currentPage]: *
|
2374
|
-
:param str [params.orderIds]: *
|
2375
|
-
:param bool [params.stop]: True if fetching a stop order
|
2827
|
+
:param int [params.currentPage]: *trigger orders only* current page
|
2828
|
+
:param str [params.orderIds]: *trigger orders only* comma seperated order ID list
|
2376
2829
|
:param bool [params.hf]: False, # True for hf order
|
2377
2830
|
:param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
2378
2831
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
@@ -2387,25 +2840,28 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2387
2840
|
async def fetch_order(self, id: str, symbol: Str = None, params={}):
|
2388
2841
|
"""
|
2389
2842
|
fetch an order
|
2390
|
-
|
2391
|
-
|
2392
|
-
|
2393
|
-
|
2394
|
-
|
2395
|
-
|
2843
|
+
|
2844
|
+
https://docs.kucoin.com/spot#get-an-order
|
2845
|
+
https://docs.kucoin.com/spot#get-single-active-order-by-clientoid
|
2846
|
+
https://docs.kucoin.com/spot#get-single-order-info
|
2847
|
+
https://docs.kucoin.com/spot#get-single-order-by-clientoid
|
2848
|
+
https://docs.kucoin.com/spot-hf/#details-of-a-single-hf-order
|
2849
|
+
https://docs.kucoin.com/spot-hf/#obtain-details-of-a-single-hf-order-using-clientoid
|
2850
|
+
|
2396
2851
|
:param str id: Order id
|
2397
|
-
:param str symbol: not sent to exchange except for
|
2852
|
+
:param str symbol: not sent to exchange except for trigger orders with clientOid, but used internally by CCXT to filter
|
2398
2853
|
:param dict [params]: exchange specific parameters
|
2399
|
-
:param bool [params.
|
2854
|
+
:param bool [params.trigger]: True if fetching a trigger order
|
2400
2855
|
:param bool [params.hf]: False, # True for hf order
|
2401
2856
|
:param bool [params.clientOid]: unique order id created by users to identify their orders
|
2402
2857
|
:returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2403
2858
|
"""
|
2404
2859
|
await self.load_markets()
|
2405
|
-
request = {}
|
2860
|
+
request: dict = {}
|
2406
2861
|
clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId')
|
2407
|
-
|
2408
|
-
hf =
|
2862
|
+
trigger = self.safe_bool_2(params, 'stop', 'trigger', False)
|
2863
|
+
hf = None
|
2864
|
+
hf, params = self.handle_hf_and_params(params)
|
2409
2865
|
market = None
|
2410
2866
|
if symbol is not None:
|
2411
2867
|
market = self.market(symbol)
|
@@ -2413,11 +2869,11 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2413
2869
|
if symbol is None:
|
2414
2870
|
raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol parameter for hf orders')
|
2415
2871
|
request['symbol'] = market['id']
|
2416
|
-
params = self.omit(params, ['stop', '
|
2872
|
+
params = self.omit(params, ['stop', 'clientOid', 'clientOrderId', 'trigger'])
|
2417
2873
|
response = None
|
2418
2874
|
if clientOrderId is not None:
|
2419
2875
|
request['clientOid'] = clientOrderId
|
2420
|
-
if
|
2876
|
+
if trigger:
|
2421
2877
|
if symbol is not None:
|
2422
2878
|
request['symbol'] = market['id']
|
2423
2879
|
response = await self.privateGetStopOrderQueryOrderByClientOid(self.extend(request, params))
|
@@ -2432,7 +2888,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2432
2888
|
if id is None:
|
2433
2889
|
raise InvalidOrder(self.id + ' fetchOrder() requires an order id')
|
2434
2890
|
request['orderId'] = id
|
2435
|
-
if
|
2891
|
+
if trigger:
|
2436
2892
|
response = await self.privateGetStopOrderOrderId(self.extend(request, params))
|
2437
2893
|
elif hf:
|
2438
2894
|
response = await self.privateGetHfOrdersOrderId(self.extend(request, params))
|
@@ -2443,7 +2899,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2443
2899
|
responseData = self.safe_value(responseData, 0)
|
2444
2900
|
return self.parse_order(responseData, market)
|
2445
2901
|
|
2446
|
-
def parse_order(self, order, market: Market = None) -> Order:
|
2902
|
+
def parse_order(self, order: dict, market: Market = None) -> Order:
|
2447
2903
|
#
|
2448
2904
|
# createOrder
|
2449
2905
|
#
|
@@ -2570,7 +3026,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2570
3026
|
feeCurrencyId = self.safe_string(order, 'feeCurrency')
|
2571
3027
|
cancelExist = self.safe_bool(order, 'cancelExist', False)
|
2572
3028
|
responseStop = self.safe_string(order, 'stop')
|
2573
|
-
|
3029
|
+
trigger = responseStop is not None
|
2574
3030
|
stopTriggered = self.safe_bool(order, 'stopTriggered', False)
|
2575
3031
|
isActive = self.safe_bool_2(order, 'isActive', 'active')
|
2576
3032
|
responseStatus = self.safe_string(order, 'status')
|
@@ -2580,7 +3036,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2580
3036
|
status = 'open'
|
2581
3037
|
else:
|
2582
3038
|
status = 'closed'
|
2583
|
-
if
|
3039
|
+
if trigger:
|
2584
3040
|
if responseStatus == 'NEW':
|
2585
3041
|
status = 'open'
|
2586
3042
|
elif not isActive and not stopTriggered:
|
@@ -2589,10 +3045,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2589
3045
|
status = 'canceled'
|
2590
3046
|
if responseStatus == 'fail':
|
2591
3047
|
status = 'rejected'
|
2592
|
-
stopPrice = self.safe_number(order, 'stopPrice')
|
2593
3048
|
return self.safe_order({
|
2594
3049
|
'info': order,
|
2595
|
-
'id': self.safe_string_n(order, ['id', 'orderId', 'newOrderId']),
|
3050
|
+
'id': self.safe_string_n(order, ['id', 'orderId', 'newOrderId', 'cancelledOrderId']),
|
2596
3051
|
'clientOrderId': self.safe_string(order, 'clientOid'),
|
2597
3052
|
'symbol': self.safe_symbol(marketId, market, '-'),
|
2598
3053
|
'type': self.safe_string(order, 'type'),
|
@@ -2601,8 +3056,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2601
3056
|
'side': self.safe_string(order, 'side'),
|
2602
3057
|
'amount': self.safe_string(order, 'size'),
|
2603
3058
|
'price': self.safe_string(order, 'price'), # price is zero for market order, omitZero is called in safeOrder2
|
2604
|
-
'
|
2605
|
-
'triggerPrice': stopPrice,
|
3059
|
+
'triggerPrice': self.safe_number(order, 'stopPrice'),
|
2606
3060
|
'cost': self.safe_string(order, 'dealFunds'),
|
2607
3061
|
'filled': self.safe_string(order, 'dealSize'),
|
2608
3062
|
'remaining': None,
|
@@ -2614,15 +3068,17 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2614
3068
|
},
|
2615
3069
|
'status': status,
|
2616
3070
|
'lastTradeTimestamp': None,
|
2617
|
-
'average':
|
3071
|
+
'average': self.safe_string(order, 'avgDealPrice'),
|
2618
3072
|
'trades': None,
|
2619
3073
|
}, market)
|
2620
3074
|
|
2621
3075
|
async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
2622
3076
|
"""
|
2623
3077
|
fetch all the trades made from a single order
|
2624
|
-
|
2625
|
-
|
3078
|
+
|
3079
|
+
https://docs.kucoin.com/#list-fills
|
3080
|
+
https://docs.kucoin.com/spot-hf/#transaction-details
|
3081
|
+
|
2626
3082
|
:param str id: order id
|
2627
3083
|
:param str symbol: unified market symbol
|
2628
3084
|
:param int [since]: the earliest time in ms to fetch trades for
|
@@ -2630,15 +3086,17 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2630
3086
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2631
3087
|
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
2632
3088
|
"""
|
2633
|
-
request = {
|
3089
|
+
request: dict = {
|
2634
3090
|
'orderId': id,
|
2635
3091
|
}
|
2636
3092
|
return await self.fetch_my_trades(symbol, since, limit, self.extend(request, params))
|
2637
3093
|
|
2638
3094
|
async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
2639
3095
|
"""
|
2640
|
-
|
2641
|
-
|
3096
|
+
|
3097
|
+
https://docs.kucoin.com/#list-fills
|
3098
|
+
https://docs.kucoin.com/spot-hf/#transaction-details
|
3099
|
+
|
2642
3100
|
fetch all trades made by the user
|
2643
3101
|
:param str symbol: unified market symbol
|
2644
3102
|
:param int [since]: the earliest time in ms to fetch trades for
|
@@ -2654,8 +3112,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2654
3112
|
paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
|
2655
3113
|
if paginate:
|
2656
3114
|
return await self.fetch_paginated_call_dynamic('fetchMyTrades', symbol, since, limit, params)
|
2657
|
-
request = {}
|
2658
|
-
hf =
|
3115
|
+
request: dict = {}
|
3116
|
+
hf = None
|
3117
|
+
hf, params = self.handle_hf_and_params(params)
|
2659
3118
|
if hf and symbol is None:
|
2660
3119
|
raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol parameter for hf orders')
|
2661
3120
|
market = None
|
@@ -2669,6 +3128,10 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2669
3128
|
response = None
|
2670
3129
|
request, params = self.handle_until_option('endAt', request, params)
|
2671
3130
|
if hf:
|
3131
|
+
# does not return trades earlier than 2019-02-18T00:00:00Z
|
3132
|
+
if since is not None:
|
3133
|
+
# only returns trades up to one week after the since param
|
3134
|
+
request['startAt'] = since
|
2672
3135
|
response = await self.privateGetHfFills(self.extend(request, params))
|
2673
3136
|
elif method == 'private_get_fills':
|
2674
3137
|
# does not return trades earlier than 2019-02-18T00:00:00Z
|
@@ -2735,7 +3198,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2735
3198
|
async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
2736
3199
|
"""
|
2737
3200
|
get the list of most recent trades for a particular symbol
|
2738
|
-
|
3201
|
+
|
3202
|
+
https://www.kucoin.com/docs/rest/spot-trading/market-data/get-trade-histories
|
3203
|
+
|
2739
3204
|
:param str symbol: unified symbol of the market to fetch trades for
|
2740
3205
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
2741
3206
|
:param int [limit]: the maximum amount of trades to fetch
|
@@ -2744,7 +3209,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2744
3209
|
"""
|
2745
3210
|
await self.load_markets()
|
2746
3211
|
market = self.market(symbol)
|
2747
|
-
request = {
|
3212
|
+
request: dict = {
|
2748
3213
|
'symbol': market['id'],
|
2749
3214
|
}
|
2750
3215
|
# pagination is not supported on the exchange side anymore
|
@@ -2772,7 +3237,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2772
3237
|
trades = self.safe_list(response, 'data', [])
|
2773
3238
|
return self.parse_trades(trades, market, since, limit)
|
2774
3239
|
|
2775
|
-
def parse_trade(self, trade, market: Market = None) -> Trade:
|
3240
|
+
def parse_trade(self, trade: dict, market: Market = None) -> Trade:
|
2776
3241
|
#
|
2777
3242
|
# fetchTrades(public)
|
2778
3243
|
#
|
@@ -2897,17 +3362,19 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2897
3362
|
'fee': fee,
|
2898
3363
|
}, market)
|
2899
3364
|
|
2900
|
-
async def fetch_trading_fee(self, symbol: str, params={}):
|
3365
|
+
async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
|
2901
3366
|
"""
|
2902
3367
|
fetch the trading fees for a market
|
2903
|
-
|
3368
|
+
|
3369
|
+
https://www.kucoin.com/docs/rest/funding/trade-fee/trading-pair-actual-fee-spot-margin-trade_hf
|
3370
|
+
|
2904
3371
|
:param str symbol: unified market symbol
|
2905
3372
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2906
3373
|
:returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
|
2907
3374
|
"""
|
2908
3375
|
await self.load_markets()
|
2909
3376
|
market = self.market(symbol)
|
2910
|
-
request = {
|
3377
|
+
request: dict = {
|
2911
3378
|
'symbols': market['id'],
|
2912
3379
|
}
|
2913
3380
|
response = await self.privateGetTradeFees(self.extend(request, params))
|
@@ -2935,10 +3402,12 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2935
3402
|
'tierBased': True,
|
2936
3403
|
}
|
2937
3404
|
|
2938
|
-
async def withdraw(self, code: str, amount: float, address, tag=None, params={}):
|
3405
|
+
async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
|
2939
3406
|
"""
|
2940
3407
|
make a withdrawal
|
2941
|
-
|
3408
|
+
|
3409
|
+
https://www.kucoin.com/docs/rest/funding/withdrawals/apply-withdraw-v3-
|
3410
|
+
|
2942
3411
|
:param str code: unified currency code
|
2943
3412
|
:param float amount: the amount to withdraw
|
2944
3413
|
:param str address: the address to withdraw to
|
@@ -2950,10 +3419,10 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2950
3419
|
await self.load_markets()
|
2951
3420
|
self.check_address(address)
|
2952
3421
|
currency = self.currency(code)
|
2953
|
-
request = {
|
3422
|
+
request: dict = {
|
2954
3423
|
'currency': currency['id'],
|
2955
|
-
'
|
2956
|
-
'
|
3424
|
+
'toAddress': address,
|
3425
|
+
'withdrawType': 'ADDRESS',
|
2957
3426
|
# 'memo': tag,
|
2958
3427
|
# 'isInner': False, # internal transfer or external withdrawal
|
2959
3428
|
# 'remark': 'optional',
|
@@ -2965,13 +3434,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2965
3434
|
networkCode, params = self.handle_network_code_and_params(params)
|
2966
3435
|
if networkCode is not None:
|
2967
3436
|
request['chain'] = self.network_code_to_id(networkCode).lower()
|
3437
|
+
request['amount'] = float(self.currency_to_precision(code, amount, networkCode))
|
2968
3438
|
includeFee = None
|
2969
3439
|
includeFee, params = self.handle_option_and_params(params, 'withdraw', 'includeFee', False)
|
2970
3440
|
if includeFee:
|
2971
3441
|
request['feeDeductType'] = 'INTERNAL'
|
2972
3442
|
response = await self.privatePostWithdrawals(self.extend(request, params))
|
2973
3443
|
#
|
2974
|
-
#
|
3444
|
+
# the id is inside "data"
|
2975
3445
|
#
|
2976
3446
|
# {
|
2977
3447
|
# "code": 200000,
|
@@ -2983,8 +3453,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2983
3453
|
data = self.safe_dict(response, 'data', {})
|
2984
3454
|
return self.parse_transaction(data, currency)
|
2985
3455
|
|
2986
|
-
def parse_transaction_status(self, status):
|
2987
|
-
statuses = {
|
3456
|
+
def parse_transaction_status(self, status: Str):
|
3457
|
+
statuses: dict = {
|
2988
3458
|
'SUCCESS': 'ok',
|
2989
3459
|
'PROCESSING': 'pending',
|
2990
3460
|
'WALLET_PROCESSING': 'pending',
|
@@ -2992,7 +3462,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2992
3462
|
}
|
2993
3463
|
return self.safe_string(statuses, status, status)
|
2994
3464
|
|
2995
|
-
def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
|
3465
|
+
def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
|
2996
3466
|
#
|
2997
3467
|
# fetchDeposits
|
2998
3468
|
#
|
@@ -3099,8 +3569,10 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3099
3569
|
async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
3100
3570
|
"""
|
3101
3571
|
fetch all deposits made to an account
|
3102
|
-
|
3103
|
-
|
3572
|
+
|
3573
|
+
https://www.kucoin.com/docs/rest/funding/deposit/get-deposit-list
|
3574
|
+
https://www.kucoin.com/docs/rest/funding/deposit/get-v1-historical-deposits-list
|
3575
|
+
|
3104
3576
|
:param str code: unified currency code
|
3105
3577
|
:param int [since]: the earliest time in ms to fetch deposits for
|
3106
3578
|
:param int [limit]: the maximum number of deposits structures to retrieve
|
@@ -3114,7 +3586,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3114
3586
|
paginate, params = self.handle_option_and_params(params, 'fetchDeposits', 'paginate')
|
3115
3587
|
if paginate:
|
3116
3588
|
return await self.fetch_paginated_call_dynamic('fetchDeposits', code, since, limit, params)
|
3117
|
-
request = {}
|
3589
|
+
request: dict = {}
|
3118
3590
|
currency = None
|
3119
3591
|
if code is not None:
|
3120
3592
|
currency = self.currency(code)
|
@@ -3169,14 +3641,17 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3169
3641
|
# }
|
3170
3642
|
# }
|
3171
3643
|
#
|
3172
|
-
|
3173
|
-
|
3644
|
+
data = self.safe_dict(response, 'data', {})
|
3645
|
+
items = self.safe_list(data, 'items', [])
|
3646
|
+
return self.parse_transactions(items, currency, since, limit, {'type': 'deposit'})
|
3174
3647
|
|
3175
3648
|
async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
3176
3649
|
"""
|
3177
3650
|
fetch all withdrawals made from an account
|
3178
|
-
|
3179
|
-
|
3651
|
+
|
3652
|
+
https://www.kucoin.com/docs/rest/funding/withdrawals/get-withdrawals-list
|
3653
|
+
https://www.kucoin.com/docs/rest/funding/withdrawals/get-v1-historical-withdrawals-list
|
3654
|
+
|
3180
3655
|
:param str code: unified currency code
|
3181
3656
|
:param int [since]: the earliest time in ms to fetch withdrawals for
|
3182
3657
|
:param int [limit]: the maximum number of withdrawals structures to retrieve
|
@@ -3190,7 +3665,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3190
3665
|
paginate, params = self.handle_option_and_params(params, 'fetchWithdrawals', 'paginate')
|
3191
3666
|
if paginate:
|
3192
3667
|
return await self.fetch_paginated_call_dynamic('fetchWithdrawals', code, since, limit, params)
|
3193
|
-
request = {}
|
3668
|
+
request: dict = {}
|
3194
3669
|
currency = None
|
3195
3670
|
if code is not None:
|
3196
3671
|
currency = self.currency(code)
|
@@ -3246,14 +3721,15 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3246
3721
|
# }
|
3247
3722
|
# }
|
3248
3723
|
#
|
3249
|
-
|
3250
|
-
|
3724
|
+
data = self.safe_dict(response, 'data', {})
|
3725
|
+
items = self.safe_list(data, 'items', [])
|
3726
|
+
return self.parse_transactions(items, currency, since, limit, {'type': 'withdrawal'})
|
3251
3727
|
|
3252
3728
|
def parse_balance_helper(self, entry):
|
3253
3729
|
account = self.account()
|
3254
|
-
account['used'] = self.
|
3255
|
-
account['free'] = self.
|
3256
|
-
account['total'] = self.
|
3730
|
+
account['used'] = self.safe_string_2(entry, 'holdBalance', 'hold')
|
3731
|
+
account['free'] = self.safe_string_2(entry, 'availableBalance', 'available')
|
3732
|
+
account['total'] = self.safe_string_2(entry, 'totalBalance', 'total')
|
3257
3733
|
debt = self.safe_string(entry, 'liability')
|
3258
3734
|
interest = self.safe_string(entry, 'interest')
|
3259
3735
|
account['debt'] = Precise.string_add(debt, interest)
|
@@ -3262,9 +3738,11 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3262
3738
|
async def fetch_balance(self, params={}) -> Balances:
|
3263
3739
|
"""
|
3264
3740
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
3265
|
-
|
3266
|
-
|
3267
|
-
|
3741
|
+
|
3742
|
+
https://www.kucoin.com/docs/rest/account/basic-info/get-account-list-spot-margin-trade_hf
|
3743
|
+
https://www.kucoin.com/docs/rest/funding/funding-overview/get-account-detail-margin
|
3744
|
+
https://www.kucoin.com/docs/rest/funding/funding-overview/get-account-detail-isolated-margin
|
3745
|
+
|
3268
3746
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3269
3747
|
:param dict [params.marginMode]: 'cross' or 'isolated', margin type for fetching margin balance
|
3270
3748
|
:param dict [params.type]: extra parameters specific to the exchange API endpoint
|
@@ -3281,15 +3759,15 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3281
3759
|
accountsByType = self.safe_dict(self.options, 'accountsByType')
|
3282
3760
|
type = self.safe_string(accountsByType, requestedType, requestedType)
|
3283
3761
|
params = self.omit(params, 'type')
|
3284
|
-
|
3285
|
-
|
3762
|
+
hf = None
|
3763
|
+
hf, params = self.handle_hf_and_params(params)
|
3764
|
+
if hf and (type != 'main'):
|
3286
3765
|
type = 'trade_hf'
|
3287
|
-
params = self.omit(params, 'hf')
|
3288
3766
|
marginMode, query = self.handle_margin_mode_and_params('fetchBalance', params)
|
3289
3767
|
response = None
|
3290
|
-
request = {}
|
3768
|
+
request: dict = {}
|
3291
3769
|
isolated = (marginMode == 'isolated') or (type == 'isolated')
|
3292
|
-
cross = (marginMode == 'cross') or (type == '
|
3770
|
+
cross = (marginMode == 'cross') or (type == 'margin')
|
3293
3771
|
if isolated:
|
3294
3772
|
if currency is not None:
|
3295
3773
|
request['balanceCurrency'] = currency['id']
|
@@ -3302,7 +3780,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3302
3780
|
request['type'] = type
|
3303
3781
|
response = await self.privateGetAccounts(self.extend(request, query))
|
3304
3782
|
#
|
3305
|
-
# Spot
|
3783
|
+
# Spot
|
3306
3784
|
#
|
3307
3785
|
# {
|
3308
3786
|
# "code": "200000",
|
@@ -3318,35 +3796,59 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3318
3796
|
# ]
|
3319
3797
|
# }
|
3320
3798
|
#
|
3799
|
+
# Cross
|
3800
|
+
#
|
3801
|
+
# {
|
3802
|
+
# "code": "200000",
|
3803
|
+
# "data": {
|
3804
|
+
# "debtRatio": "0",
|
3805
|
+
# "accounts": [
|
3806
|
+
# {
|
3807
|
+
# "currency": "USDT",
|
3808
|
+
# "totalBalance": "5",
|
3809
|
+
# "availableBalance": "5",
|
3810
|
+
# "holdBalance": "0",
|
3811
|
+
# "liability": "0",
|
3812
|
+
# "maxBorrowSize": "20"
|
3813
|
+
# },
|
3814
|
+
# ]
|
3815
|
+
# }
|
3816
|
+
# }
|
3817
|
+
#
|
3321
3818
|
# Isolated
|
3322
3819
|
#
|
3323
3820
|
# {
|
3324
3821
|
# "code": "200000",
|
3325
3822
|
# "data": {
|
3326
|
-
# "
|
3327
|
-
# "
|
3823
|
+
# "totalAssetOfQuoteCurrency": "0",
|
3824
|
+
# "totalLiabilityOfQuoteCurrency": "0",
|
3825
|
+
# "timestamp": 1712085661155,
|
3328
3826
|
# "assets": [
|
3329
3827
|
# {
|
3330
3828
|
# "symbol": "MANA-USDT",
|
3331
|
-
# "status": "
|
3829
|
+
# "status": "EFFECTIVE",
|
3332
3830
|
# "debtRatio": "0",
|
3333
3831
|
# "baseAsset": {
|
3334
3832
|
# "currency": "MANA",
|
3335
|
-
# "
|
3336
|
-
# "
|
3337
|
-
# "
|
3833
|
+
# "borrowEnabled": True,
|
3834
|
+
# "transferInEnabled": True,
|
3835
|
+
# "total": "0",
|
3836
|
+
# "hold": "0",
|
3837
|
+
# "available": "0",
|
3338
3838
|
# "liability": "0",
|
3339
3839
|
# "interest": "0",
|
3340
|
-
# "
|
3840
|
+
# "maxBorrowSize": "0"
|
3341
3841
|
# },
|
3342
3842
|
# "quoteAsset": {
|
3343
3843
|
# "currency": "USDT",
|
3344
|
-
# "
|
3345
|
-
# "
|
3346
|
-
# "
|
3844
|
+
# "borrowEnabled": True,
|
3845
|
+
# "transferInEnabled": True,
|
3846
|
+
# "total": "0",
|
3847
|
+
# "hold": "0",
|
3848
|
+
# "available": "0",
|
3347
3849
|
# "liability": "0",
|
3348
3850
|
# "interest": "0",
|
3349
|
-
# "
|
3851
|
+
# "maxBorrowSize": "0"
|
3350
3852
|
# }
|
3351
3853
|
# },
|
3352
3854
|
# ...
|
@@ -3354,13 +3856,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3354
3856
|
# }
|
3355
3857
|
# }
|
3356
3858
|
#
|
3357
|
-
data =
|
3358
|
-
result = {
|
3859
|
+
data = None
|
3860
|
+
result: dict = {
|
3359
3861
|
'info': response,
|
3360
3862
|
'timestamp': None,
|
3361
3863
|
'datetime': None,
|
3362
3864
|
}
|
3363
3865
|
if isolated:
|
3866
|
+
data = self.safe_dict(response, 'data', {})
|
3364
3867
|
assets = self.safe_value(data, 'assets', data)
|
3365
3868
|
for i in range(0, len(assets)):
|
3366
3869
|
entry = assets[i]
|
@@ -3370,11 +3873,12 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3370
3873
|
quote = self.safe_dict(entry, 'quoteAsset', {})
|
3371
3874
|
baseCode = self.safe_currency_code(self.safe_string(base, 'currency'))
|
3372
3875
|
quoteCode = self.safe_currency_code(self.safe_string(quote, 'currency'))
|
3373
|
-
subResult = {}
|
3876
|
+
subResult: dict = {}
|
3374
3877
|
subResult[baseCode] = self.parse_balance_helper(base)
|
3375
3878
|
subResult[quoteCode] = self.parse_balance_helper(quote)
|
3376
3879
|
result[symbol] = self.safe_balance(subResult)
|
3377
3880
|
elif cross:
|
3881
|
+
data = self.safe_dict(response, 'data', {})
|
3378
3882
|
accounts = self.safe_list(data, 'accounts', [])
|
3379
3883
|
for i in range(0, len(accounts)):
|
3380
3884
|
balance = accounts[i]
|
@@ -3382,6 +3886,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3382
3886
|
codeInner = self.safe_currency_code(currencyId)
|
3383
3887
|
result[codeInner] = self.parse_balance_helper(balance)
|
3384
3888
|
else:
|
3889
|
+
data = self.safe_list(response, 'data', [])
|
3385
3890
|
for i in range(0, len(data)):
|
3386
3891
|
balance = data[i]
|
3387
3892
|
balanceType = self.safe_string(balance, 'type')
|
@@ -3399,9 +3904,11 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3399
3904
|
async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
3400
3905
|
"""
|
3401
3906
|
transfer currency internally between wallets on the same account
|
3402
|
-
|
3403
|
-
|
3404
|
-
|
3907
|
+
|
3908
|
+
https://www.kucoin.com/docs/rest/funding/transfer/inner-transfer
|
3909
|
+
https://docs.kucoin.com/futures/#transfer-funds-to-kucoin-main-account-2
|
3910
|
+
https://docs.kucoin.com/spot-hf/#internal-funds-transfers-in-high-frequency-trading-accounts
|
3911
|
+
|
3405
3912
|
:param str code: unified currency code
|
3406
3913
|
:param float amount: amount to transfer
|
3407
3914
|
:param str fromAccount: account to transfer from
|
@@ -3419,7 +3926,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3419
3926
|
if fromId == 'contract':
|
3420
3927
|
if toId != 'main':
|
3421
3928
|
raise ExchangeError(self.id + ' transfer() only supports transferring from futures account to main account')
|
3422
|
-
request = {
|
3929
|
+
request: dict = {
|
3423
3930
|
'currency': currency['id'],
|
3424
3931
|
'amount': requestedAmount,
|
3425
3932
|
}
|
@@ -3454,7 +3961,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3454
3961
|
data = self.safe_dict(response, 'data')
|
3455
3962
|
return self.parse_transfer(data, currency)
|
3456
3963
|
else:
|
3457
|
-
request = {
|
3964
|
+
request: dict = {
|
3458
3965
|
'currency': currency['id'],
|
3459
3966
|
'amount': requestedAmount,
|
3460
3967
|
}
|
@@ -3481,7 +3988,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3481
3988
|
data = self.safe_dict(response, 'data')
|
3482
3989
|
return self.parse_transfer(data, currency)
|
3483
3990
|
|
3484
|
-
def parse_transfer(self, transfer, currency: Currency = None):
|
3991
|
+
def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
|
3485
3992
|
#
|
3486
3993
|
# transfer(spot)
|
3487
3994
|
#
|
@@ -3536,14 +4043,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3536
4043
|
'info': transfer,
|
3537
4044
|
}
|
3538
4045
|
|
3539
|
-
def parse_transfer_status(self, status):
|
3540
|
-
statuses = {
|
4046
|
+
def parse_transfer_status(self, status: Str) -> Str:
|
4047
|
+
statuses: dict = {
|
3541
4048
|
'PROCESSING': 'pending',
|
3542
4049
|
}
|
3543
4050
|
return self.safe_string(statuses, status, status)
|
3544
4051
|
|
3545
4052
|
def parse_ledger_entry_type(self, type):
|
3546
|
-
types = {
|
4053
|
+
types: dict = {
|
3547
4054
|
'Assets Transferred in After Upgrading': 'transfer', # Assets Transferred in After V1 to V2 Upgrading
|
3548
4055
|
'Deposit': 'transaction', # Deposit
|
3549
4056
|
'Withdrawal': 'transaction', # Withdrawal
|
@@ -3586,7 +4093,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3586
4093
|
}
|
3587
4094
|
return self.safe_string(types, type, type)
|
3588
4095
|
|
3589
|
-
def parse_ledger_entry(self, item, currency: Currency = None):
|
4096
|
+
def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
|
3590
4097
|
#
|
3591
4098
|
# {
|
3592
4099
|
# "id": "611a1e7c6a053300067a88d9", #unique key for each ledger entry
|
@@ -3604,6 +4111,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3604
4111
|
id = self.safe_string(item, 'id')
|
3605
4112
|
currencyId = self.safe_string(item, 'currency')
|
3606
4113
|
code = self.safe_currency_code(currencyId, currency)
|
4114
|
+
currency = self.safe_currency(currencyId, currency)
|
3607
4115
|
amount = self.safe_number(item, 'amount')
|
3608
4116
|
balanceAfter = None
|
3609
4117
|
# balanceAfter = self.safe_number(item, 'balance'); only returns zero string
|
@@ -3646,7 +4154,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3646
4154
|
if feeCost != '0':
|
3647
4155
|
feeCurrency = code
|
3648
4156
|
fee = {'cost': self.parse_number(feeCost), 'currency': feeCurrency}
|
3649
|
-
return {
|
4157
|
+
return self.safe_ledger_entry({
|
4158
|
+
'info': item,
|
3650
4159
|
'id': id,
|
3651
4160
|
'direction': direction,
|
3652
4161
|
'account': account,
|
@@ -3661,33 +4170,34 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3661
4170
|
'after': balanceAfter, # None
|
3662
4171
|
'status': None,
|
3663
4172
|
'fee': fee,
|
3664
|
-
|
3665
|
-
}
|
4173
|
+
}, currency)
|
3666
4174
|
|
3667
|
-
async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
|
4175
|
+
async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
|
3668
4176
|
"""
|
3669
|
-
|
3670
|
-
|
3671
|
-
|
3672
|
-
|
3673
|
-
|
4177
|
+
fetch the history of changes, actions done by the user or operations that altered the balance of the user
|
4178
|
+
|
4179
|
+
https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-spot-margin
|
4180
|
+
https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-trade_hf
|
4181
|
+
https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-margin_hf
|
4182
|
+
|
4183
|
+
:param str [code]: unified currency code, default is None
|
3674
4184
|
:param int [since]: timestamp in ms of the earliest ledger entry, default is None
|
3675
|
-
:param int [limit]: max number of ledger
|
4185
|
+
:param int [limit]: max number of ledger entries to return, default is None
|
3676
4186
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3677
4187
|
:param boolean [params.hf]: default False, when True will fetch ledger entries for the high frequency trading account
|
3678
4188
|
:param int [params.until]: the latest time in ms to fetch entries for
|
3679
|
-
:param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [
|
3680
|
-
:returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger
|
4189
|
+
:param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
4190
|
+
:returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
|
3681
4191
|
"""
|
3682
4192
|
await self.load_markets()
|
3683
4193
|
await self.load_accounts()
|
3684
4194
|
paginate = False
|
3685
4195
|
paginate, params = self.handle_option_and_params(params, 'fetchLedger', 'paginate')
|
3686
|
-
|
3687
|
-
params = self.
|
4196
|
+
hf = None
|
4197
|
+
hf, params = self.handle_hf_and_params(params)
|
3688
4198
|
if paginate:
|
3689
4199
|
return await self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params)
|
3690
|
-
request = {
|
4200
|
+
request: dict = {
|
3691
4201
|
# 'currency': currency['id'], # can choose up to 10, if not provided returns for all currencies by default
|
3692
4202
|
# 'direction': 'in', # 'out'
|
3693
4203
|
# 'bizType': 'DEPOSIT', # DEPOSIT, WITHDRAW, TRANSFER, SUB_TRANSFER,TRADE_EXCHANGE, MARGIN_EXCHANGE, KUCOIN_BONUS(optional)
|
@@ -3705,7 +4215,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3705
4215
|
marginMode = None
|
3706
4216
|
marginMode, params = self.handle_margin_mode_and_params('fetchLedger', params)
|
3707
4217
|
response = None
|
3708
|
-
if
|
4218
|
+
if hf:
|
3709
4219
|
if marginMode is not None:
|
3710
4220
|
response = await self.privateGetHfMarginAccountLedgers(self.extend(request, params))
|
3711
4221
|
else:
|
@@ -3770,15 +4280,6 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3770
4280
|
return config['v1']
|
3771
4281
|
return self.safe_value(config, 'cost', 1)
|
3772
4282
|
|
3773
|
-
def parse_borrow_rate_history(self, response, code, since, limit):
|
3774
|
-
result = []
|
3775
|
-
for i in range(0, len(response)):
|
3776
|
-
item = response[i]
|
3777
|
-
borrowRate = self.parse_borrow_rate(item)
|
3778
|
-
result.append(borrowRate)
|
3779
|
-
sorted = self.sort_by(result, 'timestamp')
|
3780
|
-
return self.filter_by_currency_since_limit(sorted, code, since, limit)
|
3781
|
-
|
3782
4283
|
def parse_borrow_rate(self, info, currency: Currency = None):
|
3783
4284
|
#
|
3784
4285
|
# {
|
@@ -3809,13 +4310,15 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3809
4310
|
'info': info,
|
3810
4311
|
}
|
3811
4312
|
|
3812
|
-
async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
4313
|
+
async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
|
3813
4314
|
"""
|
3814
4315
|
fetch the interest owed by the user for borrowing currency for margin trading
|
3815
|
-
|
3816
|
-
|
3817
|
-
|
3818
|
-
|
4316
|
+
|
4317
|
+
https://docs.kucoin.com/#get-repay-record
|
4318
|
+
https://docs.kucoin.com/#query-isolated-margin-account-info
|
4319
|
+
|
4320
|
+
:param str [code]: unified currency code
|
4321
|
+
:param str [symbol]: unified market symbol, required for isolated margin
|
3819
4322
|
:param int [since]: the earliest time in ms to fetch borrrow interest for
|
3820
4323
|
:param int [limit]: the maximum number of structures to retrieve
|
3821
4324
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -3824,14 +4327,19 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3824
4327
|
"""
|
3825
4328
|
await self.load_markets()
|
3826
4329
|
marginMode = None
|
3827
|
-
marginMode, params = self.handle_margin_mode_and_params('fetchBorrowInterest', params)
|
3828
|
-
|
3829
|
-
|
3830
|
-
request = {}
|
3831
|
-
response = None
|
4330
|
+
marginMode, params = self.handle_margin_mode_and_params('fetchBorrowInterest', params, 'cross')
|
4331
|
+
request: dict = {}
|
4332
|
+
currency = None
|
3832
4333
|
if code is not None:
|
3833
4334
|
currency = self.currency(code)
|
3834
|
-
|
4335
|
+
if marginMode == 'isolated':
|
4336
|
+
request['balanceCurrency'] = currency['id']
|
4337
|
+
else:
|
4338
|
+
request['quoteCurrency'] = currency['id']
|
4339
|
+
market = None
|
4340
|
+
if symbol is not None:
|
4341
|
+
market = self.market(symbol)
|
4342
|
+
response = None
|
3835
4343
|
if marginMode == 'isolated':
|
3836
4344
|
response = await self.privateGetIsolatedAccounts(self.extend(request, params))
|
3837
4345
|
else:
|
@@ -3902,9 +4410,11 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3902
4410
|
#
|
3903
4411
|
data = self.safe_dict(response, 'data', {})
|
3904
4412
|
assets = self.safe_list(data, 'assets', []) if (marginMode == 'isolated') else self.safe_list(data, 'accounts', [])
|
3905
|
-
|
4413
|
+
interest = self.parse_borrow_interests(assets, market)
|
4414
|
+
filteredByCurrency = self.filter_by_currency_since_limit(interest, code, since, limit)
|
4415
|
+
return self.filter_by_symbol_since_limit(filteredByCurrency, symbol, since, limit)
|
3906
4416
|
|
3907
|
-
def parse_borrow_interest(self, info, market: Market = None):
|
4417
|
+
def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
|
3908
4418
|
#
|
3909
4419
|
# Cross
|
3910
4420
|
#
|
@@ -3967,21 +4477,23 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3967
4477
|
interest = self.safe_number(info, 'accruedInterest')
|
3968
4478
|
currencyId = self.safe_string(info, 'currency')
|
3969
4479
|
return {
|
4480
|
+
'info': info,
|
3970
4481
|
'symbol': symbol,
|
3971
|
-
'marginMode': marginMode,
|
3972
4482
|
'currency': self.safe_currency_code(currencyId),
|
3973
4483
|
'interest': interest,
|
3974
4484
|
'interestRate': self.safe_number(info, 'dailyIntRate'),
|
3975
4485
|
'amountBorrowed': amountBorrowed,
|
4486
|
+
'marginMode': marginMode,
|
3976
4487
|
'timestamp': timestamp, # create time
|
3977
4488
|
'datetime': self.iso8601(timestamp),
|
3978
|
-
'info': info,
|
3979
4489
|
}
|
3980
4490
|
|
3981
4491
|
async def fetch_borrow_rate_histories(self, codes=None, since: Int = None, limit: Int = None, params={}):
|
3982
4492
|
"""
|
3983
4493
|
retrieves a history of a multiple currencies borrow interest rate at specific time slots, returns all currencies if no symbols passed, default is None
|
3984
|
-
|
4494
|
+
|
4495
|
+
https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/get-cross-isolated-margin-interest-records
|
4496
|
+
|
3985
4497
|
:param str[]|None codes: list of unified currency codes, default is None
|
3986
4498
|
:param int [since]: timestamp in ms of the earliest borrowRate, default is None
|
3987
4499
|
:param int [limit]: max number of borrow rate prices to return, default is None
|
@@ -3994,7 +4506,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3994
4506
|
marginResult = self.handle_margin_mode_and_params('fetchBorrowRateHistories', params)
|
3995
4507
|
marginMode = self.safe_string(marginResult, 0, 'cross')
|
3996
4508
|
isIsolated = (marginMode == 'isolated') # True-isolated, False-cross
|
3997
|
-
request = {
|
4509
|
+
request: dict = {
|
3998
4510
|
'isIsolated': isIsolated,
|
3999
4511
|
}
|
4000
4512
|
if since is not None:
|
@@ -4024,13 +4536,15 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4024
4536
|
# }
|
4025
4537
|
#
|
4026
4538
|
data = self.safe_dict(response, 'data')
|
4027
|
-
rows = self.safe_list(data, 'items')
|
4539
|
+
rows = self.safe_list(data, 'items', [])
|
4028
4540
|
return self.parse_borrow_rate_histories(rows, codes, since, limit)
|
4029
4541
|
|
4030
4542
|
async def fetch_borrow_rate_history(self, code: str, since: Int = None, limit: Int = None, params={}):
|
4031
4543
|
"""
|
4032
4544
|
retrieves a history of a currencies borrow interest rate at specific time slots
|
4033
|
-
|
4545
|
+
|
4546
|
+
https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/get-cross-isolated-margin-interest-records
|
4547
|
+
|
4034
4548
|
:param str code: unified currency code
|
4035
4549
|
:param int [since]: timestamp for the earliest borrow rate
|
4036
4550
|
:param int [limit]: the maximum number of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>` to retrieve
|
@@ -4044,7 +4558,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4044
4558
|
marginMode = self.safe_string(marginResult, 0, 'cross')
|
4045
4559
|
isIsolated = (marginMode == 'isolated') # True-isolated, False-cross
|
4046
4560
|
currency = self.currency(code)
|
4047
|
-
request = {
|
4561
|
+
request: dict = {
|
4048
4562
|
'isIsolated': isIsolated,
|
4049
4563
|
'currency': currency['id'],
|
4050
4564
|
}
|
@@ -4075,7 +4589,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4075
4589
|
# }
|
4076
4590
|
#
|
4077
4591
|
data = self.safe_dict(response, 'data')
|
4078
|
-
rows = self.safe_list(data, 'items')
|
4592
|
+
rows = self.safe_list(data, 'items', [])
|
4079
4593
|
return self.parse_borrow_rate_history(rows, code, since, limit)
|
4080
4594
|
|
4081
4595
|
def parse_borrow_rate_histories(self, response, codes, since, limit):
|
@@ -4089,7 +4603,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4089
4603
|
# }
|
4090
4604
|
# ]
|
4091
4605
|
#
|
4092
|
-
borrowRateHistories = {}
|
4606
|
+
borrowRateHistories: dict = {}
|
4093
4607
|
for i in range(0, len(response)):
|
4094
4608
|
item = response[i]
|
4095
4609
|
code = self.safe_currency_code(self.safe_string(item, 'currency'))
|
@@ -4107,7 +4621,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4107
4621
|
async def borrow_cross_margin(self, code: str, amount: float, params={}):
|
4108
4622
|
"""
|
4109
4623
|
create a loan to borrow margin
|
4110
|
-
|
4624
|
+
|
4625
|
+
https://docs.kucoin.com/#1-margin-borrowing
|
4626
|
+
|
4111
4627
|
:param str code: unified currency code of the currency to borrow
|
4112
4628
|
:param float amount: the amount to borrow
|
4113
4629
|
:param dict [params]: extra parameters specific to the exchange API endpoints
|
@@ -4116,7 +4632,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4116
4632
|
"""
|
4117
4633
|
await self.load_markets()
|
4118
4634
|
currency = self.currency(code)
|
4119
|
-
request = {
|
4635
|
+
request: dict = {
|
4120
4636
|
'currency': currency['id'],
|
4121
4637
|
'size': self.currency_to_precision(code, amount),
|
4122
4638
|
'timeInForce': 'FOK',
|
@@ -4140,7 +4656,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4140
4656
|
async def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
|
4141
4657
|
"""
|
4142
4658
|
create a loan to borrow margin
|
4143
|
-
|
4659
|
+
|
4660
|
+
https://docs.kucoin.com/#1-margin-borrowing
|
4661
|
+
|
4144
4662
|
:param str symbol: unified market symbol, required for isolated margin
|
4145
4663
|
:param str code: unified currency code of the currency to borrow
|
4146
4664
|
:param float amount: the amount to borrow
|
@@ -4151,7 +4669,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4151
4669
|
await self.load_markets()
|
4152
4670
|
market = self.market(symbol)
|
4153
4671
|
currency = self.currency(code)
|
4154
|
-
request = {
|
4672
|
+
request: dict = {
|
4155
4673
|
'currency': currency['id'],
|
4156
4674
|
'size': self.currency_to_precision(code, amount),
|
4157
4675
|
'symbol': market['id'],
|
@@ -4177,7 +4695,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4177
4695
|
async def repay_cross_margin(self, code: str, amount, params={}):
|
4178
4696
|
"""
|
4179
4697
|
repay borrowed margin and interest
|
4180
|
-
|
4698
|
+
|
4699
|
+
https://docs.kucoin.com/#2-repayment
|
4700
|
+
|
4181
4701
|
:param str code: unified currency code of the currency to repay
|
4182
4702
|
:param float amount: the amount to repay
|
4183
4703
|
:param dict [params]: extra parameters specific to the exchange API endpoints
|
@@ -4185,7 +4705,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4185
4705
|
"""
|
4186
4706
|
await self.load_markets()
|
4187
4707
|
currency = self.currency(code)
|
4188
|
-
request = {
|
4708
|
+
request: dict = {
|
4189
4709
|
'currency': currency['id'],
|
4190
4710
|
'size': self.currency_to_precision(code, amount),
|
4191
4711
|
}
|
@@ -4208,7 +4728,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4208
4728
|
async def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
|
4209
4729
|
"""
|
4210
4730
|
repay borrowed margin and interest
|
4211
|
-
|
4731
|
+
|
4732
|
+
https://docs.kucoin.com/#2-repayment
|
4733
|
+
|
4212
4734
|
:param str symbol: unified market symbol
|
4213
4735
|
:param str code: unified currency code of the currency to repay
|
4214
4736
|
:param float amount: the amount to repay
|
@@ -4218,7 +4740,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4218
4740
|
await self.load_markets()
|
4219
4741
|
market = self.market(symbol)
|
4220
4742
|
currency = self.currency(code)
|
4221
|
-
request = {
|
4743
|
+
request: dict = {
|
4222
4744
|
'currency': currency['id'],
|
4223
4745
|
'size': self.currency_to_precision(code, amount),
|
4224
4746
|
'symbol': market['id'],
|
@@ -4262,7 +4784,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4262
4784
|
async def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
|
4263
4785
|
"""
|
4264
4786
|
fetch deposit and withdraw fees - *IMPORTANT* use fetchDepositWithdrawFee to get more in-depth info
|
4265
|
-
|
4787
|
+
|
4788
|
+
https://docs.kucoin.com/#get-currencies
|
4789
|
+
|
4266
4790
|
:param str[]|None codes: list of unified currency codes
|
4267
4791
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4268
4792
|
:returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
|
@@ -4290,6 +4814,38 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4290
4814
|
data = self.safe_list(response, 'data', [])
|
4291
4815
|
return self.parse_deposit_withdraw_fees(data, codes, 'currency')
|
4292
4816
|
|
4817
|
+
async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
|
4818
|
+
"""
|
4819
|
+
set the level of leverage for a market
|
4820
|
+
|
4821
|
+
https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/modify-leverage-multiplier
|
4822
|
+
|
4823
|
+
:param int [leverage]: New leverage multiplier. Must be greater than 1 and up to two decimal places, and cannot be less than the user's current debt leverage or greater than the system's maximum leverage
|
4824
|
+
:param str [symbol]: unified market symbol
|
4825
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4826
|
+
:returns dict: response from the exchange
|
4827
|
+
"""
|
4828
|
+
await self.load_markets()
|
4829
|
+
market = None
|
4830
|
+
marketType: Str = None
|
4831
|
+
marketType, params = self.handle_market_type_and_params('setLeverage', None, params)
|
4832
|
+
if (symbol is not None) or marketType != 'spot':
|
4833
|
+
market = self.market(symbol)
|
4834
|
+
if market['contract']:
|
4835
|
+
raise NotSupported(self.id + ' setLeverage currently supports only spot margin')
|
4836
|
+
marginMode: Str = None
|
4837
|
+
marginMode, params = self.handle_margin_mode_and_params('setLeverage', params)
|
4838
|
+
if marginMode is None:
|
4839
|
+
raise ArgumentsRequired(self.id + ' setLeverage requires a marginMode parameter')
|
4840
|
+
request: dict = {}
|
4841
|
+
if marginMode == 'isolated' and symbol is None:
|
4842
|
+
raise ArgumentsRequired(self.id + ' setLeverage requires a symbol parameter for isolated margin')
|
4843
|
+
if symbol is not None:
|
4844
|
+
request['symbol'] = market['id']
|
4845
|
+
request['leverage'] = str(leverage)
|
4846
|
+
request['isIsolated'] = (marginMode == 'isolated')
|
4847
|
+
return await self.privatePostPositionUpdateUserLeverage(self.extend(request, params))
|
4848
|
+
|
4293
4849
|
def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
|
4294
4850
|
#
|
4295
4851
|
# the v2 URL is https://openapi-v2.kucoin.com/api/v1/endpoint
|
@@ -4305,12 +4861,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4305
4861
|
endpoint = '/api/' + version + '/' + self.implode_params(path, params)
|
4306
4862
|
if api == 'webExchange':
|
4307
4863
|
endpoint = '/' + self.implode_params(path, params)
|
4864
|
+
if api == 'earn':
|
4865
|
+
endpoint = '/api/v1/' + self.implode_params(path, params)
|
4308
4866
|
query = self.omit(params, self.extract_params(path))
|
4309
4867
|
endpart = ''
|
4310
4868
|
headers = headers if (headers is not None) else {}
|
4311
4869
|
url = self.urls['api'][api]
|
4312
4870
|
if not self.is_empty(query):
|
4313
|
-
if (method == 'GET') or (method == 'DELETE'):
|
4871
|
+
if ((method == 'GET') or (method == 'DELETE')) and (path != 'orders/multi-cancel'):
|
4314
4872
|
endpoint += '?' + self.rawencode(query)
|
4315
4873
|
else:
|
4316
4874
|
body = self.json(query)
|
@@ -4320,7 +4878,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4320
4878
|
isFuturePrivate = (api == 'futuresPrivate')
|
4321
4879
|
isPrivate = (api == 'private')
|
4322
4880
|
isBroker = (api == 'broker')
|
4323
|
-
|
4881
|
+
isEarn = (api == 'earn')
|
4882
|
+
if isPrivate or isFuturePrivate or isBroker or isEarn:
|
4324
4883
|
self.check_required_credentials()
|
4325
4884
|
timestamp = str(self.nonce())
|
4326
4885
|
headers = self.extend({
|
@@ -4346,13 +4905,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4346
4905
|
partnerSignature = self.hmac(self.encode(partnerPayload), self.encode(partnerSecret), hashlib.sha256, 'base64')
|
4347
4906
|
headers['KC-API-PARTNER-SIGN'] = partnerSignature
|
4348
4907
|
headers['KC-API-PARTNER'] = partnerId
|
4908
|
+
headers['KC-API-PARTNER-VERIFY'] = 'true'
|
4349
4909
|
if isBroker:
|
4350
4910
|
brokerName = self.safe_string(partner, 'name')
|
4351
4911
|
if brokerName is not None:
|
4352
4912
|
headers['KC-BROKER-NAME'] = brokerName
|
4353
4913
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
4354
4914
|
|
4355
|
-
def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
4915
|
+
def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
4356
4916
|
if not response:
|
4357
4917
|
self.throw_broadly_matched_exception(self.exceptions['broad'], body, body)
|
4358
4918
|
return None
|
@@ -4364,7 +4924,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4364
4924
|
#
|
4365
4925
|
errorCode = self.safe_string(response, 'code')
|
4366
4926
|
message = self.safe_string_2(response, 'msg', 'data', '')
|
4367
|
-
feedback = self.id + ' ' +
|
4927
|
+
feedback = self.id + ' ' + body
|
4368
4928
|
self.throw_exactly_matched_exception(self.exceptions['exact'], message, feedback)
|
4369
4929
|
self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
|
4370
4930
|
self.throw_broadly_matched_exception(self.exceptions['broad'], body, feedback)
|