ccxt 4.2.76__py2.py3-none-any.whl → 4.4.48__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +36 -14
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +112 -48
- ccxt/abstract/binancecoinm.py +112 -48
- ccxt/abstract/binanceus.py +147 -83
- ccxt/abstract/binanceusdm.py +112 -48
- ccxt/abstract/bingx.py +133 -78
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitfinex1.py +69 -0
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +8 -1
- ccxt/abstract/bitmart.py +13 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitpanda.py +0 -12
- ccxt/abstract/bitrue.py +3 -3
- ccxt/abstract/bitstamp.py +26 -3
- ccxt/abstract/blofin.py +24 -0
- ccxt/abstract/btcbox.py +1 -0
- ccxt/abstract/bybit.py +29 -14
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbase.py +6 -0
- ccxt/abstract/coinbaseadvanced.py +94 -0
- ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/coincatch.py +94 -0
- ccxt/abstract/coinex.py +233 -123
- ccxt/abstract/coinmetro.py +1 -0
- ccxt/abstract/cryptocom.py +14 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/gate.py +20 -0
- ccxt/abstract/gateio.py +20 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hashkey.py +67 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +4 -3
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +25 -0
- ccxt/abstract/kucoinfutures.py +35 -0
- ccxt/abstract/luno.py +2 -0
- ccxt/abstract/mexc.py +4 -0
- ccxt/abstract/myokx.py +340 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +30 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/oxfun.py +34 -0
- ccxt/abstract/paradex.py +40 -0
- ccxt/abstract/phemex.py +1 -0
- ccxt/abstract/upbit.py +4 -0
- ccxt/abstract/vertex.py +19 -0
- ccxt/abstract/whitebit.py +31 -1
- ccxt/abstract/woo.py +6 -2
- ccxt/abstract/woofipro.py +119 -0
- ccxt/abstract/xt.py +153 -0
- ccxt/abstract/zonda.py +6 -0
- ccxt/ace.py +164 -60
- ccxt/alpaca.py +727 -63
- ccxt/ascendex.py +395 -249
- ccxt/async_support/__init__.py +36 -14
- ccxt/async_support/ace.py +164 -60
- ccxt/async_support/alpaca.py +727 -63
- ccxt/async_support/ascendex.py +396 -249
- ccxt/async_support/base/exchange.py +531 -155
- ccxt/async_support/base/ws/aiohttp_client.py +28 -5
- ccxt/async_support/base/ws/cache.py +3 -2
- ccxt/async_support/base/ws/client.py +26 -5
- ccxt/async_support/base/ws/fast_client.py +4 -3
- ccxt/async_support/base/ws/functions.py +1 -1
- ccxt/async_support/base/ws/future.py +40 -31
- ccxt/async_support/base/ws/order_book_side.py +3 -0
- ccxt/async_support/bequant.py +1 -1
- ccxt/async_support/bigone.py +329 -202
- ccxt/async_support/binance.py +3513 -1511
- ccxt/async_support/binancecoinm.py +2 -1
- ccxt/async_support/binanceus.py +12 -1
- ccxt/async_support/binanceusdm.py +3 -1
- ccxt/async_support/bingx.py +3105 -881
- ccxt/async_support/bit2c.py +119 -38
- ccxt/async_support/bitbank.py +215 -76
- ccxt/async_support/bitbns.py +124 -53
- ccxt/async_support/bitfinex.py +3236 -1078
- ccxt/async_support/bitfinex1.py +1711 -0
- ccxt/async_support/bitflyer.py +239 -50
- ccxt/async_support/bitget.py +1513 -563
- ccxt/async_support/bithumb.py +201 -67
- ccxt/async_support/bitmart.py +1320 -435
- ccxt/async_support/bitmex.py +308 -111
- ccxt/async_support/bitopro.py +256 -96
- ccxt/async_support/bitrue.py +365 -233
- ccxt/async_support/bitso.py +201 -89
- ccxt/async_support/bitstamp.py +438 -269
- ccxt/async_support/bitteam.py +179 -73
- ccxt/async_support/bitvavo.py +180 -70
- ccxt/async_support/bl3p.py +92 -25
- ccxt/async_support/blockchaincom.py +193 -79
- ccxt/async_support/blofin.py +403 -150
- ccxt/async_support/btcalpha.py +161 -55
- ccxt/async_support/btcbox.py +250 -34
- ccxt/async_support/btcmarkets.py +232 -85
- ccxt/async_support/btcturk.py +159 -60
- ccxt/async_support/bybit.py +2326 -1255
- ccxt/async_support/cex.py +1409 -1329
- ccxt/async_support/coinbase.py +1455 -288
- ccxt/async_support/coinbaseadvanced.py +17 -0
- ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/async_support/coinbaseinternational.py +428 -88
- ccxt/async_support/coincatch.py +5152 -0
- ccxt/async_support/coincheck.py +121 -38
- ccxt/async_support/coinex.py +4020 -3339
- ccxt/async_support/coinlist.py +273 -116
- ccxt/async_support/coinmate.py +204 -97
- ccxt/async_support/coinmetro.py +203 -110
- ccxt/async_support/coinone.py +142 -68
- ccxt/async_support/coinsph.py +206 -89
- ccxt/async_support/coinspot.py +137 -62
- ccxt/async_support/cryptocom.py +515 -185
- ccxt/async_support/currencycom.py +203 -85
- ccxt/async_support/defx.py +2066 -0
- ccxt/async_support/delta.py +467 -158
- ccxt/async_support/deribit.py +558 -324
- ccxt/async_support/digifinex.py +340 -223
- ccxt/async_support/ellipx.py +1826 -0
- ccxt/async_support/exmo.py +259 -128
- ccxt/async_support/gate.py +1473 -464
- ccxt/async_support/gemini.py +206 -84
- ccxt/async_support/hashkey.py +4164 -0
- ccxt/async_support/hitbtc.py +334 -178
- ccxt/async_support/hollaex.py +134 -83
- ccxt/async_support/htx.py +1095 -563
- ccxt/async_support/huobijp.py +105 -56
- ccxt/async_support/hyperliquid.py +1634 -269
- ccxt/async_support/idex.py +148 -95
- ccxt/async_support/independentreserve.py +236 -31
- ccxt/async_support/indodax.py +165 -62
- ccxt/async_support/kraken.py +871 -354
- ccxt/async_support/krakenfutures.py +324 -100
- ccxt/async_support/kucoin.py +1050 -355
- ccxt/async_support/kucoinfutures.py +1004 -149
- ccxt/async_support/kuna.py +138 -106
- ccxt/async_support/latoken.py +135 -79
- ccxt/async_support/lbank.py +290 -113
- ccxt/async_support/luno.py +112 -62
- ccxt/async_support/lykke.py +104 -55
- ccxt/async_support/mercado.py +36 -29
- ccxt/async_support/mexc.py +995 -429
- ccxt/async_support/myokx.py +43 -0
- ccxt/async_support/ndax.py +163 -82
- ccxt/async_support/novadax.py +121 -75
- ccxt/async_support/oceanex.py +175 -59
- ccxt/async_support/okcoin.py +222 -163
- ccxt/async_support/okx.py +1777 -455
- ccxt/async_support/onetrading.py +132 -414
- ccxt/async_support/oxfun.py +2832 -0
- ccxt/async_support/p2b.py +79 -51
- ccxt/async_support/paradex.py +2017 -0
- ccxt/async_support/paymium.py +56 -32
- ccxt/async_support/phemex.py +572 -196
- ccxt/async_support/poloniex.py +218 -95
- ccxt/async_support/poloniexfutures.py +260 -92
- ccxt/async_support/probit.py +143 -110
- ccxt/async_support/timex.py +123 -70
- ccxt/async_support/tokocrypto.py +129 -93
- ccxt/async_support/tradeogre.py +39 -25
- ccxt/async_support/upbit.py +322 -113
- ccxt/async_support/vertex.py +2983 -0
- ccxt/async_support/wavesexchange.py +227 -173
- ccxt/async_support/wazirx.py +145 -65
- ccxt/async_support/whitebit.py +533 -138
- ccxt/async_support/woo.py +1155 -295
- ccxt/async_support/woofipro.py +2716 -0
- ccxt/async_support/xt.py +4628 -0
- ccxt/async_support/yobit.py +160 -92
- ccxt/async_support/zaif.py +80 -33
- ccxt/async_support/zonda.py +140 -69
- ccxt/base/errors.py +51 -20
- ccxt/base/exchange.py +1729 -482
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +223 -4
- ccxt/bequant.py +1 -1
- ccxt/bigone.py +329 -202
- ccxt/binance.py +3513 -1511
- ccxt/binancecoinm.py +2 -1
- ccxt/binanceus.py +12 -1
- ccxt/binanceusdm.py +3 -1
- ccxt/bingx.py +3105 -881
- ccxt/bit2c.py +119 -38
- ccxt/bitbank.py +215 -76
- ccxt/bitbns.py +124 -53
- ccxt/bitfinex.py +3235 -1078
- ccxt/bitfinex1.py +1710 -0
- ccxt/bitflyer.py +239 -50
- ccxt/bitget.py +1513 -563
- ccxt/bithumb.py +200 -67
- ccxt/bitmart.py +1320 -435
- ccxt/bitmex.py +308 -111
- ccxt/bitopro.py +256 -96
- ccxt/bitrue.py +365 -233
- ccxt/bitso.py +201 -89
- ccxt/bitstamp.py +438 -269
- ccxt/bitteam.py +179 -73
- ccxt/bitvavo.py +180 -70
- ccxt/bl3p.py +92 -25
- ccxt/blockchaincom.py +193 -79
- ccxt/blofin.py +403 -150
- ccxt/btcalpha.py +161 -55
- ccxt/btcbox.py +250 -34
- ccxt/btcmarkets.py +232 -85
- ccxt/btcturk.py +159 -60
- ccxt/bybit.py +2326 -1255
- ccxt/cex.py +1408 -1329
- ccxt/coinbase.py +1455 -288
- ccxt/coinbaseadvanced.py +17 -0
- ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/coinbaseinternational.py +428 -88
- ccxt/coincatch.py +5152 -0
- ccxt/coincheck.py +121 -38
- ccxt/coinex.py +4020 -3339
- ccxt/coinlist.py +273 -116
- ccxt/coinmate.py +204 -97
- ccxt/coinmetro.py +203 -110
- ccxt/coinone.py +142 -68
- ccxt/coinsph.py +206 -89
- ccxt/coinspot.py +137 -62
- ccxt/cryptocom.py +515 -185
- ccxt/currencycom.py +203 -85
- ccxt/defx.py +2065 -0
- ccxt/delta.py +467 -158
- ccxt/deribit.py +558 -324
- ccxt/digifinex.py +340 -223
- ccxt/ellipx.py +1826 -0
- ccxt/exmo.py +259 -128
- ccxt/gate.py +1473 -464
- ccxt/gemini.py +206 -84
- ccxt/hashkey.py +4164 -0
- ccxt/hitbtc.py +334 -178
- ccxt/hollaex.py +134 -83
- ccxt/htx.py +1095 -563
- ccxt/huobijp.py +105 -56
- ccxt/hyperliquid.py +1633 -269
- ccxt/idex.py +148 -95
- ccxt/independentreserve.py +235 -31
- ccxt/indodax.py +165 -62
- ccxt/kraken.py +871 -354
- ccxt/krakenfutures.py +324 -100
- ccxt/kucoin.py +1050 -355
- ccxt/kucoinfutures.py +1004 -149
- ccxt/kuna.py +138 -106
- ccxt/latoken.py +135 -79
- ccxt/lbank.py +290 -113
- ccxt/luno.py +112 -62
- ccxt/lykke.py +104 -55
- ccxt/mercado.py +36 -29
- ccxt/mexc.py +994 -429
- ccxt/myokx.py +43 -0
- ccxt/ndax.py +163 -82
- ccxt/novadax.py +121 -75
- ccxt/oceanex.py +175 -59
- ccxt/okcoin.py +222 -163
- ccxt/okx.py +1777 -455
- ccxt/onetrading.py +132 -414
- ccxt/oxfun.py +2831 -0
- ccxt/p2b.py +79 -51
- ccxt/paradex.py +2017 -0
- ccxt/paymium.py +56 -32
- ccxt/phemex.py +572 -196
- ccxt/poloniex.py +218 -95
- ccxt/poloniexfutures.py +260 -92
- ccxt/pro/__init__.py +29 -5
- ccxt/pro/alpaca.py +32 -17
- ccxt/pro/ascendex.py +63 -15
- ccxt/pro/bequant.py +4 -0
- ccxt/pro/binance.py +1596 -329
- ccxt/pro/binancecoinm.py +1 -0
- ccxt/pro/binanceus.py +2 -9
- ccxt/pro/binanceusdm.py +2 -0
- ccxt/pro/bingx.py +527 -134
- ccxt/pro/bitcoincom.py +4 -1
- ccxt/pro/bitfinex.py +731 -266
- ccxt/pro/bitfinex1.py +635 -0
- ccxt/pro/bitget.py +726 -357
- ccxt/pro/bithumb.py +380 -0
- ccxt/pro/bitmart.py +138 -39
- ccxt/pro/bitmex.py +199 -40
- ccxt/pro/bitopro.py +25 -13
- ccxt/pro/bitrue.py +31 -32
- ccxt/pro/bitstamp.py +7 -6
- ccxt/pro/bitvavo.py +204 -82
- ccxt/pro/blockchaincom.py +30 -17
- ccxt/pro/blofin.py +692 -0
- ccxt/pro/bybit.py +791 -82
- ccxt/pro/cex.py +99 -51
- ccxt/pro/coinbase.py +220 -30
- ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
- ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
- ccxt/pro/coinbaseinternational.py +193 -30
- ccxt/pro/coincatch.py +1464 -0
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +967 -661
- ccxt/pro/coinone.py +17 -10
- ccxt/pro/cryptocom.py +446 -66
- ccxt/pro/currencycom.py +11 -10
- ccxt/pro/defx.py +832 -0
- ccxt/pro/deribit.py +168 -32
- ccxt/pro/exmo.py +253 -21
- ccxt/pro/gate.py +729 -64
- ccxt/pro/gemini.py +44 -26
- ccxt/pro/hashkey.py +802 -0
- ccxt/pro/hitbtc.py +208 -103
- ccxt/pro/hollaex.py +25 -9
- ccxt/pro/htx.py +83 -39
- ccxt/pro/huobijp.py +17 -16
- ccxt/pro/hyperliquid.py +502 -31
- ccxt/pro/idex.py +28 -13
- ccxt/pro/independentreserve.py +21 -16
- ccxt/pro/kraken.py +298 -51
- ccxt/pro/krakenfutures.py +166 -75
- ccxt/pro/kucoin.py +395 -77
- ccxt/pro/kucoinfutures.py +400 -99
- ccxt/pro/lbank.py +52 -31
- ccxt/pro/luno.py +12 -10
- ccxt/pro/mexc.py +400 -50
- ccxt/pro/myokx.py +28 -0
- ccxt/pro/ndax.py +25 -12
- ccxt/pro/okcoin.py +28 -9
- ccxt/pro/okx.py +935 -124
- ccxt/pro/onetrading.py +41 -24
- ccxt/pro/oxfun.py +1054 -0
- ccxt/pro/p2b.py +100 -24
- ccxt/pro/paradex.py +352 -0
- ccxt/pro/phemex.py +93 -34
- ccxt/pro/poloniex.py +129 -50
- ccxt/pro/poloniexfutures.py +53 -32
- ccxt/pro/probit.py +93 -86
- ccxt/pro/upbit.py +401 -8
- ccxt/pro/vertex.py +943 -0
- ccxt/pro/wazirx.py +46 -28
- ccxt/pro/whitebit.py +65 -12
- ccxt/pro/woo.py +486 -70
- ccxt/pro/woofipro.py +1271 -0
- ccxt/pro/xt.py +1067 -0
- ccxt/probit.py +143 -110
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/__init__.py +38 -0
- ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
- ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
- ccxt/static_dependencies/lark/ast_utils.py +59 -0
- ccxt/static_dependencies/lark/common.py +86 -0
- ccxt/static_dependencies/lark/exceptions.py +292 -0
- ccxt/static_dependencies/lark/grammar.py +130 -0
- ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
- ccxt/static_dependencies/lark/indenter.py +143 -0
- ccxt/static_dependencies/lark/lark.py +658 -0
- ccxt/static_dependencies/lark/lexer.py +678 -0
- ccxt/static_dependencies/lark/load_grammar.py +1428 -0
- ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
- ccxt/static_dependencies/lark/parser_frontends.py +257 -0
- ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
- ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
- ccxt/static_dependencies/lark/parsers/earley.py +314 -0
- ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
- ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
- ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
- ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
- ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
- ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/lark/reconstruct.py +107 -0
- ccxt/static_dependencies/lark/tools/__init__.py +70 -0
- ccxt/static_dependencies/lark/tools/nearley.py +202 -0
- ccxt/static_dependencies/lark/tools/serialize.py +32 -0
- ccxt/static_dependencies/lark/tools/standalone.py +196 -0
- ccxt/static_dependencies/lark/tree.py +267 -0
- ccxt/static_dependencies/lark/tree_matcher.py +186 -0
- ccxt/static_dependencies/lark/tree_templates.py +180 -0
- ccxt/static_dependencies/lark/utils.py +343 -0
- ccxt/static_dependencies/lark/visitors.py +596 -0
- ccxt/static_dependencies/marshmallow/__init__.py +81 -0
- ccxt/static_dependencies/marshmallow/base.py +65 -0
- ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
- ccxt/static_dependencies/marshmallow/decorators.py +231 -0
- ccxt/static_dependencies/marshmallow/error_store.py +60 -0
- ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
- ccxt/static_dependencies/marshmallow/fields.py +2114 -0
- ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/schema.py +1228 -0
- ccxt/static_dependencies/marshmallow/types.py +12 -0
- ccxt/static_dependencies/marshmallow/utils.py +378 -0
- ccxt/static_dependencies/marshmallow/validate.py +678 -0
- ccxt/static_dependencies/marshmallow/warnings.py +2 -0
- ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
- ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
- ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
- ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
- ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
- ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
- ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/static_dependencies/starknet/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
- ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
- ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
- ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
- ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
- ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
- ccxt/static_dependencies/starknet/common.py +15 -0
- ccxt/static_dependencies/starknet/constants.py +39 -0
- ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
- ccxt/static_dependencies/starknet/hash/address.py +79 -0
- ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
- ccxt/static_dependencies/starknet/hash/selector.py +16 -0
- ccxt/static_dependencies/starknet/hash/storage.py +12 -0
- ccxt/static_dependencies/starknet/hash/utils.py +78 -0
- ccxt/static_dependencies/starknet/models/__init__.py +0 -0
- ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
- ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
- ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
- ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
- ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
- ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
- ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
- ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
- ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
- ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
- ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
- ccxt/static_dependencies/starknet/utils/schema.py +13 -0
- ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
- ccxt/static_dependencies/starkware/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
- ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
- ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
- ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
- ccxt/static_dependencies/sympy/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
- ccxt/static_dependencies/sympy/external/__init__.py +0 -0
- ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
- ccxt/static_dependencies/sympy/external/importtools.py +187 -0
- ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
- ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
- ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
- ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
- ccxt/test/{test_async.py → tests_async.py} +465 -407
- ccxt/test/tests_helpers.py +285 -0
- ccxt/test/tests_init.py +39 -0
- ccxt/test/{test_sync.py → tests_sync.py} +465 -409
- ccxt/timex.py +123 -70
- ccxt/tokocrypto.py +129 -93
- ccxt/tradeogre.py +39 -25
- ccxt/upbit.py +322 -113
- ccxt/vertex.py +2983 -0
- ccxt/wavesexchange.py +227 -173
- ccxt/wazirx.py +145 -65
- ccxt/whitebit.py +533 -138
- ccxt/woo.py +1155 -295
- ccxt/woofipro.py +2716 -0
- ccxt/xt.py +4627 -0
- ccxt/yobit.py +159 -92
- ccxt/zaif.py +80 -33
- ccxt/zonda.py +140 -69
- ccxt-4.4.48.dist-info/LICENSE.txt +21 -0
- ccxt-4.4.48.dist-info/METADATA +646 -0
- ccxt-4.4.48.dist-info/RECORD +669 -0
- {ccxt-4.2.76.dist-info → ccxt-4.4.48.dist-info}/WHEEL +1 -1
- ccxt/abstract/bitbay.py +0 -47
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3496
- ccxt/async_support/flowbtc.py +0 -34
- ccxt/bitbay.py +0 -17
- ccxt/bitfinex2.py +0 -3496
- ccxt/flowbtc.py +0 -34
- ccxt/hitbtc3.py +0 -16
- ccxt/pro/bitfinex2.py +0 -1081
- ccxt/test/base/__init__.py +0 -28
- ccxt/test/base/test_account.py +0 -26
- ccxt/test/base/test_balance.py +0 -56
- ccxt/test/base/test_borrow_interest.py +0 -35
- ccxt/test/base/test_borrow_rate.py +0 -32
- ccxt/test/base/test_calculate_fee.py +0 -51
- ccxt/test/base/test_crypto.py +0 -127
- ccxt/test/base/test_currency.py +0 -76
- ccxt/test/base/test_datetime.py +0 -103
- ccxt/test/base/test_decimal_to_precision.py +0 -392
- ccxt/test/base/test_deep_extend.py +0 -68
- ccxt/test/base/test_deposit_withdrawal.py +0 -50
- ccxt/test/base/test_exchange_datetime_functions.py +0 -76
- ccxt/test/base/test_funding_rate_history.py +0 -29
- ccxt/test/base/test_last_price.py +0 -32
- ccxt/test/base/test_ledger_entry.py +0 -45
- ccxt/test/base/test_ledger_item.py +0 -48
- ccxt/test/base/test_leverage_tier.py +0 -33
- ccxt/test/base/test_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -190
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -32
- ccxt/test/base/test_open_interest.py +0 -32
- ccxt/test/base/test_order.py +0 -64
- ccxt/test/base/test_order_book.py +0 -63
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -345
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -86
- ccxt/test/base/test_trade.py +0 -47
- ccxt/test/base/test_trading_fee.py +0 -26
- ccxt/test/base/test_transaction.py +0 -39
- ccxt-4.2.76.dist-info/METADATA +0 -626
- ccxt-4.2.76.dist-info/RECORD +0 -534
- {ccxt-4.2.76.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
ccxt/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
|
|
@@ -71,13 +72,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
71
72
|
'fetchAccounts': True,
|
72
73
|
'fetchBalance': True,
|
73
74
|
'fetchBorrowInterest': True,
|
74
|
-
'fetchBorrowRateHistories':
|
75
|
-
'fetchBorrowRateHistory':
|
75
|
+
'fetchBorrowRateHistories': True,
|
76
|
+
'fetchBorrowRateHistory': True,
|
76
77
|
'fetchClosedOrders': True,
|
77
78
|
'fetchCrossBorrowRate': False,
|
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,15 +255,20 @@ 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
|
262
|
+
'margin/interest': 20, # 20SW
|
249
263
|
'project/list': 10, # 10SW
|
250
264
|
'project/marketInterestRate': 7.5, # 5PW
|
251
265
|
'redeem/orders': 10, # 10SW
|
252
266
|
'purchase/orders': 10, # 10SW
|
253
267
|
# broker
|
254
268
|
'broker/api/rebase/download': 3,
|
269
|
+
'migrate/user/account/status': 3,
|
270
|
+
# affiliate
|
271
|
+
'affiliate/inviter/statistics': 30,
|
255
272
|
},
|
256
273
|
'post': {
|
257
274
|
# account
|
@@ -291,6 +308,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
291
308
|
'lend/purchase/update': 10, # 10SW
|
292
309
|
# ws
|
293
310
|
'bullet-private': 10, # 10SW
|
311
|
+
'position/update-user-leverage': 5,
|
312
|
+
'deposit-address/create': 20,
|
294
313
|
},
|
295
314
|
'delete': {
|
296
315
|
# account
|
@@ -403,6 +422,10 @@ class kucoin(Exchange, ImplicitAPI):
|
|
403
422
|
'broker/nd/account': 2,
|
404
423
|
'broker/nd/account/apikey': 2,
|
405
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,
|
406
429
|
},
|
407
430
|
'post': {
|
408
431
|
'broker/nd/transfer': 1,
|
@@ -414,6 +437,25 @@ class kucoin(Exchange, ImplicitAPI):
|
|
414
437
|
'broker/nd/account/apikey': 3,
|
415
438
|
},
|
416
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
|
+
},
|
417
459
|
},
|
418
460
|
'timeframes': {
|
419
461
|
'1m': '1min',
|
@@ -434,6 +476,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
434
476
|
'precisionMode': TICK_SIZE,
|
435
477
|
'exceptions': {
|
436
478
|
'exact': {
|
479
|
+
'The order does not exist.': OrderNotFound,
|
437
480
|
'order not exist': OrderNotFound,
|
438
481
|
'order not exist.': OrderNotFound, # duplicated error temporarily
|
439
482
|
'order_not_exist': OrderNotFound, # {"code":"order_not_exist","msg":"order_not_exist"} ¯\_(ツ)_/¯
|
@@ -441,6 +484,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
441
484
|
'Order size below the minimum requirement.': InvalidOrder, # {"code":"400100","msg":"Order size below the minimum requirement."}
|
442
485
|
'The withdrawal amount is below the minimum requirement.': ExchangeError, # {"code":"400100","msg":"The withdrawal amount is below the minimum requirement."}
|
443
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"}
|
444
489
|
'400': BadRequest,
|
445
490
|
'401': AuthenticationError,
|
446
491
|
'403': NotSupported,
|
@@ -464,6 +509,56 @@ class kucoin(Exchange, ImplicitAPI):
|
|
464
509
|
'130202': ExchangeError, # The system is renewing the loan automatically. Please try again later
|
465
510
|
'130203': InsufficientFunds, # Insufficient account balance
|
466
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
|
467
562
|
'200004': InsufficientFunds,
|
468
563
|
'210014': InvalidOrder, # {"code":"210014","msg":"Exceeds the max. borrowing amount, the remaining amount you can borrow: 0USDT"}
|
469
564
|
'210021': InsufficientFunds, # {"code":"210021","msg":"Balance not enough"}
|
@@ -480,20 +575,25 @@ class kucoin(Exchange, ImplicitAPI):
|
|
480
575
|
'400006': AuthenticationError,
|
481
576
|
'400007': AuthenticationError,
|
482
577
|
'400008': NotSupported,
|
483
|
-
'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"}
|
484
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"}
|
485
581
|
'400350': InvalidOrder, # {"code":"400350","msg":"Upper limit for holding: 10,000USDT, you can still buy 10,000USDT worth of coin."}
|
486
582
|
'400370': InvalidOrder, # {"code":"400370","msg":"Max. price: 0.02500000000000000000"}
|
487
583
|
'400400': BadRequest, # Parameter error
|
584
|
+
'400401': AuthenticationError, # User is not logged in
|
488
585
|
'400500': InvalidOrder, # {"code":"400500","msg":"Your located country/region is currently not supported for the trading of self token"}
|
489
586
|
'400600': BadSymbol, # {"code":"400600","msg":"validation.createOrder.symbolNotAvailable"}
|
490
587
|
'400760': InvalidOrder, # {"code":"400760","msg":"order price should be more than XX"}
|
491
588
|
'401000': BadRequest, # {"code":"401000","msg":"The interface has been deprecated"}
|
589
|
+
'408000': BadRequest, # Network timeout, please try again later
|
492
590
|
'411100': AccountSuspended,
|
493
591
|
'415000': BadRequest, # {"code":"415000","msg":"Unsupported Media Type"}
|
494
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"}
|
495
593
|
'500000': ExchangeNotAvailable, # {"code":"500000","msg":"Internal Server Error"}
|
496
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"}
|
497
597
|
'900014': BadRequest, # {"code":"900014","msg":"Invalid chainId"}
|
498
598
|
},
|
499
599
|
'broad': {
|
@@ -551,11 +651,17 @@ class kucoin(Exchange, ImplicitAPI):
|
|
551
651
|
'BIFI': 'BIFIF',
|
552
652
|
'VAI': 'VAIOT',
|
553
653
|
'WAX': 'WAXP',
|
654
|
+
'ALT': 'APTOSLAUNCHTOKEN',
|
655
|
+
'KALT': 'ALT', # ALTLAYER
|
656
|
+
'FUD': 'FTX Users\' Debt',
|
554
657
|
},
|
555
658
|
'options': {
|
659
|
+
'hf': None, # would be auto set to `true/false` after first load
|
556
660
|
'version': 'v1',
|
557
661
|
'symbolSeparator': '-',
|
558
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
|
559
665
|
'fetchCurrencies': {
|
560
666
|
'webApiEnable': True, # fetches from WEB
|
561
667
|
'webApiRetries': 1,
|
@@ -575,6 +681,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
575
681
|
'currencies': 'v3',
|
576
682
|
'currencies/{currency}': 'v3',
|
577
683
|
'symbols': 'v2',
|
684
|
+
'mark-price/all-symbols': 'v3',
|
685
|
+
'announcements': 'v3',
|
578
686
|
},
|
579
687
|
},
|
580
688
|
'private': {
|
@@ -599,6 +707,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
599
707
|
'oco/orders': 'v3',
|
600
708
|
# margin trading
|
601
709
|
'hf/margin/orders/active': 'v3',
|
710
|
+
'hf/margin/order/active/symbols': 'v3',
|
602
711
|
'hf/margin/orders/done': 'v3',
|
603
712
|
'hf/margin/orders/{orderId}': 'v3',
|
604
713
|
'hf/margin/orders/client-order/{clientOid}': 'v3',
|
@@ -607,10 +716,15 @@ class kucoin(Exchange, ImplicitAPI):
|
|
607
716
|
'margin/currencies': 'v3',
|
608
717
|
'margin/borrow': 'v3',
|
609
718
|
'margin/repay': 'v3',
|
719
|
+
'margin/interest': 'v3',
|
610
720
|
'project/list': 'v3',
|
611
721
|
'project/marketInterestRate': 'v3',
|
612
722
|
'redeem/orders': 'v3',
|
613
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',
|
614
728
|
},
|
615
729
|
'POST': {
|
616
730
|
# account
|
@@ -620,6 +734,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
620
734
|
'accounts/sub-transfer': 'v2',
|
621
735
|
'accounts/inner-transfer': 'v2',
|
622
736
|
'transfer-out': 'v3',
|
737
|
+
'deposit-address/create': 'v3',
|
623
738
|
# spot trading
|
624
739
|
'oco/order': 'v3',
|
625
740
|
# margin trading
|
@@ -630,6 +745,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
630
745
|
'purchase': 'v3',
|
631
746
|
'redeem': 'v3',
|
632
747
|
'lend/purchase/update': 'v3',
|
748
|
+
'position/update-user-leverage': 'v3',
|
749
|
+
'withdrawals': 'v3',
|
633
750
|
},
|
634
751
|
'DELETE': {
|
635
752
|
# account
|
@@ -677,7 +794,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
677
794
|
'hf': 'trade_hf',
|
678
795
|
},
|
679
796
|
'networks': {
|
680
|
-
'
|
797
|
+
'BRC20': 'btc',
|
681
798
|
'BTCNATIVESEGWIT': 'bech32',
|
682
799
|
'ERC20': 'eth',
|
683
800
|
'TRC20': 'trx',
|
@@ -695,7 +812,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
695
812
|
'TLOS': 'tlos', # tlosevm is different
|
696
813
|
'CFX': 'cfx',
|
697
814
|
'ACA': 'aca',
|
698
|
-
'
|
815
|
+
'OP': 'optimism',
|
699
816
|
'ONT': 'ont',
|
700
817
|
'GLMR': 'glmr',
|
701
818
|
'CSPR': 'cspr',
|
@@ -814,6 +931,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
814
931
|
'TRUE': 'true',
|
815
932
|
'CS': 'cs',
|
816
933
|
'ORAI': 'orai',
|
934
|
+
'BASE': 'base',
|
817
935
|
# below will be uncommented after consensus
|
818
936
|
# 'BITCOINDIAMON': 'bcd',
|
819
937
|
# 'BITCOINGOLD': 'btg',
|
@@ -889,15 +1007,85 @@ class kucoin(Exchange, ImplicitAPI):
|
|
889
1007
|
'spot': 'TRADE',
|
890
1008
|
},
|
891
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
|
+
},
|
892
1078
|
})
|
893
1079
|
|
894
1080
|
def nonce(self):
|
895
|
-
return self.milliseconds()
|
1081
|
+
return self.milliseconds() - self.options['timeDifference']
|
896
1082
|
|
897
1083
|
async def fetch_time(self, params={}):
|
898
1084
|
"""
|
899
1085
|
fetches the current integer timestamp in milliseconds from the exchange server
|
900
|
-
|
1086
|
+
|
1087
|
+
https://docs.kucoin.com/#server-time
|
1088
|
+
|
901
1089
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
902
1090
|
:returns int: the current integer timestamp in milliseconds from the exchange server
|
903
1091
|
"""
|
@@ -914,7 +1102,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
914
1102
|
async def fetch_status(self, params={}):
|
915
1103
|
"""
|
916
1104
|
the latest known information on the availability of the exchange API
|
917
|
-
|
1105
|
+
|
1106
|
+
https://docs.kucoin.com/#service-status
|
1107
|
+
|
918
1108
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
919
1109
|
:returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
|
920
1110
|
"""
|
@@ -938,15 +1128,20 @@ class kucoin(Exchange, ImplicitAPI):
|
|
938
1128
|
'info': response,
|
939
1129
|
}
|
940
1130
|
|
941
|
-
async def fetch_markets(self, params={}):
|
1131
|
+
async def fetch_markets(self, params={}) -> List[Market]:
|
942
1132
|
"""
|
943
1133
|
retrieves data on all markets for kucoin
|
944
|
-
|
945
|
-
|
1134
|
+
|
1135
|
+
https://docs.kucoin.com/#get-symbols-list-deprecated
|
1136
|
+
https://docs.kucoin.com/#get-all-tickers
|
1137
|
+
|
946
1138
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
947
1139
|
:returns dict[]: an array of objects representing market data
|
948
1140
|
"""
|
949
|
-
|
1141
|
+
fetchTickersFees = None
|
1142
|
+
fetchTickersFees, params = self.handle_option_and_params(params, 'fetchMarkets', 'fetchTickersFees', True)
|
1143
|
+
promises = []
|
1144
|
+
promises.append(self.publicGetSymbols(params))
|
950
1145
|
#
|
951
1146
|
# {
|
952
1147
|
# "code": "200000",
|
@@ -969,59 +1164,102 @@ class kucoin(Exchange, ImplicitAPI):
|
|
969
1164
|
# "isMarginEnabled": True,
|
970
1165
|
# "enableTrading": True
|
971
1166
|
# },
|
972
|
-
# ]
|
973
|
-
# }
|
974
1167
|
#
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
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
|
+
#
|
979
1205
|
if fetchTickersFees:
|
980
|
-
|
981
|
-
|
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
|
-
|
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')
|
1012
1247
|
result = []
|
1013
|
-
for i in range(0, len(
|
1014
|
-
market =
|
1248
|
+
for i in range(0, len(symbolsData)):
|
1249
|
+
market = symbolsData[i]
|
1015
1250
|
id = self.safe_string(market, 'symbol')
|
1016
1251
|
baseId, quoteId = id.split('-')
|
1017
1252
|
base = self.safe_currency_code(baseId)
|
1018
1253
|
quote = self.safe_currency_code(quoteId)
|
1019
1254
|
# quoteIncrement = self.safe_number(market, 'quoteIncrement')
|
1020
|
-
ticker = self.safe_dict(
|
1255
|
+
ticker = self.safe_dict(tickersById, id, {})
|
1021
1256
|
makerFeeRate = self.safe_string(ticker, 'makerFeeRate')
|
1022
1257
|
takerFeeRate = self.safe_string(ticker, 'takerFeeRate')
|
1023
1258
|
makerCoefficient = self.safe_string(ticker, 'makerCoefficient')
|
1024
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
|
1025
1263
|
result.append({
|
1026
1264
|
'id': id,
|
1027
1265
|
'symbol': base + '/' + quote,
|
@@ -1033,7 +1271,11 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1033
1271
|
'settleId': None,
|
1034
1272
|
'type': 'spot',
|
1035
1273
|
'spot': True,
|
1036
|
-
'margin':
|
1274
|
+
'margin': isMarginable,
|
1275
|
+
'marginModes': {
|
1276
|
+
'cross': hasCrossMargin,
|
1277
|
+
'isolated': hasIsolatedMargin,
|
1278
|
+
},
|
1037
1279
|
'swap': False,
|
1038
1280
|
'future': False,
|
1039
1281
|
'option': False,
|
@@ -1073,12 +1315,40 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1073
1315
|
'created': None,
|
1074
1316
|
'info': market,
|
1075
1317
|
})
|
1318
|
+
if self.options['adjustForTimeDifference']:
|
1319
|
+
await self.load_time_difference()
|
1076
1320
|
return result
|
1077
1321
|
|
1078
|
-
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:
|
1079
1347
|
"""
|
1080
1348
|
fetches all available currencies on an exchange
|
1081
|
-
|
1349
|
+
|
1350
|
+
https://docs.kucoin.com/#get-currencies
|
1351
|
+
|
1082
1352
|
:param dict params: extra parameters specific to the exchange API endpoint
|
1083
1353
|
:returns dict: an associative dictionary of currencies
|
1084
1354
|
"""
|
@@ -1100,8 +1370,10 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1100
1370
|
# "chains":[
|
1101
1371
|
# {
|
1102
1372
|
# "chainName":"ERC20",
|
1103
|
-
# "
|
1373
|
+
# "chainId": "eth"
|
1104
1374
|
# "withdrawalMinSize":"2999",
|
1375
|
+
# "depositMinSize":null,
|
1376
|
+
# "withdrawFeeRate":"0",
|
1105
1377
|
# "withdrawalMinFee":"2999",
|
1106
1378
|
# "isWithdrawEnabled":false,
|
1107
1379
|
# "isDepositEnabled":false,
|
@@ -1150,12 +1422,12 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1150
1422
|
# }
|
1151
1423
|
#
|
1152
1424
|
responses = await asyncio.gather(*promises)
|
1153
|
-
currenciesResponse = self.
|
1154
|
-
currenciesData = self.
|
1155
|
-
additionalResponse = self.
|
1156
|
-
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', [])
|
1157
1429
|
additionalDataGrouped = self.group_by(additionalData, 'currency')
|
1158
|
-
result = {}
|
1430
|
+
result: dict = {}
|
1159
1431
|
for i in range(0, len(currenciesData)):
|
1160
1432
|
entry = currenciesData[i]
|
1161
1433
|
id = self.safe_string(entry, 'currency')
|
@@ -1163,9 +1435,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1163
1435
|
code = self.safe_currency_code(id)
|
1164
1436
|
isWithdrawEnabled = None
|
1165
1437
|
isDepositEnabled = None
|
1166
|
-
networks = {}
|
1438
|
+
networks: dict = {}
|
1167
1439
|
chains = self.safe_list(entry, 'chains', [])
|
1168
|
-
extraChainsData = self.index_by(self.
|
1440
|
+
extraChainsData = self.index_by(self.safe_list(additionalDataGrouped, id, []), 'chain')
|
1169
1441
|
rawPrecision = self.safe_string(entry, 'precision')
|
1170
1442
|
precision = self.parse_number(self.parse_precision(rawPrecision))
|
1171
1443
|
chainsLength = len(chains)
|
@@ -1176,7 +1448,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1176
1448
|
for j in range(0, chainsLength):
|
1177
1449
|
chain = chains[j]
|
1178
1450
|
chainId = self.safe_string(chain, 'chainId')
|
1179
|
-
networkCode = self.network_id_to_code(chainId)
|
1451
|
+
networkCode = self.network_id_to_code(chainId, code)
|
1180
1452
|
chainWithdrawEnabled = self.safe_bool(chain, 'isWithdrawEnabled', False)
|
1181
1453
|
if isWithdrawEnabled is None:
|
1182
1454
|
isWithdrawEnabled = chainWithdrawEnabled
|
@@ -1204,7 +1476,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1204
1476
|
'max': None,
|
1205
1477
|
},
|
1206
1478
|
'deposit': {
|
1207
|
-
'min': self.safe_number(
|
1479
|
+
'min': self.safe_number(chain, 'depositMinSize'),
|
1208
1480
|
'max': None,
|
1209
1481
|
},
|
1210
1482
|
},
|
@@ -1230,7 +1502,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1230
1502
|
async def fetch_accounts(self, params={}) -> List[Account]:
|
1231
1503
|
"""
|
1232
1504
|
fetch all the accounts associated with a profile
|
1233
|
-
|
1505
|
+
|
1506
|
+
https://docs.kucoin.com/#list-accounts
|
1507
|
+
|
1234
1508
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1235
1509
|
:returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
|
1236
1510
|
"""
|
@@ -1278,14 +1552,16 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1278
1552
|
async def fetch_transaction_fee(self, code: str, params={}):
|
1279
1553
|
"""
|
1280
1554
|
*DEPRECATED* please use fetchDepositWithdrawFee instead
|
1281
|
-
|
1555
|
+
|
1556
|
+
https://docs.kucoin.com/#get-withdrawal-quotas
|
1557
|
+
|
1282
1558
|
:param str code: unified currency code
|
1283
1559
|
:param dict params: extra parameters specific to the exchange API endpoint
|
1284
1560
|
:returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
|
1285
1561
|
"""
|
1286
1562
|
await self.load_markets()
|
1287
1563
|
currency = self.currency(code)
|
1288
|
-
request = {
|
1564
|
+
request: dict = {
|
1289
1565
|
'currency': currency['id'],
|
1290
1566
|
}
|
1291
1567
|
networkCode = None
|
@@ -1293,8 +1569,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1293
1569
|
if networkCode is not None:
|
1294
1570
|
request['chain'] = self.network_code_to_id(networkCode).lower()
|
1295
1571
|
response = await self.privateGetWithdrawalsQuotas(self.extend(request, params))
|
1296
|
-
data = self.
|
1297
|
-
withdrawFees = {}
|
1572
|
+
data = self.safe_dict(response, 'data', {})
|
1573
|
+
withdrawFees: dict = {}
|
1298
1574
|
withdrawFees[code] = self.safe_number(data, 'withdrawMinFee')
|
1299
1575
|
return {
|
1300
1576
|
'info': response,
|
@@ -1305,7 +1581,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1305
1581
|
async def fetch_deposit_withdraw_fee(self, code: str, params={}):
|
1306
1582
|
"""
|
1307
1583
|
fetch the fee for deposits and withdrawals
|
1308
|
-
|
1584
|
+
|
1585
|
+
https://docs.kucoin.com/#get-withdrawal-quotas
|
1586
|
+
|
1309
1587
|
:param str code: unified currency code
|
1310
1588
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1311
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
|
@@ -1313,7 +1591,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1313
1591
|
"""
|
1314
1592
|
await self.load_markets()
|
1315
1593
|
currency = self.currency(code)
|
1316
|
-
request = {
|
1594
|
+
request: dict = {
|
1317
1595
|
'currency': currency['id'],
|
1318
1596
|
}
|
1319
1597
|
networkCode = None
|
@@ -1358,32 +1636,28 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1358
1636
|
# "chain": "ERC20"
|
1359
1637
|
# }
|
1360
1638
|
#
|
1361
|
-
|
1639
|
+
minWithdrawFee = self.safe_number(fee, 'withdrawMinFee')
|
1640
|
+
result: dict = {
|
1362
1641
|
'info': fee,
|
1363
1642
|
'withdraw': {
|
1643
|
+
'fee': minWithdrawFee,
|
1644
|
+
'percentage': False,
|
1645
|
+
},
|
1646
|
+
'deposit': {
|
1364
1647
|
'fee': None,
|
1365
1648
|
'percentage': None,
|
1366
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,
|
1367
1656
|
'deposit': {
|
1368
1657
|
'fee': None,
|
1369
1658
|
'percentage': None,
|
1370
1659
|
},
|
1371
|
-
'networks': {},
|
1372
1660
|
}
|
1373
|
-
isWithdrawEnabled = self.safe_bool(fee, 'isWithdrawEnabled')
|
1374
|
-
if isWithdrawEnabled:
|
1375
|
-
result['withdraw']['fee'] = self.safe_number_2(fee, 'withdrawalMinFee', 'withdrawMinFee')
|
1376
|
-
result['withdraw']['percentage'] = False
|
1377
|
-
networkId = self.safe_string(fee, 'chain')
|
1378
|
-
if networkId:
|
1379
|
-
networkCode = self.network_id_to_code(networkId, self.safe_string(currency, 'code'))
|
1380
|
-
result['networks'][networkCode] = {
|
1381
|
-
'withdraw': result['withdraw'],
|
1382
|
-
'deposit': {
|
1383
|
-
'fee': None,
|
1384
|
-
'percentage': None,
|
1385
|
-
},
|
1386
|
-
}
|
1387
1661
|
return result
|
1388
1662
|
|
1389
1663
|
def is_futures_method(self, methodName, params):
|
@@ -1403,7 +1677,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1403
1677
|
params = self.omit(params, 'type')
|
1404
1678
|
return(type == 'contract') or (type == 'future') or (type == 'futures') # * (type == 'futures') deprecated, use(type == 'future')
|
1405
1679
|
|
1406
|
-
def parse_ticker(self, ticker, market: Market = None) -> Ticker:
|
1680
|
+
def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
|
1407
1681
|
#
|
1408
1682
|
# {
|
1409
1683
|
# "symbol": "BTC-USDT", # symbol
|
@@ -1469,7 +1743,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1469
1743
|
symbol = market['symbol']
|
1470
1744
|
baseVolume = self.safe_string(ticker, 'vol')
|
1471
1745
|
quoteVolume = self.safe_string(ticker, 'volValue')
|
1472
|
-
timestamp = self.
|
1746
|
+
timestamp = self.safe_integer_n(ticker, ['time', 'datetime', 'timePoint'])
|
1473
1747
|
return self.safe_ticker({
|
1474
1748
|
'symbol': symbol,
|
1475
1749
|
'timestamp': timestamp,
|
@@ -1490,13 +1764,16 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1490
1764
|
'average': self.safe_string(ticker, 'averagePrice'),
|
1491
1765
|
'baseVolume': baseVolume,
|
1492
1766
|
'quoteVolume': quoteVolume,
|
1767
|
+
'markPrice': self.safe_string(ticker, 'value'),
|
1493
1768
|
'info': ticker,
|
1494
1769
|
}, market)
|
1495
1770
|
|
1496
1771
|
async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
1497
1772
|
"""
|
1498
1773
|
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
1499
|
-
|
1774
|
+
|
1775
|
+
https://docs.kucoin.com/#get-all-tickers
|
1776
|
+
|
1500
1777
|
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
1501
1778
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1502
1779
|
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -1535,7 +1812,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1535
1812
|
data = self.safe_dict(response, 'data', {})
|
1536
1813
|
tickers = self.safe_list(data, 'ticker', [])
|
1537
1814
|
time = self.safe_integer(data, 'time')
|
1538
|
-
result = {}
|
1815
|
+
result: dict = {}
|
1539
1816
|
for i in range(0, len(tickers)):
|
1540
1817
|
tickers[i]['time'] = time
|
1541
1818
|
ticker = self.parse_ticker(tickers[i])
|
@@ -1544,17 +1821,35 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1544
1821
|
result[symbol] = ticker
|
1545
1822
|
return self.filter_by_array_tickers(result, 'symbol', symbols)
|
1546
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
|
+
|
1547
1840
|
async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
|
1548
1841
|
"""
|
1549
1842
|
fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
1550
|
-
|
1843
|
+
|
1844
|
+
https://docs.kucoin.com/#get-24hr-stats
|
1845
|
+
|
1551
1846
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
1552
1847
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1553
1848
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1554
1849
|
"""
|
1555
1850
|
await self.load_markets()
|
1556
1851
|
market = self.market(symbol)
|
1557
|
-
request = {
|
1852
|
+
request: dict = {
|
1558
1853
|
'symbol': market['id'],
|
1559
1854
|
}
|
1560
1855
|
response = await self.publicGetMarketStats(self.extend(request, params))
|
@@ -1581,7 +1876,28 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1581
1876
|
# }
|
1582
1877
|
# }
|
1583
1878
|
#
|
1584
|
-
|
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)
|
1585
1901
|
|
1586
1902
|
def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
|
1587
1903
|
#
|
@@ -1607,7 +1923,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1607
1923
|
async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
1608
1924
|
"""
|
1609
1925
|
fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
1610
|
-
|
1926
|
+
|
1927
|
+
https://docs.kucoin.com/#get-klines
|
1928
|
+
|
1611
1929
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
1612
1930
|
:param str timeframe: the length of time each candle represents
|
1613
1931
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
@@ -1623,7 +1941,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1623
1941
|
return await self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1500)
|
1624
1942
|
market = self.market(symbol)
|
1625
1943
|
marketId = market['id']
|
1626
|
-
request = {
|
1944
|
+
request: dict = {
|
1627
1945
|
'symbol': marketId,
|
1628
1946
|
'type': self.safe_string(self.timeframes, timeframe, timeframe),
|
1629
1947
|
}
|
@@ -1658,7 +1976,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1658
1976
|
|
1659
1977
|
async def create_deposit_address(self, code: str, params={}):
|
1660
1978
|
"""
|
1661
|
-
|
1979
|
+
|
1980
|
+
https://www.kucoin.com/docs/rest/funding/deposit/create-deposit-address-v3-
|
1981
|
+
|
1662
1982
|
create a currency deposit address
|
1663
1983
|
:param str code: unified currency code of the currency for the deposit address
|
1664
1984
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1667,24 +1987,38 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1667
1987
|
"""
|
1668
1988
|
await self.load_markets()
|
1669
1989
|
currency = self.currency(code)
|
1670
|
-
request = {
|
1990
|
+
request: dict = {
|
1671
1991
|
'currency': currency['id'],
|
1672
1992
|
}
|
1673
1993
|
networkCode = None
|
1674
1994
|
networkCode, params = self.handle_network_code_and_params(params)
|
1675
1995
|
if networkCode is not None:
|
1676
|
-
request['chain'] = self.network_code_to_id(networkCode)
|
1677
|
-
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))
|
1678
1998
|
# {"code":"260000","msg":"Deposit address already exists."}
|
1679
|
-
#
|
1680
|
-
#
|
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
|
+
#
|
1681
2013
|
data = self.safe_dict(response, 'data', {})
|
1682
2014
|
return self.parse_deposit_address(data, currency)
|
1683
2015
|
|
1684
|
-
async def fetch_deposit_address(self, code: str, params={}):
|
2016
|
+
async def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
|
1685
2017
|
"""
|
1686
2018
|
fetch the deposit address for a currency associated with self account
|
1687
|
-
|
2019
|
+
|
2020
|
+
https://docs.kucoin.com/#get-deposit-addresses-v2
|
2021
|
+
|
1688
2022
|
:param str code: unified currency code
|
1689
2023
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1690
2024
|
:param str [params.network]: the blockchain network name
|
@@ -1692,7 +2026,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1692
2026
|
"""
|
1693
2027
|
await self.load_markets()
|
1694
2028
|
currency = self.currency(code)
|
1695
|
-
request = {
|
2029
|
+
request: dict = {
|
1696
2030
|
'currency': currency['id'],
|
1697
2031
|
# for USDT - OMNI, ERC20, TRC20, default is ERC20
|
1698
2032
|
# for BTC - Native, Segwit, TRC20, the parameters are bech32, btc, trx, default is Native
|
@@ -1713,28 +2047,30 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1713
2047
|
raise ExchangeError(self.id + ' fetchDepositAddress() returned an empty response, you might try to run createDepositAddress() first and try again')
|
1714
2048
|
return self.parse_deposit_address(data, currency)
|
1715
2049
|
|
1716
|
-
def parse_deposit_address(self, depositAddress, currency: Currency = None):
|
2050
|
+
def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
|
1717
2051
|
address = self.safe_string(depositAddress, 'address')
|
1718
2052
|
# BCH/BSV is returned with a "bitcoincash:" prefix, which we cut off here and only keep the address
|
1719
2053
|
if address is not None:
|
1720
2054
|
address = address.replace('bitcoincash:', '')
|
1721
2055
|
code = None
|
1722
2056
|
if currency is not None:
|
1723
|
-
code = currency['id']
|
2057
|
+
code = self.safe_currency_code(currency['id'])
|
1724
2058
|
if code != 'NIM':
|
1725
2059
|
# contains spaces
|
1726
2060
|
self.check_address(address)
|
1727
2061
|
return {
|
1728
2062
|
'info': depositAddress,
|
1729
2063
|
'currency': code,
|
2064
|
+
'network': self.network_id_to_code(self.safe_string(depositAddress, 'chainId')),
|
1730
2065
|
'address': address,
|
1731
2066
|
'tag': self.safe_string(depositAddress, 'memo'),
|
1732
|
-
'network': self.network_id_to_code(self.safe_string(depositAddress, 'chain')),
|
1733
2067
|
}
|
1734
2068
|
|
1735
|
-
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]:
|
1736
2070
|
"""
|
1737
|
-
|
2071
|
+
|
2072
|
+
https://docs.kucoin.com/#get-deposit-addresses-v2
|
2073
|
+
|
1738
2074
|
fetch the deposit address for a currency associated with self account
|
1739
2075
|
:param str code: unified currency code
|
1740
2076
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1742,7 +2078,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1742
2078
|
"""
|
1743
2079
|
await self.load_markets()
|
1744
2080
|
currency = self.currency(code)
|
1745
|
-
request = {
|
2081
|
+
request: dict = {
|
1746
2082
|
'currency': currency['id'],
|
1747
2083
|
}
|
1748
2084
|
version = self.options['versions']['private']['GET']['deposit-addresses']
|
@@ -1766,15 +2102,17 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1766
2102
|
self.options['versions']['private']['GET']['deposit-addresses'] = version
|
1767
2103
|
chains = self.safe_list(response, 'data', [])
|
1768
2104
|
parsed = self.parse_deposit_addresses(chains, [currency['code']], False, {
|
1769
|
-
'currency': currency['
|
2105
|
+
'currency': currency['code'],
|
1770
2106
|
})
|
1771
2107
|
return self.index_by(parsed, 'network')
|
1772
2108
|
|
1773
2109
|
async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
1774
2110
|
"""
|
1775
2111
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
1776
|
-
|
1777
|
-
|
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
|
+
|
1778
2116
|
:param str symbol: unified symbol of the market to fetch the order book for
|
1779
2117
|
:param int [limit]: the maximum amount of order book entries to return
|
1780
2118
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1783,7 +2121,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1783
2121
|
await self.load_markets()
|
1784
2122
|
market = self.market(symbol)
|
1785
2123
|
level = self.safe_integer(params, 'level', 2)
|
1786
|
-
request = {'symbol': market['id']}
|
2124
|
+
request: dict = {'symbol': market['id']}
|
1787
2125
|
isAuthenticated = self.check_required_credentials(False)
|
1788
2126
|
response = None
|
1789
2127
|
if not isAuthenticated or limit is not None:
|
@@ -1848,49 +2186,56 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1848
2186
|
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
1849
2187
|
"""
|
1850
2188
|
Create an order on the exchange
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
|
1856
|
-
|
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
|
+
|
1857
2198
|
:param str symbol: Unified CCXT market symbol
|
1858
2199
|
:param str type: 'limit' or 'market'
|
1859
2200
|
:param str side: 'buy' or 'sell'
|
1860
2201
|
:param float amount: the amount of currency to trade
|
1861
|
-
: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
|
1862
2203
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1863
2204
|
:param float [params.triggerPrice]: The price at which a trigger order is triggered at
|
1864
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
|
1865
2206
|
:param str [params.timeInForce]: GTC, GTT, IOC, or FOK, default is GTC, limit orders only
|
1866
2207
|
:param str [params.postOnly]: Post only flag, invalid when timeInForce is IOC or FOK
|
1867
|
-
|
1868
|
-
|
2208
|
+
|
2209
|
+
EXCHANGE SPECIFIC PARAMETERS
|
1869
2210
|
:param str [params.clientOid]: client order id, defaults to uuid if not passed
|
1870
2211
|
:param str [params.remark]: remark for the order, length cannot exceed 100 utf8 characters
|
1871
2212
|
:param str [params.tradeType]: 'TRADE', # TRADE, MARGIN_TRADE # not used with margin orders
|
1872
|
-
|
2213
|
+
limit orders ---------------------------------------------------
|
1873
2214
|
:param float [params.cancelAfter]: long, # cancel after n seconds, requires timeInForce to be GTT
|
1874
2215
|
:param bool [params.hidden]: False, # Order will not be displayed in the order book
|
1875
2216
|
:param bool [params.iceberg]: False, # Only a portion of the order is displayed in the order book
|
1876
2217
|
:param str [params.visibleSize]: self.amount_to_precision(symbol, visibleSize), # The maximum visible size of an iceberg order
|
1877
|
-
|
2218
|
+
market orders --------------------------------------------------
|
1878
2219
|
:param str [params.funds]: # Amount of quote currency to use
|
1879
|
-
|
1880
|
-
:param str [params.stop]: Either loss or entry, the default is loss. Requires
|
1881
|
-
|
2220
|
+
stop orders ----------------------------------------------------
|
2221
|
+
:param str [params.stop]: Either loss or entry, the default is loss. Requires triggerPrice to be defined
|
2222
|
+
margin orders --------------------------------------------------
|
1882
2223
|
:param float [params.leverage]: Leverage size of the order
|
1883
2224
|
:param str [params.stp]: '', # self trade prevention, CN, CO, CB or DC
|
1884
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
|
1885
2226
|
:param bool [params.hf]: False, # True for hf order
|
1886
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
|
1887
2229
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1888
2230
|
"""
|
1889
2231
|
await self.load_markets()
|
1890
2232
|
market = self.market(symbol)
|
1891
2233
|
testOrder = self.safe_bool(params, 'test', False)
|
1892
2234
|
params = self.omit(params, 'test')
|
1893
|
-
|
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)
|
1894
2239
|
triggerPrice, stopLossPrice, takeProfitPrice = self.handle_trigger_prices(params)
|
1895
2240
|
tradeType = self.safe_string(params, 'tradeType') # keep it for backward compatibility
|
1896
2241
|
isTriggerOrder = (triggerPrice or stopLossPrice or takeProfitPrice)
|
@@ -1903,14 +2248,18 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1903
2248
|
if testOrder:
|
1904
2249
|
if isMarginOrder:
|
1905
2250
|
response = await self.privatePostMarginOrderTest(orderRequest)
|
2251
|
+
elif hf:
|
2252
|
+
response = await self.privatePostHfOrdersTest(orderRequest)
|
1906
2253
|
else:
|
1907
2254
|
response = await self.privatePostOrdersTest(orderRequest)
|
1908
|
-
elif isHf:
|
1909
|
-
response = await self.privatePostHfOrders(orderRequest)
|
1910
2255
|
elif isTriggerOrder:
|
1911
2256
|
response = await self.privatePostStopOrder(orderRequest)
|
1912
2257
|
elif isMarginOrder:
|
1913
2258
|
response = await self.privatePostMarginOrder(orderRequest)
|
2259
|
+
elif useSync:
|
2260
|
+
response = await self.privatePostHfOrdersSync(orderRequest)
|
2261
|
+
elif hf:
|
2262
|
+
response = await self.privatePostHfOrders(orderRequest)
|
1914
2263
|
else:
|
1915
2264
|
response = await self.privatePostOrders(orderRequest)
|
1916
2265
|
#
|
@@ -1927,7 +2276,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1927
2276
|
async def create_market_order_with_cost(self, symbol: str, side: OrderSide, cost: float, params={}):
|
1928
2277
|
"""
|
1929
2278
|
create a market order by providing the symbol, side and cost
|
1930
|
-
|
2279
|
+
|
2280
|
+
https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
|
2281
|
+
|
1931
2282
|
:param str symbol: unified symbol of the market to create an order in
|
1932
2283
|
:param str side: 'buy' or 'sell'
|
1933
2284
|
:param float cost: how much you want to trade in units of the quote currency
|
@@ -1935,13 +2286,17 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1935
2286
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1936
2287
|
"""
|
1937
2288
|
await self.load_markets()
|
1938
|
-
|
1939
|
-
|
2289
|
+
req = {
|
2290
|
+
'cost': cost,
|
2291
|
+
}
|
2292
|
+
return await self.create_order(symbol, 'market', side, 0, None, self.extend(req, params))
|
1940
2293
|
|
1941
2294
|
async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
|
1942
2295
|
"""
|
1943
2296
|
create a market buy order by providing the symbol and cost
|
1944
|
-
|
2297
|
+
|
2298
|
+
https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
|
2299
|
+
|
1945
2300
|
:param str symbol: unified symbol of the market to create an order in
|
1946
2301
|
:param float cost: how much you want to trade in units of the quote currency
|
1947
2302
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1953,7 +2308,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1953
2308
|
async def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}):
|
1954
2309
|
"""
|
1955
2310
|
create a market sell order by providing the symbol and cost
|
1956
|
-
|
2311
|
+
|
2312
|
+
https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
|
2313
|
+
|
1957
2314
|
:param str symbol: unified symbol of the market to create an order in
|
1958
2315
|
:param float cost: how much you want to trade in units of the quote currency
|
1959
2316
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1965,11 +2322,15 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1965
2322
|
async def create_orders(self, orders: List[OrderRequest], params={}):
|
1966
2323
|
"""
|
1967
2324
|
create a list of trade orders
|
1968
|
-
|
1969
|
-
|
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
|
+
|
1970
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
|
1971
2331
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1972
2332
|
:param bool [params.hf]: False, # True for hf orders
|
2333
|
+
:param bool [params.sync]: False, # True to use the hf sync call
|
1973
2334
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1974
2335
|
"""
|
1975
2336
|
await self.load_markets()
|
@@ -1993,14 +2354,18 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1993
2354
|
orderRequest = self.create_order_request(marketId, type, side, amount, price, orderParams)
|
1994
2355
|
ordersRequests.append(orderRequest)
|
1995
2356
|
market = self.market(symbol)
|
1996
|
-
request = {
|
2357
|
+
request: dict = {
|
1997
2358
|
'symbol': market['id'],
|
1998
2359
|
'orderList': ordersRequests,
|
1999
2360
|
}
|
2000
|
-
hf =
|
2001
|
-
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)
|
2002
2365
|
response = None
|
2003
|
-
if
|
2366
|
+
if useSync:
|
2367
|
+
response = await self.privatePostHfOrdersMultiSync(self.extend(request, params))
|
2368
|
+
elif hf:
|
2004
2369
|
response = await self.privatePostHfOrdersMulti(self.extend(request, params))
|
2005
2370
|
else:
|
2006
2371
|
response = await self.privatePostOrdersMulti(self.extend(request, params))
|
@@ -2038,12 +2403,19 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2038
2403
|
data = self.safe_list(data, 'data', [])
|
2039
2404
|
return self.parse_orders(data)
|
2040
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
|
+
|
2041
2413
|
def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
2042
2414
|
market = self.market(symbol)
|
2043
2415
|
# required param, cannot be used twice
|
2044
2416
|
clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId', self.uuid())
|
2045
2417
|
params = self.omit(params, ['clientOid', 'clientOrderId'])
|
2046
|
-
request = {
|
2418
|
+
request: dict = {
|
2047
2419
|
'clientOid': clientOrderId,
|
2048
2420
|
'side': side,
|
2049
2421
|
'symbol': market['id'],
|
@@ -2058,7 +2430,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2058
2430
|
if quoteAmount is not None:
|
2059
2431
|
params = self.omit(params, ['cost', 'funds'])
|
2060
2432
|
# kucoin uses base precision even for quote values
|
2061
|
-
costString = self.
|
2433
|
+
costString = self.market_order_amount_to_precision(symbol, quoteAmount)
|
2062
2434
|
request['funds'] = costString
|
2063
2435
|
else:
|
2064
2436
|
amountString = self.amount_to_precision(symbol, amount)
|
@@ -2098,20 +2470,22 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2098
2470
|
async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
2099
2471
|
"""
|
2100
2472
|
edit an order, kucoin currently only supports the modification of HF orders
|
2101
|
-
|
2473
|
+
|
2474
|
+
https://docs.kucoin.com/spot-hf/#modify-order
|
2475
|
+
|
2102
2476
|
:param str id: order id
|
2103
2477
|
:param str symbol: unified symbol of the market to create an order in
|
2104
2478
|
:param str type: not used
|
2105
2479
|
:param str side: not used
|
2106
2480
|
:param float amount: how much of the currency you want to trade in units of the base currency
|
2107
|
-
: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
|
2108
2482
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2109
2483
|
:param str [params.clientOrderId]: client order id, defaults to id if not passed
|
2110
2484
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2111
2485
|
"""
|
2112
2486
|
await self.load_markets()
|
2113
2487
|
market = self.market(symbol)
|
2114
|
-
request = {
|
2488
|
+
request: dict = {
|
2115
2489
|
'symbol': market['id'],
|
2116
2490
|
}
|
2117
2491
|
clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId')
|
@@ -2138,78 +2512,149 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2138
2512
|
async def cancel_order(self, id: str, symbol: Str = None, params={}):
|
2139
2513
|
"""
|
2140
2514
|
cancels an open order
|
2141
|
-
|
2142
|
-
|
2143
|
-
|
2144
|
-
|
2145
|
-
|
2146
|
-
|
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
|
+
|
2147
2525
|
:param str id: order id
|
2148
2526
|
:param str symbol: unified symbol of the market the order was made in
|
2149
2527
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2150
|
-
:param bool [params.
|
2528
|
+
:param bool [params.trigger]: True if cancelling a stop order
|
2151
2529
|
:param bool [params.hf]: False, # True for hf order
|
2530
|
+
:param bool [params.sync]: False, # True to use the hf sync call
|
2152
2531
|
:returns: Response from the exchange
|
2153
2532
|
"""
|
2154
2533
|
await self.load_markets()
|
2155
|
-
request = {}
|
2534
|
+
request: dict = {}
|
2156
2535
|
clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId')
|
2157
|
-
|
2158
|
-
hf =
|
2159
|
-
|
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:
|
2160
2542
|
if symbol is None:
|
2161
2543
|
raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol parameter for hf orders')
|
2162
2544
|
market = self.market(symbol)
|
2163
2545
|
request['symbol'] = market['id']
|
2164
2546
|
response = None
|
2165
|
-
params = self.omit(params, ['clientOid', 'clientOrderId', 'stop', '
|
2547
|
+
params = self.omit(params, ['clientOid', 'clientOrderId', 'stop', 'trigger'])
|
2166
2548
|
if clientOrderId is not None:
|
2167
2549
|
request['clientOid'] = clientOrderId
|
2168
|
-
if
|
2550
|
+
if trigger:
|
2169
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))
|
2170
2563
|
elif hf:
|
2171
2564
|
response = await self.privateDeleteHfOrdersClientOrderClientOid(self.extend(request, params))
|
2565
|
+
#
|
2566
|
+
# {
|
2567
|
+
# "code": "200000",
|
2568
|
+
# "data": {
|
2569
|
+
# "clientOid": "6d539dc614db3"
|
2570
|
+
# }
|
2571
|
+
# }
|
2572
|
+
#
|
2172
2573
|
else:
|
2173
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)
|
2174
2587
|
else:
|
2175
2588
|
request['orderId'] = id
|
2176
|
-
if
|
2589
|
+
if trigger:
|
2177
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))
|
2178
2599
|
elif hf:
|
2179
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)
|
2180
2611
|
else:
|
2181
2612
|
response = await self.privateDeleteOrdersOrderId(self.extend(request, params))
|
2182
|
-
|
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
|
+
})
|
2183
2626
|
|
2184
2627
|
async def cancel_all_orders(self, symbol: Str = None, params={}):
|
2185
2628
|
"""
|
2186
2629
|
cancel all open orders
|
2187
|
-
|
2188
|
-
|
2189
|
-
|
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
|
+
|
2190
2635
|
:param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
|
2191
2636
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2192
|
-
:param bool [params.
|
2637
|
+
:param bool [params.trigger]: *invalid for isolated margin* True if cancelling all stop orders
|
2193
2638
|
:param str [params.marginMode]: 'cross' or 'isolated'
|
2194
2639
|
:param str [params.orderIds]: *stop orders only* Comma seperated order IDs
|
2195
|
-
:param bool [params.stop]: True if cancelling a stop order
|
2196
2640
|
:param bool [params.hf]: False, # True for hf order
|
2197
2641
|
:returns: Response from the exchange
|
2198
2642
|
"""
|
2199
2643
|
await self.load_markets()
|
2200
|
-
request = {}
|
2201
|
-
|
2202
|
-
hf =
|
2203
|
-
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')
|
2204
2649
|
marginMode, query = self.handle_margin_mode_and_params('cancelAllOrders', params)
|
2205
2650
|
if symbol is not None:
|
2206
2651
|
request['symbol'] = self.market_id(symbol)
|
2207
2652
|
if marginMode is not None:
|
2208
2653
|
request['tradeType'] = self.options['marginModes'][marginMode]
|
2209
|
-
if marginMode == 'isolated' and
|
2654
|
+
if marginMode == 'isolated' and trigger:
|
2210
2655
|
raise BadRequest(self.id + ' cancelAllOrders does not support isolated margin for stop orders')
|
2211
2656
|
response = None
|
2212
|
-
if
|
2657
|
+
if trigger:
|
2213
2658
|
response = await self.privateDeleteStopOrderCancel(self.extend(request, query))
|
2214
2659
|
elif hf:
|
2215
2660
|
if symbol is None:
|
@@ -2223,38 +2668,42 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2223
2668
|
async def fetch_orders_by_status(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
2224
2669
|
"""
|
2225
2670
|
fetch a list of orders
|
2226
|
-
|
2227
|
-
|
2228
|
-
|
2229
|
-
|
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
|
+
|
2230
2677
|
:param str status: *not used for stop orders* 'open' or 'closed'
|
2231
2678
|
:param str symbol: unified market symbol
|
2232
2679
|
:param int [since]: timestamp in ms of the earliest order
|
2233
2680
|
:param int [limit]: max number of orders to return
|
2234
2681
|
:param dict [params]: exchange specific params
|
2235
2682
|
:param int [params.until]: end time in ms
|
2236
|
-
:param bool [params.stop]: True if fetching stop orders
|
2237
2683
|
:param str [params.side]: buy or sell
|
2238
2684
|
:param str [params.type]: limit, market, limit_stop or market_stop
|
2239
2685
|
:param str [params.tradeType]: TRADE for spot trading, MARGIN_TRADE for Margin Trading
|
2240
|
-
:param int [params.currentPage]: *
|
2241
|
-
:param str [params.orderIds]: *
|
2242
|
-
: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
|
2243
2689
|
:param bool [params.hf]: False, # True for hf order
|
2244
2690
|
:returns: An `array of order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
2245
2691
|
"""
|
2246
2692
|
await self.load_markets()
|
2247
2693
|
lowercaseStatus = status.lower()
|
2248
|
-
until = self.
|
2249
|
-
|
2250
|
-
hf =
|
2251
|
-
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'])
|
2252
2701
|
marginMode, query = self.handle_margin_mode_and_params('fetchOrdersByStatus', params)
|
2253
2702
|
if lowercaseStatus == 'open':
|
2254
2703
|
lowercaseStatus = 'active'
|
2255
2704
|
elif lowercaseStatus == 'closed':
|
2256
2705
|
lowercaseStatus = 'done'
|
2257
|
-
request = {
|
2706
|
+
request: dict = {
|
2258
2707
|
'status': lowercaseStatus,
|
2259
2708
|
}
|
2260
2709
|
market = None
|
@@ -2269,7 +2718,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2269
2718
|
request['endAt'] = until
|
2270
2719
|
request['tradeType'] = self.safe_string(self.options['marginModes'], marginMode, 'TRADE')
|
2271
2720
|
response = None
|
2272
|
-
if
|
2721
|
+
if trigger:
|
2273
2722
|
response = await self.privateGetStopOrder(self.extend(request, query))
|
2274
2723
|
elif hf:
|
2275
2724
|
if lowercaseStatus == 'active':
|
@@ -2321,26 +2770,31 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2321
2770
|
# ]
|
2322
2771
|
# }
|
2323
2772
|
# }
|
2773
|
+
listData = self.safe_list(response, 'data')
|
2774
|
+
if listData is not None:
|
2775
|
+
return self.parse_orders(listData, market, since, limit)
|
2324
2776
|
responseData = self.safe_dict(response, 'data', {})
|
2325
|
-
orders = self.
|
2777
|
+
orders = self.safe_list(responseData, 'items', [])
|
2326
2778
|
return self.parse_orders(orders, market, since, limit)
|
2327
2779
|
|
2328
2780
|
async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
2329
2781
|
"""
|
2330
2782
|
fetches information on multiple closed orders made by the user
|
2331
|
-
|
2332
|
-
|
2333
|
-
|
2334
|
-
|
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
|
+
|
2335
2789
|
:param str symbol: unified market symbol of the market orders were made in
|
2336
2790
|
:param int [since]: the earliest time in ms to fetch orders for
|
2337
2791
|
:param int [limit]: the maximum number of order structures to retrieve
|
2338
2792
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2339
|
-
:param int [params.
|
2793
|
+
:param int [params.until]: end time in ms
|
2340
2794
|
:param str [params.side]: buy or sell
|
2341
2795
|
:param str [params.type]: limit, market, limit_stop or market_stop
|
2342
2796
|
:param str [params.tradeType]: TRADE for spot trading, MARGIN_TRADE for Margin Trading
|
2343
|
-
:param bool [params.
|
2797
|
+
:param bool [params.trigger]: True if fetching a trigger order
|
2344
2798
|
:param bool [params.hf]: False, # True for hf order
|
2345
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)
|
2346
2800
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
@@ -2355,22 +2809,23 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2355
2809
|
async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
2356
2810
|
"""
|
2357
2811
|
fetch all unfilled currently open orders
|
2358
|
-
|
2359
|
-
|
2360
|
-
|
2361
|
-
|
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
|
+
|
2362
2818
|
:param str symbol: unified market symbol
|
2363
2819
|
:param int [since]: the earliest time in ms to fetch open orders for
|
2364
2820
|
:param int [limit]: the maximum number of open orders structures to retrieve
|
2365
2821
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2366
|
-
:param int [params.
|
2367
|
-
:param bool [params.
|
2822
|
+
:param int [params.until]: end time in ms
|
2823
|
+
:param bool [params.trigger]: True if fetching trigger orders
|
2368
2824
|
:param str [params.side]: buy or sell
|
2369
2825
|
:param str [params.type]: limit, market, limit_stop or market_stop
|
2370
2826
|
:param str [params.tradeType]: TRADE for spot trading, MARGIN_TRADE for Margin Trading
|
2371
|
-
:param int [params.currentPage]: *
|
2372
|
-
:param str [params.orderIds]: *
|
2373
|
-
: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
|
2374
2829
|
:param bool [params.hf]: False, # True for hf order
|
2375
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)
|
2376
2831
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
@@ -2385,25 +2840,28 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2385
2840
|
async def fetch_order(self, id: str, symbol: Str = None, params={}):
|
2386
2841
|
"""
|
2387
2842
|
fetch an order
|
2388
|
-
|
2389
|
-
|
2390
|
-
|
2391
|
-
|
2392
|
-
|
2393
|
-
|
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
|
+
|
2394
2851
|
:param str id: Order id
|
2395
|
-
: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
|
2396
2853
|
:param dict [params]: exchange specific parameters
|
2397
|
-
:param bool [params.
|
2854
|
+
:param bool [params.trigger]: True if fetching a trigger order
|
2398
2855
|
:param bool [params.hf]: False, # True for hf order
|
2399
2856
|
:param bool [params.clientOid]: unique order id created by users to identify their orders
|
2400
2857
|
:returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2401
2858
|
"""
|
2402
2859
|
await self.load_markets()
|
2403
|
-
request = {}
|
2860
|
+
request: dict = {}
|
2404
2861
|
clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId')
|
2405
|
-
|
2406
|
-
hf =
|
2862
|
+
trigger = self.safe_bool_2(params, 'stop', 'trigger', False)
|
2863
|
+
hf = None
|
2864
|
+
hf, params = self.handle_hf_and_params(params)
|
2407
2865
|
market = None
|
2408
2866
|
if symbol is not None:
|
2409
2867
|
market = self.market(symbol)
|
@@ -2411,11 +2869,11 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2411
2869
|
if symbol is None:
|
2412
2870
|
raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol parameter for hf orders')
|
2413
2871
|
request['symbol'] = market['id']
|
2414
|
-
params = self.omit(params, ['stop', '
|
2872
|
+
params = self.omit(params, ['stop', 'clientOid', 'clientOrderId', 'trigger'])
|
2415
2873
|
response = None
|
2416
2874
|
if clientOrderId is not None:
|
2417
2875
|
request['clientOid'] = clientOrderId
|
2418
|
-
if
|
2876
|
+
if trigger:
|
2419
2877
|
if symbol is not None:
|
2420
2878
|
request['symbol'] = market['id']
|
2421
2879
|
response = await self.privateGetStopOrderQueryOrderByClientOid(self.extend(request, params))
|
@@ -2430,7 +2888,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2430
2888
|
if id is None:
|
2431
2889
|
raise InvalidOrder(self.id + ' fetchOrder() requires an order id')
|
2432
2890
|
request['orderId'] = id
|
2433
|
-
if
|
2891
|
+
if trigger:
|
2434
2892
|
response = await self.privateGetStopOrderOrderId(self.extend(request, params))
|
2435
2893
|
elif hf:
|
2436
2894
|
response = await self.privateGetHfOrdersOrderId(self.extend(request, params))
|
@@ -2441,7 +2899,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2441
2899
|
responseData = self.safe_value(responseData, 0)
|
2442
2900
|
return self.parse_order(responseData, market)
|
2443
2901
|
|
2444
|
-
def parse_order(self, order, market: Market = None) -> Order:
|
2902
|
+
def parse_order(self, order: dict, market: Market = None) -> Order:
|
2445
2903
|
#
|
2446
2904
|
# createOrder
|
2447
2905
|
#
|
@@ -2568,7 +3026,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2568
3026
|
feeCurrencyId = self.safe_string(order, 'feeCurrency')
|
2569
3027
|
cancelExist = self.safe_bool(order, 'cancelExist', False)
|
2570
3028
|
responseStop = self.safe_string(order, 'stop')
|
2571
|
-
|
3029
|
+
trigger = responseStop is not None
|
2572
3030
|
stopTriggered = self.safe_bool(order, 'stopTriggered', False)
|
2573
3031
|
isActive = self.safe_bool_2(order, 'isActive', 'active')
|
2574
3032
|
responseStatus = self.safe_string(order, 'status')
|
@@ -2578,7 +3036,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2578
3036
|
status = 'open'
|
2579
3037
|
else:
|
2580
3038
|
status = 'closed'
|
2581
|
-
if
|
3039
|
+
if trigger:
|
2582
3040
|
if responseStatus == 'NEW':
|
2583
3041
|
status = 'open'
|
2584
3042
|
elif not isActive and not stopTriggered:
|
@@ -2587,10 +3045,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2587
3045
|
status = 'canceled'
|
2588
3046
|
if responseStatus == 'fail':
|
2589
3047
|
status = 'rejected'
|
2590
|
-
stopPrice = self.safe_number(order, 'stopPrice')
|
2591
3048
|
return self.safe_order({
|
2592
3049
|
'info': order,
|
2593
|
-
'id': self.safe_string_n(order, ['id', 'orderId', 'newOrderId']),
|
3050
|
+
'id': self.safe_string_n(order, ['id', 'orderId', 'newOrderId', 'cancelledOrderId']),
|
2594
3051
|
'clientOrderId': self.safe_string(order, 'clientOid'),
|
2595
3052
|
'symbol': self.safe_symbol(marketId, market, '-'),
|
2596
3053
|
'type': self.safe_string(order, 'type'),
|
@@ -2599,8 +3056,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2599
3056
|
'side': self.safe_string(order, 'side'),
|
2600
3057
|
'amount': self.safe_string(order, 'size'),
|
2601
3058
|
'price': self.safe_string(order, 'price'), # price is zero for market order, omitZero is called in safeOrder2
|
2602
|
-
'
|
2603
|
-
'triggerPrice': stopPrice,
|
3059
|
+
'triggerPrice': self.safe_number(order, 'stopPrice'),
|
2604
3060
|
'cost': self.safe_string(order, 'dealFunds'),
|
2605
3061
|
'filled': self.safe_string(order, 'dealSize'),
|
2606
3062
|
'remaining': None,
|
@@ -2612,15 +3068,17 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2612
3068
|
},
|
2613
3069
|
'status': status,
|
2614
3070
|
'lastTradeTimestamp': None,
|
2615
|
-
'average':
|
3071
|
+
'average': self.safe_string(order, 'avgDealPrice'),
|
2616
3072
|
'trades': None,
|
2617
3073
|
}, market)
|
2618
3074
|
|
2619
3075
|
async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
2620
3076
|
"""
|
2621
3077
|
fetch all the trades made from a single order
|
2622
|
-
|
2623
|
-
|
3078
|
+
|
3079
|
+
https://docs.kucoin.com/#list-fills
|
3080
|
+
https://docs.kucoin.com/spot-hf/#transaction-details
|
3081
|
+
|
2624
3082
|
:param str id: order id
|
2625
3083
|
:param str symbol: unified market symbol
|
2626
3084
|
:param int [since]: the earliest time in ms to fetch trades for
|
@@ -2628,15 +3086,17 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2628
3086
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2629
3087
|
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
2630
3088
|
"""
|
2631
|
-
request = {
|
3089
|
+
request: dict = {
|
2632
3090
|
'orderId': id,
|
2633
3091
|
}
|
2634
3092
|
return await self.fetch_my_trades(symbol, since, limit, self.extend(request, params))
|
2635
3093
|
|
2636
3094
|
async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
2637
3095
|
"""
|
2638
|
-
|
2639
|
-
|
3096
|
+
|
3097
|
+
https://docs.kucoin.com/#list-fills
|
3098
|
+
https://docs.kucoin.com/spot-hf/#transaction-details
|
3099
|
+
|
2640
3100
|
fetch all trades made by the user
|
2641
3101
|
:param str symbol: unified market symbol
|
2642
3102
|
:param int [since]: the earliest time in ms to fetch trades for
|
@@ -2652,8 +3112,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2652
3112
|
paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
|
2653
3113
|
if paginate:
|
2654
3114
|
return await self.fetch_paginated_call_dynamic('fetchMyTrades', symbol, since, limit, params)
|
2655
|
-
request = {}
|
2656
|
-
hf =
|
3115
|
+
request: dict = {}
|
3116
|
+
hf = None
|
3117
|
+
hf, params = self.handle_hf_and_params(params)
|
2657
3118
|
if hf and symbol is None:
|
2658
3119
|
raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol parameter for hf orders')
|
2659
3120
|
market = None
|
@@ -2667,6 +3128,10 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2667
3128
|
response = None
|
2668
3129
|
request, params = self.handle_until_option('endAt', request, params)
|
2669
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
|
2670
3135
|
response = await self.privateGetHfFills(self.extend(request, params))
|
2671
3136
|
elif method == 'private_get_fills':
|
2672
3137
|
# does not return trades earlier than 2019-02-18T00:00:00Z
|
@@ -2733,7 +3198,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2733
3198
|
async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
2734
3199
|
"""
|
2735
3200
|
get the list of most recent trades for a particular symbol
|
2736
|
-
|
3201
|
+
|
3202
|
+
https://www.kucoin.com/docs/rest/spot-trading/market-data/get-trade-histories
|
3203
|
+
|
2737
3204
|
:param str symbol: unified symbol of the market to fetch trades for
|
2738
3205
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
2739
3206
|
:param int [limit]: the maximum amount of trades to fetch
|
@@ -2742,7 +3209,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2742
3209
|
"""
|
2743
3210
|
await self.load_markets()
|
2744
3211
|
market = self.market(symbol)
|
2745
|
-
request = {
|
3212
|
+
request: dict = {
|
2746
3213
|
'symbol': market['id'],
|
2747
3214
|
}
|
2748
3215
|
# pagination is not supported on the exchange side anymore
|
@@ -2770,7 +3237,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2770
3237
|
trades = self.safe_list(response, 'data', [])
|
2771
3238
|
return self.parse_trades(trades, market, since, limit)
|
2772
3239
|
|
2773
|
-
def parse_trade(self, trade, market: Market = None) -> Trade:
|
3240
|
+
def parse_trade(self, trade: dict, market: Market = None) -> Trade:
|
2774
3241
|
#
|
2775
3242
|
# fetchTrades(public)
|
2776
3243
|
#
|
@@ -2895,17 +3362,19 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2895
3362
|
'fee': fee,
|
2896
3363
|
}, market)
|
2897
3364
|
|
2898
|
-
async def fetch_trading_fee(self, symbol: str, params={}):
|
3365
|
+
async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
|
2899
3366
|
"""
|
2900
3367
|
fetch the trading fees for a market
|
2901
|
-
|
3368
|
+
|
3369
|
+
https://www.kucoin.com/docs/rest/funding/trade-fee/trading-pair-actual-fee-spot-margin-trade_hf
|
3370
|
+
|
2902
3371
|
:param str symbol: unified market symbol
|
2903
3372
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2904
3373
|
:returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
|
2905
3374
|
"""
|
2906
3375
|
await self.load_markets()
|
2907
3376
|
market = self.market(symbol)
|
2908
|
-
request = {
|
3377
|
+
request: dict = {
|
2909
3378
|
'symbols': market['id'],
|
2910
3379
|
}
|
2911
3380
|
response = await self.privateGetTradeFees(self.extend(request, params))
|
@@ -2933,10 +3402,12 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2933
3402
|
'tierBased': True,
|
2934
3403
|
}
|
2935
3404
|
|
2936
|
-
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:
|
2937
3406
|
"""
|
2938
3407
|
make a withdrawal
|
2939
|
-
|
3408
|
+
|
3409
|
+
https://www.kucoin.com/docs/rest/funding/withdrawals/apply-withdraw-v3-
|
3410
|
+
|
2940
3411
|
:param str code: unified currency code
|
2941
3412
|
:param float amount: the amount to withdraw
|
2942
3413
|
:param str address: the address to withdraw to
|
@@ -2948,10 +3419,10 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2948
3419
|
await self.load_markets()
|
2949
3420
|
self.check_address(address)
|
2950
3421
|
currency = self.currency(code)
|
2951
|
-
request = {
|
3422
|
+
request: dict = {
|
2952
3423
|
'currency': currency['id'],
|
2953
|
-
'
|
2954
|
-
'
|
3424
|
+
'toAddress': address,
|
3425
|
+
'withdrawType': 'ADDRESS',
|
2955
3426
|
# 'memo': tag,
|
2956
3427
|
# 'isInner': False, # internal transfer or external withdrawal
|
2957
3428
|
# 'remark': 'optional',
|
@@ -2963,13 +3434,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2963
3434
|
networkCode, params = self.handle_network_code_and_params(params)
|
2964
3435
|
if networkCode is not None:
|
2965
3436
|
request['chain'] = self.network_code_to_id(networkCode).lower()
|
3437
|
+
request['amount'] = float(self.currency_to_precision(code, amount, networkCode))
|
2966
3438
|
includeFee = None
|
2967
3439
|
includeFee, params = self.handle_option_and_params(params, 'withdraw', 'includeFee', False)
|
2968
3440
|
if includeFee:
|
2969
3441
|
request['feeDeductType'] = 'INTERNAL'
|
2970
3442
|
response = await self.privatePostWithdrawals(self.extend(request, params))
|
2971
3443
|
#
|
2972
|
-
#
|
3444
|
+
# the id is inside "data"
|
2973
3445
|
#
|
2974
3446
|
# {
|
2975
3447
|
# "code": 200000,
|
@@ -2981,8 +3453,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2981
3453
|
data = self.safe_dict(response, 'data', {})
|
2982
3454
|
return self.parse_transaction(data, currency)
|
2983
3455
|
|
2984
|
-
def parse_transaction_status(self, status):
|
2985
|
-
statuses = {
|
3456
|
+
def parse_transaction_status(self, status: Str):
|
3457
|
+
statuses: dict = {
|
2986
3458
|
'SUCCESS': 'ok',
|
2987
3459
|
'PROCESSING': 'pending',
|
2988
3460
|
'WALLET_PROCESSING': 'pending',
|
@@ -2990,7 +3462,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2990
3462
|
}
|
2991
3463
|
return self.safe_string(statuses, status, status)
|
2992
3464
|
|
2993
|
-
def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
|
3465
|
+
def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
|
2994
3466
|
#
|
2995
3467
|
# fetchDeposits
|
2996
3468
|
#
|
@@ -3097,8 +3569,10 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3097
3569
|
async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
3098
3570
|
"""
|
3099
3571
|
fetch all deposits made to an account
|
3100
|
-
|
3101
|
-
|
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
|
+
|
3102
3576
|
:param str code: unified currency code
|
3103
3577
|
:param int [since]: the earliest time in ms to fetch deposits for
|
3104
3578
|
:param int [limit]: the maximum number of deposits structures to retrieve
|
@@ -3112,7 +3586,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3112
3586
|
paginate, params = self.handle_option_and_params(params, 'fetchDeposits', 'paginate')
|
3113
3587
|
if paginate:
|
3114
3588
|
return await self.fetch_paginated_call_dynamic('fetchDeposits', code, since, limit, params)
|
3115
|
-
request = {}
|
3589
|
+
request: dict = {}
|
3116
3590
|
currency = None
|
3117
3591
|
if code is not None:
|
3118
3592
|
currency = self.currency(code)
|
@@ -3167,14 +3641,17 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3167
3641
|
# }
|
3168
3642
|
# }
|
3169
3643
|
#
|
3170
|
-
|
3171
|
-
|
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'})
|
3172
3647
|
|
3173
3648
|
async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
3174
3649
|
"""
|
3175
3650
|
fetch all withdrawals made from an account
|
3176
|
-
|
3177
|
-
|
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
|
+
|
3178
3655
|
:param str code: unified currency code
|
3179
3656
|
:param int [since]: the earliest time in ms to fetch withdrawals for
|
3180
3657
|
:param int [limit]: the maximum number of withdrawals structures to retrieve
|
@@ -3188,7 +3665,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3188
3665
|
paginate, params = self.handle_option_and_params(params, 'fetchWithdrawals', 'paginate')
|
3189
3666
|
if paginate:
|
3190
3667
|
return await self.fetch_paginated_call_dynamic('fetchWithdrawals', code, since, limit, params)
|
3191
|
-
request = {}
|
3668
|
+
request: dict = {}
|
3192
3669
|
currency = None
|
3193
3670
|
if code is not None:
|
3194
3671
|
currency = self.currency(code)
|
@@ -3244,14 +3721,15 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3244
3721
|
# }
|
3245
3722
|
# }
|
3246
3723
|
#
|
3247
|
-
|
3248
|
-
|
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'})
|
3249
3727
|
|
3250
3728
|
def parse_balance_helper(self, entry):
|
3251
3729
|
account = self.account()
|
3252
|
-
account['used'] = self.
|
3253
|
-
account['free'] = self.
|
3254
|
-
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')
|
3255
3733
|
debt = self.safe_string(entry, 'liability')
|
3256
3734
|
interest = self.safe_string(entry, 'interest')
|
3257
3735
|
account['debt'] = Precise.string_add(debt, interest)
|
@@ -3260,9 +3738,11 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3260
3738
|
async def fetch_balance(self, params={}) -> Balances:
|
3261
3739
|
"""
|
3262
3740
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
3263
|
-
|
3264
|
-
|
3265
|
-
|
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
|
+
|
3266
3746
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3267
3747
|
:param dict [params.marginMode]: 'cross' or 'isolated', margin type for fetching margin balance
|
3268
3748
|
:param dict [params.type]: extra parameters specific to the exchange API endpoint
|
@@ -3279,15 +3759,15 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3279
3759
|
accountsByType = self.safe_dict(self.options, 'accountsByType')
|
3280
3760
|
type = self.safe_string(accountsByType, requestedType, requestedType)
|
3281
3761
|
params = self.omit(params, 'type')
|
3282
|
-
|
3283
|
-
|
3762
|
+
hf = None
|
3763
|
+
hf, params = self.handle_hf_and_params(params)
|
3764
|
+
if hf and (type != 'main'):
|
3284
3765
|
type = 'trade_hf'
|
3285
|
-
params = self.omit(params, 'hf')
|
3286
3766
|
marginMode, query = self.handle_margin_mode_and_params('fetchBalance', params)
|
3287
3767
|
response = None
|
3288
|
-
request = {}
|
3768
|
+
request: dict = {}
|
3289
3769
|
isolated = (marginMode == 'isolated') or (type == 'isolated')
|
3290
|
-
cross = (marginMode == 'cross') or (type == '
|
3770
|
+
cross = (marginMode == 'cross') or (type == 'margin')
|
3291
3771
|
if isolated:
|
3292
3772
|
if currency is not None:
|
3293
3773
|
request['balanceCurrency'] = currency['id']
|
@@ -3300,7 +3780,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3300
3780
|
request['type'] = type
|
3301
3781
|
response = await self.privateGetAccounts(self.extend(request, query))
|
3302
3782
|
#
|
3303
|
-
# Spot
|
3783
|
+
# Spot
|
3304
3784
|
#
|
3305
3785
|
# {
|
3306
3786
|
# "code": "200000",
|
@@ -3316,35 +3796,59 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3316
3796
|
# ]
|
3317
3797
|
# }
|
3318
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
|
+
#
|
3319
3818
|
# Isolated
|
3320
3819
|
#
|
3321
3820
|
# {
|
3322
3821
|
# "code": "200000",
|
3323
3822
|
# "data": {
|
3324
|
-
# "
|
3325
|
-
# "
|
3823
|
+
# "totalAssetOfQuoteCurrency": "0",
|
3824
|
+
# "totalLiabilityOfQuoteCurrency": "0",
|
3825
|
+
# "timestamp": 1712085661155,
|
3326
3826
|
# "assets": [
|
3327
3827
|
# {
|
3328
3828
|
# "symbol": "MANA-USDT",
|
3329
|
-
# "status": "
|
3829
|
+
# "status": "EFFECTIVE",
|
3330
3830
|
# "debtRatio": "0",
|
3331
3831
|
# "baseAsset": {
|
3332
3832
|
# "currency": "MANA",
|
3333
|
-
# "
|
3334
|
-
# "
|
3335
|
-
# "
|
3833
|
+
# "borrowEnabled": True,
|
3834
|
+
# "transferInEnabled": True,
|
3835
|
+
# "total": "0",
|
3836
|
+
# "hold": "0",
|
3837
|
+
# "available": "0",
|
3336
3838
|
# "liability": "0",
|
3337
3839
|
# "interest": "0",
|
3338
|
-
# "
|
3840
|
+
# "maxBorrowSize": "0"
|
3339
3841
|
# },
|
3340
3842
|
# "quoteAsset": {
|
3341
3843
|
# "currency": "USDT",
|
3342
|
-
# "
|
3343
|
-
# "
|
3344
|
-
# "
|
3844
|
+
# "borrowEnabled": True,
|
3845
|
+
# "transferInEnabled": True,
|
3846
|
+
# "total": "0",
|
3847
|
+
# "hold": "0",
|
3848
|
+
# "available": "0",
|
3345
3849
|
# "liability": "0",
|
3346
3850
|
# "interest": "0",
|
3347
|
-
# "
|
3851
|
+
# "maxBorrowSize": "0"
|
3348
3852
|
# }
|
3349
3853
|
# },
|
3350
3854
|
# ...
|
@@ -3352,13 +3856,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3352
3856
|
# }
|
3353
3857
|
# }
|
3354
3858
|
#
|
3355
|
-
data =
|
3356
|
-
result = {
|
3859
|
+
data = None
|
3860
|
+
result: dict = {
|
3357
3861
|
'info': response,
|
3358
3862
|
'timestamp': None,
|
3359
3863
|
'datetime': None,
|
3360
3864
|
}
|
3361
3865
|
if isolated:
|
3866
|
+
data = self.safe_dict(response, 'data', {})
|
3362
3867
|
assets = self.safe_value(data, 'assets', data)
|
3363
3868
|
for i in range(0, len(assets)):
|
3364
3869
|
entry = assets[i]
|
@@ -3368,11 +3873,12 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3368
3873
|
quote = self.safe_dict(entry, 'quoteAsset', {})
|
3369
3874
|
baseCode = self.safe_currency_code(self.safe_string(base, 'currency'))
|
3370
3875
|
quoteCode = self.safe_currency_code(self.safe_string(quote, 'currency'))
|
3371
|
-
subResult = {}
|
3876
|
+
subResult: dict = {}
|
3372
3877
|
subResult[baseCode] = self.parse_balance_helper(base)
|
3373
3878
|
subResult[quoteCode] = self.parse_balance_helper(quote)
|
3374
3879
|
result[symbol] = self.safe_balance(subResult)
|
3375
3880
|
elif cross:
|
3881
|
+
data = self.safe_dict(response, 'data', {})
|
3376
3882
|
accounts = self.safe_list(data, 'accounts', [])
|
3377
3883
|
for i in range(0, len(accounts)):
|
3378
3884
|
balance = accounts[i]
|
@@ -3380,6 +3886,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3380
3886
|
codeInner = self.safe_currency_code(currencyId)
|
3381
3887
|
result[codeInner] = self.parse_balance_helper(balance)
|
3382
3888
|
else:
|
3889
|
+
data = self.safe_list(response, 'data', [])
|
3383
3890
|
for i in range(0, len(data)):
|
3384
3891
|
balance = data[i]
|
3385
3892
|
balanceType = self.safe_string(balance, 'type')
|
@@ -3397,9 +3904,11 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3397
3904
|
async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
3398
3905
|
"""
|
3399
3906
|
transfer currency internally between wallets on the same account
|
3400
|
-
|
3401
|
-
|
3402
|
-
|
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
|
+
|
3403
3912
|
:param str code: unified currency code
|
3404
3913
|
:param float amount: amount to transfer
|
3405
3914
|
:param str fromAccount: account to transfer from
|
@@ -3417,7 +3926,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3417
3926
|
if fromId == 'contract':
|
3418
3927
|
if toId != 'main':
|
3419
3928
|
raise ExchangeError(self.id + ' transfer() only supports transferring from futures account to main account')
|
3420
|
-
request = {
|
3929
|
+
request: dict = {
|
3421
3930
|
'currency': currency['id'],
|
3422
3931
|
'amount': requestedAmount,
|
3423
3932
|
}
|
@@ -3452,7 +3961,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3452
3961
|
data = self.safe_dict(response, 'data')
|
3453
3962
|
return self.parse_transfer(data, currency)
|
3454
3963
|
else:
|
3455
|
-
request = {
|
3964
|
+
request: dict = {
|
3456
3965
|
'currency': currency['id'],
|
3457
3966
|
'amount': requestedAmount,
|
3458
3967
|
}
|
@@ -3479,7 +3988,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3479
3988
|
data = self.safe_dict(response, 'data')
|
3480
3989
|
return self.parse_transfer(data, currency)
|
3481
3990
|
|
3482
|
-
def parse_transfer(self, transfer, currency: Currency = None):
|
3991
|
+
def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
|
3483
3992
|
#
|
3484
3993
|
# transfer(spot)
|
3485
3994
|
#
|
@@ -3534,14 +4043,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3534
4043
|
'info': transfer,
|
3535
4044
|
}
|
3536
4045
|
|
3537
|
-
def parse_transfer_status(self, status):
|
3538
|
-
statuses = {
|
4046
|
+
def parse_transfer_status(self, status: Str) -> Str:
|
4047
|
+
statuses: dict = {
|
3539
4048
|
'PROCESSING': 'pending',
|
3540
4049
|
}
|
3541
4050
|
return self.safe_string(statuses, status, status)
|
3542
4051
|
|
3543
4052
|
def parse_ledger_entry_type(self, type):
|
3544
|
-
types = {
|
4053
|
+
types: dict = {
|
3545
4054
|
'Assets Transferred in After Upgrading': 'transfer', # Assets Transferred in After V1 to V2 Upgrading
|
3546
4055
|
'Deposit': 'transaction', # Deposit
|
3547
4056
|
'Withdrawal': 'transaction', # Withdrawal
|
@@ -3584,7 +4093,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3584
4093
|
}
|
3585
4094
|
return self.safe_string(types, type, type)
|
3586
4095
|
|
3587
|
-
def parse_ledger_entry(self, item, currency: Currency = None):
|
4096
|
+
def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
|
3588
4097
|
#
|
3589
4098
|
# {
|
3590
4099
|
# "id": "611a1e7c6a053300067a88d9", #unique key for each ledger entry
|
@@ -3602,6 +4111,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3602
4111
|
id = self.safe_string(item, 'id')
|
3603
4112
|
currencyId = self.safe_string(item, 'currency')
|
3604
4113
|
code = self.safe_currency_code(currencyId, currency)
|
4114
|
+
currency = self.safe_currency(currencyId, currency)
|
3605
4115
|
amount = self.safe_number(item, 'amount')
|
3606
4116
|
balanceAfter = None
|
3607
4117
|
# balanceAfter = self.safe_number(item, 'balance'); only returns zero string
|
@@ -3644,7 +4154,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3644
4154
|
if feeCost != '0':
|
3645
4155
|
feeCurrency = code
|
3646
4156
|
fee = {'cost': self.parse_number(feeCost), 'currency': feeCurrency}
|
3647
|
-
return {
|
4157
|
+
return self.safe_ledger_entry({
|
4158
|
+
'info': item,
|
3648
4159
|
'id': id,
|
3649
4160
|
'direction': direction,
|
3650
4161
|
'account': account,
|
@@ -3659,33 +4170,34 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3659
4170
|
'after': balanceAfter, # None
|
3660
4171
|
'status': None,
|
3661
4172
|
'fee': fee,
|
3662
|
-
|
3663
|
-
}
|
4173
|
+
}, currency)
|
3664
4174
|
|
3665
|
-
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]:
|
3666
4176
|
"""
|
3667
|
-
|
3668
|
-
|
3669
|
-
|
3670
|
-
|
3671
|
-
|
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
|
3672
4184
|
:param int [since]: timestamp in ms of the earliest ledger entry, default is None
|
3673
|
-
:param int [limit]: max number of ledger
|
4185
|
+
:param int [limit]: max number of ledger entries to return, default is None
|
3674
4186
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3675
4187
|
:param boolean [params.hf]: default False, when True will fetch ledger entries for the high frequency trading account
|
3676
4188
|
:param int [params.until]: the latest time in ms to fetch entries for
|
3677
|
-
:param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [
|
3678
|
-
: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>`
|
3679
4191
|
"""
|
3680
4192
|
await self.load_markets()
|
3681
4193
|
await self.load_accounts()
|
3682
4194
|
paginate = False
|
3683
4195
|
paginate, params = self.handle_option_and_params(params, 'fetchLedger', 'paginate')
|
3684
|
-
|
3685
|
-
params = self.
|
4196
|
+
hf = None
|
4197
|
+
hf, params = self.handle_hf_and_params(params)
|
3686
4198
|
if paginate:
|
3687
4199
|
return await self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params)
|
3688
|
-
request = {
|
4200
|
+
request: dict = {
|
3689
4201
|
# 'currency': currency['id'], # can choose up to 10, if not provided returns for all currencies by default
|
3690
4202
|
# 'direction': 'in', # 'out'
|
3691
4203
|
# 'bizType': 'DEPOSIT', # DEPOSIT, WITHDRAW, TRANSFER, SUB_TRANSFER,TRADE_EXCHANGE, MARGIN_EXCHANGE, KUCOIN_BONUS(optional)
|
@@ -3703,7 +4215,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3703
4215
|
marginMode = None
|
3704
4216
|
marginMode, params = self.handle_margin_mode_and_params('fetchLedger', params)
|
3705
4217
|
response = None
|
3706
|
-
if
|
4218
|
+
if hf:
|
3707
4219
|
if marginMode is not None:
|
3708
4220
|
response = await self.privateGetHfMarginAccountLedgers(self.extend(request, params))
|
3709
4221
|
else:
|
@@ -3768,15 +4280,6 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3768
4280
|
return config['v1']
|
3769
4281
|
return self.safe_value(config, 'cost', 1)
|
3770
4282
|
|
3771
|
-
def parse_borrow_rate_history(self, response, code, since, limit):
|
3772
|
-
result = []
|
3773
|
-
for i in range(0, len(response)):
|
3774
|
-
item = response[i]
|
3775
|
-
borrowRate = self.parse_borrow_rate(item)
|
3776
|
-
result.append(borrowRate)
|
3777
|
-
sorted = self.sort_by(result, 'timestamp')
|
3778
|
-
return self.filter_by_currency_since_limit(sorted, code, since, limit)
|
3779
|
-
|
3780
4283
|
def parse_borrow_rate(self, info, currency: Currency = None):
|
3781
4284
|
#
|
3782
4285
|
# {
|
@@ -3788,25 +4291,34 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3788
4291
|
# "timestamp": 1658531274508488480
|
3789
4292
|
# },
|
3790
4293
|
#
|
3791
|
-
|
3792
|
-
|
4294
|
+
# {
|
4295
|
+
# "createdAt": 1697783812257,
|
4296
|
+
# "currency": "XMR",
|
4297
|
+
# "interestAmount": "0.1",
|
4298
|
+
# "dayRatio": "0.001"
|
4299
|
+
# }
|
4300
|
+
#
|
4301
|
+
timestampId = self.safe_string_2(info, 'createdAt', 'timestamp')
|
4302
|
+
timestamp = self.parse_to_int(timestampId[0:13])
|
3793
4303
|
currencyId = self.safe_string(info, 'currency')
|
3794
4304
|
return {
|
3795
4305
|
'currency': self.safe_currency_code(currencyId, currency),
|
3796
|
-
'rate': self.
|
4306
|
+
'rate': self.safe_number_2(info, 'dailyIntRate', 'dayRatio'),
|
3797
4307
|
'period': 86400000,
|
3798
4308
|
'timestamp': timestamp,
|
3799
4309
|
'datetime': self.iso8601(timestamp),
|
3800
4310
|
'info': info,
|
3801
4311
|
}
|
3802
4312
|
|
3803
|
-
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]:
|
3804
4314
|
"""
|
3805
4315
|
fetch the interest owed by the user for borrowing currency for margin trading
|
3806
|
-
|
3807
|
-
|
3808
|
-
|
3809
|
-
|
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
|
3810
4322
|
:param int [since]: the earliest time in ms to fetch borrrow interest for
|
3811
4323
|
:param int [limit]: the maximum number of structures to retrieve
|
3812
4324
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -3815,14 +4327,19 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3815
4327
|
"""
|
3816
4328
|
await self.load_markets()
|
3817
4329
|
marginMode = None
|
3818
|
-
marginMode, params = self.handle_margin_mode_and_params('fetchBorrowInterest', params)
|
3819
|
-
|
3820
|
-
|
3821
|
-
request = {}
|
3822
|
-
response = None
|
4330
|
+
marginMode, params = self.handle_margin_mode_and_params('fetchBorrowInterest', params, 'cross')
|
4331
|
+
request: dict = {}
|
4332
|
+
currency = None
|
3823
4333
|
if code is not None:
|
3824
4334
|
currency = self.currency(code)
|
3825
|
-
|
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
|
3826
4343
|
if marginMode == 'isolated':
|
3827
4344
|
response = await self.privateGetIsolatedAccounts(self.extend(request, params))
|
3828
4345
|
else:
|
@@ -3893,9 +4410,11 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3893
4410
|
#
|
3894
4411
|
data = self.safe_dict(response, 'data', {})
|
3895
4412
|
assets = self.safe_list(data, 'assets', []) if (marginMode == 'isolated') else self.safe_list(data, 'accounts', [])
|
3896
|
-
|
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)
|
3897
4416
|
|
3898
|
-
def parse_borrow_interest(self, info, market: Market = None):
|
4417
|
+
def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
|
3899
4418
|
#
|
3900
4419
|
# Cross
|
3901
4420
|
#
|
@@ -3958,21 +4477,153 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3958
4477
|
interest = self.safe_number(info, 'accruedInterest')
|
3959
4478
|
currencyId = self.safe_string(info, 'currency')
|
3960
4479
|
return {
|
4480
|
+
'info': info,
|
3961
4481
|
'symbol': symbol,
|
3962
|
-
'marginMode': marginMode,
|
3963
4482
|
'currency': self.safe_currency_code(currencyId),
|
3964
4483
|
'interest': interest,
|
3965
4484
|
'interestRate': self.safe_number(info, 'dailyIntRate'),
|
3966
4485
|
'amountBorrowed': amountBorrowed,
|
4486
|
+
'marginMode': marginMode,
|
3967
4487
|
'timestamp': timestamp, # create time
|
3968
4488
|
'datetime': self.iso8601(timestamp),
|
3969
|
-
'info': info,
|
3970
4489
|
}
|
3971
4490
|
|
4491
|
+
async def fetch_borrow_rate_histories(self, codes=None, since: Int = None, limit: Int = None, params={}):
|
4492
|
+
"""
|
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
|
4494
|
+
|
4495
|
+
https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/get-cross-isolated-margin-interest-records
|
4496
|
+
|
4497
|
+
:param str[]|None codes: list of unified currency codes, default is None
|
4498
|
+
:param int [since]: timestamp in ms of the earliest borrowRate, default is None
|
4499
|
+
:param int [limit]: max number of borrow rate prices to return, default is None
|
4500
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4501
|
+
:param str [params.marginMode]: 'cross' or 'isolated' default is 'cross'
|
4502
|
+
:param int [params.until]: the latest time in ms to fetch entries for
|
4503
|
+
:returns dict: a dictionary of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>` indexed by the market symbol
|
4504
|
+
"""
|
4505
|
+
await self.load_markets()
|
4506
|
+
marginResult = self.handle_margin_mode_and_params('fetchBorrowRateHistories', params)
|
4507
|
+
marginMode = self.safe_string(marginResult, 0, 'cross')
|
4508
|
+
isIsolated = (marginMode == 'isolated') # True-isolated, False-cross
|
4509
|
+
request: dict = {
|
4510
|
+
'isIsolated': isIsolated,
|
4511
|
+
}
|
4512
|
+
if since is not None:
|
4513
|
+
request['startTime'] = since
|
4514
|
+
request, params = self.handle_until_option('endTime', request, params)
|
4515
|
+
if limit is not None:
|
4516
|
+
request['pageSize'] = limit # default:50, min:10, max:500
|
4517
|
+
response = await self.privateGetMarginInterest(self.extend(request, params))
|
4518
|
+
#
|
4519
|
+
# {
|
4520
|
+
# "code": "200000",
|
4521
|
+
# "data": {
|
4522
|
+
# "timestamp": 1710829939673,
|
4523
|
+
# "currentPage": 1,
|
4524
|
+
# "pageSize": 50,
|
4525
|
+
# "totalNum": 0,
|
4526
|
+
# "totalPage": 0,
|
4527
|
+
# "items": [
|
4528
|
+
# {
|
4529
|
+
# "createdAt": 1697783812257,
|
4530
|
+
# "currency": "XMR",
|
4531
|
+
# "interestAmount": "0.1",
|
4532
|
+
# "dayRatio": "0.001"
|
4533
|
+
# }
|
4534
|
+
# ]
|
4535
|
+
# }
|
4536
|
+
# }
|
4537
|
+
#
|
4538
|
+
data = self.safe_dict(response, 'data')
|
4539
|
+
rows = self.safe_list(data, 'items', [])
|
4540
|
+
return self.parse_borrow_rate_histories(rows, codes, since, limit)
|
4541
|
+
|
4542
|
+
async def fetch_borrow_rate_history(self, code: str, since: Int = None, limit: Int = None, params={}):
|
4543
|
+
"""
|
4544
|
+
retrieves a history of a currencies borrow interest rate at specific time slots
|
4545
|
+
|
4546
|
+
https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/get-cross-isolated-margin-interest-records
|
4547
|
+
|
4548
|
+
:param str code: unified currency code
|
4549
|
+
:param int [since]: timestamp for the earliest borrow rate
|
4550
|
+
:param int [limit]: the maximum number of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>` to retrieve
|
4551
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4552
|
+
:param str [params.marginMode]: 'cross' or 'isolated' default is 'cross'
|
4553
|
+
:param int [params.until]: the latest time in ms to fetch entries for
|
4554
|
+
:returns dict[]: an array of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>`
|
4555
|
+
"""
|
4556
|
+
await self.load_markets()
|
4557
|
+
marginResult = self.handle_margin_mode_and_params('fetchBorrowRateHistories', params)
|
4558
|
+
marginMode = self.safe_string(marginResult, 0, 'cross')
|
4559
|
+
isIsolated = (marginMode == 'isolated') # True-isolated, False-cross
|
4560
|
+
currency = self.currency(code)
|
4561
|
+
request: dict = {
|
4562
|
+
'isIsolated': isIsolated,
|
4563
|
+
'currency': currency['id'],
|
4564
|
+
}
|
4565
|
+
if since is not None:
|
4566
|
+
request['startTime'] = since
|
4567
|
+
request, params = self.handle_until_option('endTime', request, params)
|
4568
|
+
if limit is not None:
|
4569
|
+
request['pageSize'] = limit # default:50, min:10, max:500
|
4570
|
+
response = await self.privateGetMarginInterest(self.extend(request, params))
|
4571
|
+
#
|
4572
|
+
# {
|
4573
|
+
# "code": "200000",
|
4574
|
+
# "data": {
|
4575
|
+
# "timestamp": 1710829939673,
|
4576
|
+
# "currentPage": 1,
|
4577
|
+
# "pageSize": 50,
|
4578
|
+
# "totalNum": 0,
|
4579
|
+
# "totalPage": 0,
|
4580
|
+
# "items": [
|
4581
|
+
# {
|
4582
|
+
# "createdAt": 1697783812257,
|
4583
|
+
# "currency": "XMR",
|
4584
|
+
# "interestAmount": "0.1",
|
4585
|
+
# "dayRatio": "0.001"
|
4586
|
+
# }
|
4587
|
+
# ]
|
4588
|
+
# }
|
4589
|
+
# }
|
4590
|
+
#
|
4591
|
+
data = self.safe_dict(response, 'data')
|
4592
|
+
rows = self.safe_list(data, 'items', [])
|
4593
|
+
return self.parse_borrow_rate_history(rows, code, since, limit)
|
4594
|
+
|
4595
|
+
def parse_borrow_rate_histories(self, response, codes, since, limit):
|
4596
|
+
#
|
4597
|
+
# [
|
4598
|
+
# {
|
4599
|
+
# "createdAt": 1697783812257,
|
4600
|
+
# "currency": "XMR",
|
4601
|
+
# "interestAmount": "0.1",
|
4602
|
+
# "dayRatio": "0.001"
|
4603
|
+
# }
|
4604
|
+
# ]
|
4605
|
+
#
|
4606
|
+
borrowRateHistories: dict = {}
|
4607
|
+
for i in range(0, len(response)):
|
4608
|
+
item = response[i]
|
4609
|
+
code = self.safe_currency_code(self.safe_string(item, 'currency'))
|
4610
|
+
if codes is None or self.in_array(code, codes):
|
4611
|
+
if not (code in borrowRateHistories):
|
4612
|
+
borrowRateHistories[code] = []
|
4613
|
+
borrowRateStructure = self.parse_borrow_rate(item)
|
4614
|
+
borrowRateHistories[code].append(borrowRateStructure)
|
4615
|
+
keys = list(borrowRateHistories.keys())
|
4616
|
+
for i in range(0, len(keys)):
|
4617
|
+
code = keys[i]
|
4618
|
+
borrowRateHistories[code] = self.filter_by_currency_since_limit(borrowRateHistories[code], code, since, limit)
|
4619
|
+
return borrowRateHistories
|
4620
|
+
|
3972
4621
|
async def borrow_cross_margin(self, code: str, amount: float, params={}):
|
3973
4622
|
"""
|
3974
4623
|
create a loan to borrow margin
|
3975
|
-
|
4624
|
+
|
4625
|
+
https://docs.kucoin.com/#1-margin-borrowing
|
4626
|
+
|
3976
4627
|
:param str code: unified currency code of the currency to borrow
|
3977
4628
|
:param float amount: the amount to borrow
|
3978
4629
|
:param dict [params]: extra parameters specific to the exchange API endpoints
|
@@ -3981,7 +4632,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3981
4632
|
"""
|
3982
4633
|
await self.load_markets()
|
3983
4634
|
currency = self.currency(code)
|
3984
|
-
request = {
|
4635
|
+
request: dict = {
|
3985
4636
|
'currency': currency['id'],
|
3986
4637
|
'size': self.currency_to_precision(code, amount),
|
3987
4638
|
'timeInForce': 'FOK',
|
@@ -4005,7 +4656,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4005
4656
|
async def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
|
4006
4657
|
"""
|
4007
4658
|
create a loan to borrow margin
|
4008
|
-
|
4659
|
+
|
4660
|
+
https://docs.kucoin.com/#1-margin-borrowing
|
4661
|
+
|
4009
4662
|
:param str symbol: unified market symbol, required for isolated margin
|
4010
4663
|
:param str code: unified currency code of the currency to borrow
|
4011
4664
|
:param float amount: the amount to borrow
|
@@ -4016,7 +4669,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4016
4669
|
await self.load_markets()
|
4017
4670
|
market = self.market(symbol)
|
4018
4671
|
currency = self.currency(code)
|
4019
|
-
request = {
|
4672
|
+
request: dict = {
|
4020
4673
|
'currency': currency['id'],
|
4021
4674
|
'size': self.currency_to_precision(code, amount),
|
4022
4675
|
'symbol': market['id'],
|
@@ -4042,7 +4695,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4042
4695
|
async def repay_cross_margin(self, code: str, amount, params={}):
|
4043
4696
|
"""
|
4044
4697
|
repay borrowed margin and interest
|
4045
|
-
|
4698
|
+
|
4699
|
+
https://docs.kucoin.com/#2-repayment
|
4700
|
+
|
4046
4701
|
:param str code: unified currency code of the currency to repay
|
4047
4702
|
:param float amount: the amount to repay
|
4048
4703
|
:param dict [params]: extra parameters specific to the exchange API endpoints
|
@@ -4050,7 +4705,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4050
4705
|
"""
|
4051
4706
|
await self.load_markets()
|
4052
4707
|
currency = self.currency(code)
|
4053
|
-
request = {
|
4708
|
+
request: dict = {
|
4054
4709
|
'currency': currency['id'],
|
4055
4710
|
'size': self.currency_to_precision(code, amount),
|
4056
4711
|
}
|
@@ -4073,7 +4728,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4073
4728
|
async def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
|
4074
4729
|
"""
|
4075
4730
|
repay borrowed margin and interest
|
4076
|
-
|
4731
|
+
|
4732
|
+
https://docs.kucoin.com/#2-repayment
|
4733
|
+
|
4077
4734
|
:param str symbol: unified market symbol
|
4078
4735
|
:param str code: unified currency code of the currency to repay
|
4079
4736
|
:param float amount: the amount to repay
|
@@ -4083,7 +4740,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4083
4740
|
await self.load_markets()
|
4084
4741
|
market = self.market(symbol)
|
4085
4742
|
currency = self.currency(code)
|
4086
|
-
request = {
|
4743
|
+
request: dict = {
|
4087
4744
|
'currency': currency['id'],
|
4088
4745
|
'size': self.currency_to_precision(code, amount),
|
4089
4746
|
'symbol': market['id'],
|
@@ -4127,7 +4784,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4127
4784
|
async def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
|
4128
4785
|
"""
|
4129
4786
|
fetch deposit and withdraw fees - *IMPORTANT* use fetchDepositWithdrawFee to get more in-depth info
|
4130
|
-
|
4787
|
+
|
4788
|
+
https://docs.kucoin.com/#get-currencies
|
4789
|
+
|
4131
4790
|
:param str[]|None codes: list of unified currency codes
|
4132
4791
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4133
4792
|
:returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
|
@@ -4155,6 +4814,38 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4155
4814
|
data = self.safe_list(response, 'data', [])
|
4156
4815
|
return self.parse_deposit_withdraw_fees(data, codes, 'currency')
|
4157
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
|
+
|
4158
4849
|
def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
|
4159
4850
|
#
|
4160
4851
|
# the v2 URL is https://openapi-v2.kucoin.com/api/v1/endpoint
|
@@ -4170,12 +4861,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4170
4861
|
endpoint = '/api/' + version + '/' + self.implode_params(path, params)
|
4171
4862
|
if api == 'webExchange':
|
4172
4863
|
endpoint = '/' + self.implode_params(path, params)
|
4864
|
+
if api == 'earn':
|
4865
|
+
endpoint = '/api/v1/' + self.implode_params(path, params)
|
4173
4866
|
query = self.omit(params, self.extract_params(path))
|
4174
4867
|
endpart = ''
|
4175
4868
|
headers = headers if (headers is not None) else {}
|
4176
4869
|
url = self.urls['api'][api]
|
4177
4870
|
if not self.is_empty(query):
|
4178
|
-
if (method == 'GET') or (method == 'DELETE'):
|
4871
|
+
if ((method == 'GET') or (method == 'DELETE')) and (path != 'orders/multi-cancel'):
|
4179
4872
|
endpoint += '?' + self.rawencode(query)
|
4180
4873
|
else:
|
4181
4874
|
body = self.json(query)
|
@@ -4185,7 +4878,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4185
4878
|
isFuturePrivate = (api == 'futuresPrivate')
|
4186
4879
|
isPrivate = (api == 'private')
|
4187
4880
|
isBroker = (api == 'broker')
|
4188
|
-
|
4881
|
+
isEarn = (api == 'earn')
|
4882
|
+
if isPrivate or isFuturePrivate or isBroker or isEarn:
|
4189
4883
|
self.check_required_credentials()
|
4190
4884
|
timestamp = str(self.nonce())
|
4191
4885
|
headers = self.extend({
|
@@ -4211,13 +4905,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4211
4905
|
partnerSignature = self.hmac(self.encode(partnerPayload), self.encode(partnerSecret), hashlib.sha256, 'base64')
|
4212
4906
|
headers['KC-API-PARTNER-SIGN'] = partnerSignature
|
4213
4907
|
headers['KC-API-PARTNER'] = partnerId
|
4908
|
+
headers['KC-API-PARTNER-VERIFY'] = 'true'
|
4214
4909
|
if isBroker:
|
4215
4910
|
brokerName = self.safe_string(partner, 'name')
|
4216
4911
|
if brokerName is not None:
|
4217
4912
|
headers['KC-BROKER-NAME'] = brokerName
|
4218
4913
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
4219
4914
|
|
4220
|
-
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):
|
4221
4916
|
if not response:
|
4222
4917
|
self.throw_broadly_matched_exception(self.exceptions['broad'], body, body)
|
4223
4918
|
return None
|
@@ -4229,7 +4924,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4229
4924
|
#
|
4230
4925
|
errorCode = self.safe_string(response, 'code')
|
4231
4926
|
message = self.safe_string_2(response, 'msg', 'data', '')
|
4232
|
-
feedback = self.id + ' ' +
|
4927
|
+
feedback = self.id + ' ' + body
|
4233
4928
|
self.throw_exactly_matched_exception(self.exceptions['exact'], message, feedback)
|
4234
4929
|
self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
|
4235
4930
|
self.throw_broadly_matched_exception(self.exceptions['broad'], body, feedback)
|