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