ccxt 4.2.76__py2.py3-none-any.whl → 4.4.48__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +36 -14
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +112 -48
- ccxt/abstract/binancecoinm.py +112 -48
- ccxt/abstract/binanceus.py +147 -83
- ccxt/abstract/binanceusdm.py +112 -48
- ccxt/abstract/bingx.py +133 -78
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitfinex1.py +69 -0
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +8 -1
- ccxt/abstract/bitmart.py +13 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitpanda.py +0 -12
- ccxt/abstract/bitrue.py +3 -3
- ccxt/abstract/bitstamp.py +26 -3
- ccxt/abstract/blofin.py +24 -0
- ccxt/abstract/btcbox.py +1 -0
- ccxt/abstract/bybit.py +29 -14
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbase.py +6 -0
- ccxt/abstract/coinbaseadvanced.py +94 -0
- ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/coincatch.py +94 -0
- ccxt/abstract/coinex.py +233 -123
- ccxt/abstract/coinmetro.py +1 -0
- ccxt/abstract/cryptocom.py +14 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/gate.py +20 -0
- ccxt/abstract/gateio.py +20 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hashkey.py +67 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +4 -3
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +25 -0
- ccxt/abstract/kucoinfutures.py +35 -0
- ccxt/abstract/luno.py +2 -0
- ccxt/abstract/mexc.py +4 -0
- ccxt/abstract/myokx.py +340 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +30 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/oxfun.py +34 -0
- ccxt/abstract/paradex.py +40 -0
- ccxt/abstract/phemex.py +1 -0
- ccxt/abstract/upbit.py +4 -0
- ccxt/abstract/vertex.py +19 -0
- ccxt/abstract/whitebit.py +31 -1
- ccxt/abstract/woo.py +6 -2
- ccxt/abstract/woofipro.py +119 -0
- ccxt/abstract/xt.py +153 -0
- ccxt/abstract/zonda.py +6 -0
- ccxt/ace.py +164 -60
- ccxt/alpaca.py +727 -63
- ccxt/ascendex.py +395 -249
- ccxt/async_support/__init__.py +36 -14
- ccxt/async_support/ace.py +164 -60
- ccxt/async_support/alpaca.py +727 -63
- ccxt/async_support/ascendex.py +396 -249
- ccxt/async_support/base/exchange.py +531 -155
- ccxt/async_support/base/ws/aiohttp_client.py +28 -5
- ccxt/async_support/base/ws/cache.py +3 -2
- ccxt/async_support/base/ws/client.py +26 -5
- ccxt/async_support/base/ws/fast_client.py +4 -3
- ccxt/async_support/base/ws/functions.py +1 -1
- ccxt/async_support/base/ws/future.py +40 -31
- ccxt/async_support/base/ws/order_book_side.py +3 -0
- ccxt/async_support/bequant.py +1 -1
- ccxt/async_support/bigone.py +329 -202
- ccxt/async_support/binance.py +3513 -1511
- ccxt/async_support/binancecoinm.py +2 -1
- ccxt/async_support/binanceus.py +12 -1
- ccxt/async_support/binanceusdm.py +3 -1
- ccxt/async_support/bingx.py +3105 -881
- ccxt/async_support/bit2c.py +119 -38
- ccxt/async_support/bitbank.py +215 -76
- ccxt/async_support/bitbns.py +124 -53
- ccxt/async_support/bitfinex.py +3236 -1078
- ccxt/async_support/bitfinex1.py +1711 -0
- ccxt/async_support/bitflyer.py +239 -50
- ccxt/async_support/bitget.py +1513 -563
- ccxt/async_support/bithumb.py +201 -67
- ccxt/async_support/bitmart.py +1320 -435
- ccxt/async_support/bitmex.py +308 -111
- ccxt/async_support/bitopro.py +256 -96
- ccxt/async_support/bitrue.py +365 -233
- ccxt/async_support/bitso.py +201 -89
- ccxt/async_support/bitstamp.py +438 -269
- ccxt/async_support/bitteam.py +179 -73
- ccxt/async_support/bitvavo.py +180 -70
- ccxt/async_support/bl3p.py +92 -25
- ccxt/async_support/blockchaincom.py +193 -79
- ccxt/async_support/blofin.py +403 -150
- ccxt/async_support/btcalpha.py +161 -55
- ccxt/async_support/btcbox.py +250 -34
- ccxt/async_support/btcmarkets.py +232 -85
- ccxt/async_support/btcturk.py +159 -60
- ccxt/async_support/bybit.py +2326 -1255
- ccxt/async_support/cex.py +1409 -1329
- ccxt/async_support/coinbase.py +1455 -288
- ccxt/async_support/coinbaseadvanced.py +17 -0
- ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/async_support/coinbaseinternational.py +428 -88
- ccxt/async_support/coincatch.py +5152 -0
- ccxt/async_support/coincheck.py +121 -38
- ccxt/async_support/coinex.py +4020 -3339
- ccxt/async_support/coinlist.py +273 -116
- ccxt/async_support/coinmate.py +204 -97
- ccxt/async_support/coinmetro.py +203 -110
- ccxt/async_support/coinone.py +142 -68
- ccxt/async_support/coinsph.py +206 -89
- ccxt/async_support/coinspot.py +137 -62
- ccxt/async_support/cryptocom.py +515 -185
- ccxt/async_support/currencycom.py +203 -85
- ccxt/async_support/defx.py +2066 -0
- ccxt/async_support/delta.py +467 -158
- ccxt/async_support/deribit.py +558 -324
- ccxt/async_support/digifinex.py +340 -223
- ccxt/async_support/ellipx.py +1826 -0
- ccxt/async_support/exmo.py +259 -128
- ccxt/async_support/gate.py +1473 -464
- ccxt/async_support/gemini.py +206 -84
- ccxt/async_support/hashkey.py +4164 -0
- ccxt/async_support/hitbtc.py +334 -178
- ccxt/async_support/hollaex.py +134 -83
- ccxt/async_support/htx.py +1095 -563
- ccxt/async_support/huobijp.py +105 -56
- ccxt/async_support/hyperliquid.py +1634 -269
- ccxt/async_support/idex.py +148 -95
- ccxt/async_support/independentreserve.py +236 -31
- ccxt/async_support/indodax.py +165 -62
- ccxt/async_support/kraken.py +871 -354
- ccxt/async_support/krakenfutures.py +324 -100
- ccxt/async_support/kucoin.py +1050 -355
- ccxt/async_support/kucoinfutures.py +1004 -149
- ccxt/async_support/kuna.py +138 -106
- ccxt/async_support/latoken.py +135 -79
- ccxt/async_support/lbank.py +290 -113
- ccxt/async_support/luno.py +112 -62
- ccxt/async_support/lykke.py +104 -55
- ccxt/async_support/mercado.py +36 -29
- ccxt/async_support/mexc.py +995 -429
- ccxt/async_support/myokx.py +43 -0
- ccxt/async_support/ndax.py +163 -82
- ccxt/async_support/novadax.py +121 -75
- ccxt/async_support/oceanex.py +175 -59
- ccxt/async_support/okcoin.py +222 -163
- ccxt/async_support/okx.py +1777 -455
- ccxt/async_support/onetrading.py +132 -414
- ccxt/async_support/oxfun.py +2832 -0
- ccxt/async_support/p2b.py +79 -51
- ccxt/async_support/paradex.py +2017 -0
- ccxt/async_support/paymium.py +56 -32
- ccxt/async_support/phemex.py +572 -196
- ccxt/async_support/poloniex.py +218 -95
- ccxt/async_support/poloniexfutures.py +260 -92
- ccxt/async_support/probit.py +143 -110
- ccxt/async_support/timex.py +123 -70
- ccxt/async_support/tokocrypto.py +129 -93
- ccxt/async_support/tradeogre.py +39 -25
- ccxt/async_support/upbit.py +322 -113
- ccxt/async_support/vertex.py +2983 -0
- ccxt/async_support/wavesexchange.py +227 -173
- ccxt/async_support/wazirx.py +145 -65
- ccxt/async_support/whitebit.py +533 -138
- ccxt/async_support/woo.py +1155 -295
- ccxt/async_support/woofipro.py +2716 -0
- ccxt/async_support/xt.py +4628 -0
- ccxt/async_support/yobit.py +160 -92
- ccxt/async_support/zaif.py +80 -33
- ccxt/async_support/zonda.py +140 -69
- ccxt/base/errors.py +51 -20
- ccxt/base/exchange.py +1729 -482
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +223 -4
- ccxt/bequant.py +1 -1
- ccxt/bigone.py +329 -202
- ccxt/binance.py +3513 -1511
- ccxt/binancecoinm.py +2 -1
- ccxt/binanceus.py +12 -1
- ccxt/binanceusdm.py +3 -1
- ccxt/bingx.py +3105 -881
- ccxt/bit2c.py +119 -38
- ccxt/bitbank.py +215 -76
- ccxt/bitbns.py +124 -53
- ccxt/bitfinex.py +3235 -1078
- ccxt/bitfinex1.py +1710 -0
- ccxt/bitflyer.py +239 -50
- ccxt/bitget.py +1513 -563
- ccxt/bithumb.py +200 -67
- ccxt/bitmart.py +1320 -435
- ccxt/bitmex.py +308 -111
- ccxt/bitopro.py +256 -96
- ccxt/bitrue.py +365 -233
- ccxt/bitso.py +201 -89
- ccxt/bitstamp.py +438 -269
- ccxt/bitteam.py +179 -73
- ccxt/bitvavo.py +180 -70
- ccxt/bl3p.py +92 -25
- ccxt/blockchaincom.py +193 -79
- ccxt/blofin.py +403 -150
- ccxt/btcalpha.py +161 -55
- ccxt/btcbox.py +250 -34
- ccxt/btcmarkets.py +232 -85
- ccxt/btcturk.py +159 -60
- ccxt/bybit.py +2326 -1255
- ccxt/cex.py +1408 -1329
- ccxt/coinbase.py +1455 -288
- ccxt/coinbaseadvanced.py +17 -0
- ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/coinbaseinternational.py +428 -88
- ccxt/coincatch.py +5152 -0
- ccxt/coincheck.py +121 -38
- ccxt/coinex.py +4020 -3339
- ccxt/coinlist.py +273 -116
- ccxt/coinmate.py +204 -97
- ccxt/coinmetro.py +203 -110
- ccxt/coinone.py +142 -68
- ccxt/coinsph.py +206 -89
- ccxt/coinspot.py +137 -62
- ccxt/cryptocom.py +515 -185
- ccxt/currencycom.py +203 -85
- ccxt/defx.py +2065 -0
- ccxt/delta.py +467 -158
- ccxt/deribit.py +558 -324
- ccxt/digifinex.py +340 -223
- ccxt/ellipx.py +1826 -0
- ccxt/exmo.py +259 -128
- ccxt/gate.py +1473 -464
- ccxt/gemini.py +206 -84
- ccxt/hashkey.py +4164 -0
- ccxt/hitbtc.py +334 -178
- ccxt/hollaex.py +134 -83
- ccxt/htx.py +1095 -563
- ccxt/huobijp.py +105 -56
- ccxt/hyperliquid.py +1633 -269
- ccxt/idex.py +148 -95
- ccxt/independentreserve.py +235 -31
- ccxt/indodax.py +165 -62
- ccxt/kraken.py +871 -354
- ccxt/krakenfutures.py +324 -100
- ccxt/kucoin.py +1050 -355
- ccxt/kucoinfutures.py +1004 -149
- ccxt/kuna.py +138 -106
- ccxt/latoken.py +135 -79
- ccxt/lbank.py +290 -113
- ccxt/luno.py +112 -62
- ccxt/lykke.py +104 -55
- ccxt/mercado.py +36 -29
- ccxt/mexc.py +994 -429
- ccxt/myokx.py +43 -0
- ccxt/ndax.py +163 -82
- ccxt/novadax.py +121 -75
- ccxt/oceanex.py +175 -59
- ccxt/okcoin.py +222 -163
- ccxt/okx.py +1777 -455
- ccxt/onetrading.py +132 -414
- ccxt/oxfun.py +2831 -0
- ccxt/p2b.py +79 -51
- ccxt/paradex.py +2017 -0
- ccxt/paymium.py +56 -32
- ccxt/phemex.py +572 -196
- ccxt/poloniex.py +218 -95
- ccxt/poloniexfutures.py +260 -92
- ccxt/pro/__init__.py +29 -5
- ccxt/pro/alpaca.py +32 -17
- ccxt/pro/ascendex.py +63 -15
- ccxt/pro/bequant.py +4 -0
- ccxt/pro/binance.py +1596 -329
- ccxt/pro/binancecoinm.py +1 -0
- ccxt/pro/binanceus.py +2 -9
- ccxt/pro/binanceusdm.py +2 -0
- ccxt/pro/bingx.py +527 -134
- ccxt/pro/bitcoincom.py +4 -1
- ccxt/pro/bitfinex.py +731 -266
- ccxt/pro/bitfinex1.py +635 -0
- ccxt/pro/bitget.py +726 -357
- ccxt/pro/bithumb.py +380 -0
- ccxt/pro/bitmart.py +138 -39
- ccxt/pro/bitmex.py +199 -40
- ccxt/pro/bitopro.py +25 -13
- ccxt/pro/bitrue.py +31 -32
- ccxt/pro/bitstamp.py +7 -6
- ccxt/pro/bitvavo.py +204 -82
- ccxt/pro/blockchaincom.py +30 -17
- ccxt/pro/blofin.py +692 -0
- ccxt/pro/bybit.py +791 -82
- ccxt/pro/cex.py +99 -51
- ccxt/pro/coinbase.py +220 -30
- ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
- ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
- ccxt/pro/coinbaseinternational.py +193 -30
- ccxt/pro/coincatch.py +1464 -0
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +967 -661
- ccxt/pro/coinone.py +17 -10
- ccxt/pro/cryptocom.py +446 -66
- ccxt/pro/currencycom.py +11 -10
- ccxt/pro/defx.py +832 -0
- ccxt/pro/deribit.py +168 -32
- ccxt/pro/exmo.py +253 -21
- ccxt/pro/gate.py +729 -64
- ccxt/pro/gemini.py +44 -26
- ccxt/pro/hashkey.py +802 -0
- ccxt/pro/hitbtc.py +208 -103
- ccxt/pro/hollaex.py +25 -9
- ccxt/pro/htx.py +83 -39
- ccxt/pro/huobijp.py +17 -16
- ccxt/pro/hyperliquid.py +502 -31
- ccxt/pro/idex.py +28 -13
- ccxt/pro/independentreserve.py +21 -16
- ccxt/pro/kraken.py +298 -51
- ccxt/pro/krakenfutures.py +166 -75
- ccxt/pro/kucoin.py +395 -77
- ccxt/pro/kucoinfutures.py +400 -99
- ccxt/pro/lbank.py +52 -31
- ccxt/pro/luno.py +12 -10
- ccxt/pro/mexc.py +400 -50
- ccxt/pro/myokx.py +28 -0
- ccxt/pro/ndax.py +25 -12
- ccxt/pro/okcoin.py +28 -9
- ccxt/pro/okx.py +935 -124
- ccxt/pro/onetrading.py +41 -24
- ccxt/pro/oxfun.py +1054 -0
- ccxt/pro/p2b.py +100 -24
- ccxt/pro/paradex.py +352 -0
- ccxt/pro/phemex.py +93 -34
- ccxt/pro/poloniex.py +129 -50
- ccxt/pro/poloniexfutures.py +53 -32
- ccxt/pro/probit.py +93 -86
- ccxt/pro/upbit.py +401 -8
- ccxt/pro/vertex.py +943 -0
- ccxt/pro/wazirx.py +46 -28
- ccxt/pro/whitebit.py +65 -12
- ccxt/pro/woo.py +486 -70
- ccxt/pro/woofipro.py +1271 -0
- ccxt/pro/xt.py +1067 -0
- ccxt/probit.py +143 -110
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/__init__.py +38 -0
- ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
- ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
- ccxt/static_dependencies/lark/ast_utils.py +59 -0
- ccxt/static_dependencies/lark/common.py +86 -0
- ccxt/static_dependencies/lark/exceptions.py +292 -0
- ccxt/static_dependencies/lark/grammar.py +130 -0
- ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
- ccxt/static_dependencies/lark/indenter.py +143 -0
- ccxt/static_dependencies/lark/lark.py +658 -0
- ccxt/static_dependencies/lark/lexer.py +678 -0
- ccxt/static_dependencies/lark/load_grammar.py +1428 -0
- ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
- ccxt/static_dependencies/lark/parser_frontends.py +257 -0
- ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
- ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
- ccxt/static_dependencies/lark/parsers/earley.py +314 -0
- ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
- ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
- ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
- ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
- ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
- ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/lark/reconstruct.py +107 -0
- ccxt/static_dependencies/lark/tools/__init__.py +70 -0
- ccxt/static_dependencies/lark/tools/nearley.py +202 -0
- ccxt/static_dependencies/lark/tools/serialize.py +32 -0
- ccxt/static_dependencies/lark/tools/standalone.py +196 -0
- ccxt/static_dependencies/lark/tree.py +267 -0
- ccxt/static_dependencies/lark/tree_matcher.py +186 -0
- ccxt/static_dependencies/lark/tree_templates.py +180 -0
- ccxt/static_dependencies/lark/utils.py +343 -0
- ccxt/static_dependencies/lark/visitors.py +596 -0
- ccxt/static_dependencies/marshmallow/__init__.py +81 -0
- ccxt/static_dependencies/marshmallow/base.py +65 -0
- ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
- ccxt/static_dependencies/marshmallow/decorators.py +231 -0
- ccxt/static_dependencies/marshmallow/error_store.py +60 -0
- ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
- ccxt/static_dependencies/marshmallow/fields.py +2114 -0
- ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/schema.py +1228 -0
- ccxt/static_dependencies/marshmallow/types.py +12 -0
- ccxt/static_dependencies/marshmallow/utils.py +378 -0
- ccxt/static_dependencies/marshmallow/validate.py +678 -0
- ccxt/static_dependencies/marshmallow/warnings.py +2 -0
- ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
- ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
- ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
- ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
- ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
- ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
- ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/static_dependencies/starknet/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
- ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
- ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
- ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
- ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
- ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
- ccxt/static_dependencies/starknet/common.py +15 -0
- ccxt/static_dependencies/starknet/constants.py +39 -0
- ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
- ccxt/static_dependencies/starknet/hash/address.py +79 -0
- ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
- ccxt/static_dependencies/starknet/hash/selector.py +16 -0
- ccxt/static_dependencies/starknet/hash/storage.py +12 -0
- ccxt/static_dependencies/starknet/hash/utils.py +78 -0
- ccxt/static_dependencies/starknet/models/__init__.py +0 -0
- ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
- ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
- ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
- ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
- ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
- ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
- ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
- ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
- ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
- ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
- ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
- ccxt/static_dependencies/starknet/utils/schema.py +13 -0
- ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
- ccxt/static_dependencies/starkware/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
- ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
- ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
- ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
- ccxt/static_dependencies/sympy/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
- ccxt/static_dependencies/sympy/external/__init__.py +0 -0
- ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
- ccxt/static_dependencies/sympy/external/importtools.py +187 -0
- ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
- ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
- ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
- ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
- ccxt/test/{test_async.py → tests_async.py} +465 -407
- ccxt/test/tests_helpers.py +285 -0
- ccxt/test/tests_init.py +39 -0
- ccxt/test/{test_sync.py → tests_sync.py} +465 -409
- ccxt/timex.py +123 -70
- ccxt/tokocrypto.py +129 -93
- ccxt/tradeogre.py +39 -25
- ccxt/upbit.py +322 -113
- ccxt/vertex.py +2983 -0
- ccxt/wavesexchange.py +227 -173
- ccxt/wazirx.py +145 -65
- ccxt/whitebit.py +533 -138
- ccxt/woo.py +1155 -295
- ccxt/woofipro.py +2716 -0
- ccxt/xt.py +4627 -0
- ccxt/yobit.py +159 -92
- ccxt/zaif.py +80 -33
- ccxt/zonda.py +140 -69
- ccxt-4.4.48.dist-info/LICENSE.txt +21 -0
- ccxt-4.4.48.dist-info/METADATA +646 -0
- ccxt-4.4.48.dist-info/RECORD +669 -0
- {ccxt-4.2.76.dist-info → ccxt-4.4.48.dist-info}/WHEEL +1 -1
- ccxt/abstract/bitbay.py +0 -47
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3496
- ccxt/async_support/flowbtc.py +0 -34
- ccxt/bitbay.py +0 -17
- ccxt/bitfinex2.py +0 -3496
- ccxt/flowbtc.py +0 -34
- ccxt/hitbtc3.py +0 -16
- ccxt/pro/bitfinex2.py +0 -1081
- ccxt/test/base/__init__.py +0 -28
- ccxt/test/base/test_account.py +0 -26
- ccxt/test/base/test_balance.py +0 -56
- ccxt/test/base/test_borrow_interest.py +0 -35
- ccxt/test/base/test_borrow_rate.py +0 -32
- ccxt/test/base/test_calculate_fee.py +0 -51
- ccxt/test/base/test_crypto.py +0 -127
- ccxt/test/base/test_currency.py +0 -76
- ccxt/test/base/test_datetime.py +0 -103
- ccxt/test/base/test_decimal_to_precision.py +0 -392
- ccxt/test/base/test_deep_extend.py +0 -68
- ccxt/test/base/test_deposit_withdrawal.py +0 -50
- ccxt/test/base/test_exchange_datetime_functions.py +0 -76
- ccxt/test/base/test_funding_rate_history.py +0 -29
- ccxt/test/base/test_last_price.py +0 -32
- ccxt/test/base/test_ledger_entry.py +0 -45
- ccxt/test/base/test_ledger_item.py +0 -48
- ccxt/test/base/test_leverage_tier.py +0 -33
- ccxt/test/base/test_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -190
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -32
- ccxt/test/base/test_open_interest.py +0 -32
- ccxt/test/base/test_order.py +0 -64
- ccxt/test/base/test_order_book.py +0 -63
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -345
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -86
- ccxt/test/base/test_trade.py +0 -47
- ccxt/test/base/test_trading_fee.py +0 -26
- ccxt/test/base/test_transaction.py +0 -39
- ccxt-4.2.76.dist-info/METADATA +0 -626
- ccxt-4.2.76.dist-info/RECORD +0 -534
- {ccxt-4.2.76.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
ccxt/async_support/okx.py
CHANGED
@@ -7,29 +7,33 @@ from ccxt.async_support.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.okx import ImplicitAPI
|
8
8
|
import asyncio
|
9
9
|
import hashlib
|
10
|
-
from ccxt.base.types import Account, Balances, Currency, Greeks, Int, Leverage, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Account, Balances, BorrowInterest, Conversion, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, DepositAddress, Greeks, Int, LedgerEntry, Leverage, LeverageTier, LongShortRatio, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
|
11
11
|
from typing import List
|
12
|
+
from typing import Any
|
12
13
|
from ccxt.base.errors import ExchangeError
|
14
|
+
from ccxt.base.errors import AuthenticationError
|
13
15
|
from ccxt.base.errors import PermissionDenied
|
14
16
|
from ccxt.base.errors import AccountNotEnabled
|
15
17
|
from ccxt.base.errors import AccountSuspended
|
16
18
|
from ccxt.base.errors import ArgumentsRequired
|
17
19
|
from ccxt.base.errors import BadRequest
|
18
20
|
from ccxt.base.errors import BadSymbol
|
21
|
+
from ccxt.base.errors import OperationRejected
|
22
|
+
from ccxt.base.errors import ManualInteractionNeeded
|
19
23
|
from ccxt.base.errors import InsufficientFunds
|
20
24
|
from ccxt.base.errors import InvalidAddress
|
21
25
|
from ccxt.base.errors import InvalidOrder
|
22
26
|
from ccxt.base.errors import OrderNotFound
|
23
|
-
from ccxt.base.errors import
|
27
|
+
from ccxt.base.errors import ContractUnavailable
|
24
28
|
from ccxt.base.errors import NotSupported
|
25
29
|
from ccxt.base.errors import NetworkError
|
30
|
+
from ccxt.base.errors import DDoSProtection
|
26
31
|
from ccxt.base.errors import RateLimitExceeded
|
27
32
|
from ccxt.base.errors import ExchangeNotAvailable
|
28
33
|
from ccxt.base.errors import OnMaintenance
|
29
34
|
from ccxt.base.errors import InvalidNonce
|
30
35
|
from ccxt.base.errors import RequestTimeout
|
31
|
-
from ccxt.base.errors import
|
32
|
-
from ccxt.base.errors import ContractUnavailable
|
36
|
+
from ccxt.base.errors import CancelPending
|
33
37
|
from ccxt.base.decimal_to_precision import TICK_SIZE
|
34
38
|
from ccxt.base.precise import Precise
|
35
39
|
|
@@ -54,10 +58,13 @@ class okx(Exchange, ImplicitAPI):
|
|
54
58
|
'option': True,
|
55
59
|
'addMargin': True,
|
56
60
|
'cancelAllOrders': False,
|
61
|
+
'cancelAllOrdersAfter': True,
|
57
62
|
'cancelOrder': True,
|
58
63
|
'cancelOrders': True,
|
64
|
+
'cancelOrdersForSymbols': True,
|
59
65
|
'closeAllPositions': False,
|
60
66
|
'closePosition': True,
|
67
|
+
'createConvertTrade': True,
|
61
68
|
'createDepositAddress': False,
|
62
69
|
'createMarketBuyOrderWithCost': True,
|
63
70
|
'createMarketSellOrderWithCost': True,
|
@@ -83,6 +90,10 @@ class okx(Exchange, ImplicitAPI):
|
|
83
90
|
'fetchCanceledOrders': True,
|
84
91
|
'fetchClosedOrder': None,
|
85
92
|
'fetchClosedOrders': True,
|
93
|
+
'fetchConvertCurrencies': True,
|
94
|
+
'fetchConvertQuote': True,
|
95
|
+
'fetchConvertTrade': True,
|
96
|
+
'fetchConvertTradeHistory': True,
|
86
97
|
'fetchCrossBorrowRate': True,
|
87
98
|
'fetchCrossBorrowRates': True,
|
88
99
|
'fetchCurrencies': True,
|
@@ -95,6 +106,8 @@ class okx(Exchange, ImplicitAPI):
|
|
95
106
|
'fetchDepositWithdrawFee': 'emulated',
|
96
107
|
'fetchDepositWithdrawFees': True,
|
97
108
|
'fetchFundingHistory': True,
|
109
|
+
'fetchFundingInterval': True,
|
110
|
+
'fetchFundingIntervals': False,
|
98
111
|
'fetchFundingRate': True,
|
99
112
|
'fetchFundingRateHistory': True,
|
100
113
|
'fetchFundingRates': False,
|
@@ -107,9 +120,14 @@ class okx(Exchange, ImplicitAPI):
|
|
107
120
|
'fetchLedgerEntry': None,
|
108
121
|
'fetchLeverage': True,
|
109
122
|
'fetchLeverageTiers': False,
|
123
|
+
'fetchLongShortRatio': False,
|
124
|
+
'fetchLongShortRatioHistory': True,
|
125
|
+
'fetchMarginAdjustmentHistory': True,
|
110
126
|
'fetchMarketLeverageTiers': True,
|
111
127
|
'fetchMarkets': True,
|
112
128
|
'fetchMarkOHLCV': True,
|
129
|
+
'fetchMarkPrice': True,
|
130
|
+
'fetchMarkPrices': True,
|
113
131
|
'fetchMySettlementHistory': False,
|
114
132
|
'fetchMyTrades': True,
|
115
133
|
'fetchOHLCV': True,
|
@@ -117,15 +135,18 @@ class okx(Exchange, ImplicitAPI):
|
|
117
135
|
'fetchOpenInterestHistory': True,
|
118
136
|
'fetchOpenOrder': None,
|
119
137
|
'fetchOpenOrders': True,
|
138
|
+
'fetchOption': True,
|
139
|
+
'fetchOptionChain': True,
|
120
140
|
'fetchOrder': True,
|
121
141
|
'fetchOrderBook': True,
|
122
142
|
'fetchOrderBooks': False,
|
123
143
|
'fetchOrders': False,
|
124
144
|
'fetchOrderTrades': True,
|
125
|
-
'fetchPermissions': None,
|
126
145
|
'fetchPosition': True,
|
146
|
+
'fetchPositionHistory': 'emulated',
|
127
147
|
'fetchPositions': True,
|
128
148
|
'fetchPositionsForSymbol': True,
|
149
|
+
'fetchPositionsHistory': True,
|
129
150
|
'fetchPositionsRisk': False,
|
130
151
|
'fetchPremiumIndexOHLCV': False,
|
131
152
|
'fetchSettlementHistory': True,
|
@@ -149,6 +170,7 @@ class okx(Exchange, ImplicitAPI):
|
|
149
170
|
'fetchWithdrawalWhitelist': False,
|
150
171
|
'reduceMargin': True,
|
151
172
|
'repayCrossMargin': True,
|
173
|
+
'sandbox': True,
|
152
174
|
'setLeverage': True,
|
153
175
|
'setMargin': False,
|
154
176
|
'setMarginMode': True,
|
@@ -242,6 +264,7 @@ class okx(Exchange, ImplicitAPI):
|
|
242
264
|
'rubik/stat/margin/loan-ratio': 4,
|
243
265
|
# long/short
|
244
266
|
'rubik/stat/contracts/long-short-account-ratio': 4,
|
267
|
+
'rubik/stat/contracts/long-short-account-ratio-contract': 4,
|
245
268
|
'rubik/stat/contracts/open-interest-volume': 4,
|
246
269
|
'rubik/stat/option/open-interest-volume': 4,
|
247
270
|
# put/call
|
@@ -255,13 +278,20 @@ class okx(Exchange, ImplicitAPI):
|
|
255
278
|
'sprd/books': 1 / 2,
|
256
279
|
'sprd/ticker': 1,
|
257
280
|
'sprd/public-trades': 1 / 5,
|
281
|
+
'market/sprd-ticker': 2,
|
282
|
+
'market/sprd-candles': 2,
|
283
|
+
'market/sprd-history-candles': 2,
|
258
284
|
'tradingBot/grid/ai-param': 1,
|
259
285
|
'tradingBot/grid/min-investment': 1,
|
260
286
|
'tradingBot/public/rsi-back-testing': 1,
|
261
287
|
'asset/exchange-list': 5 / 3,
|
262
288
|
'finance/staking-defi/eth/apy-history': 5 / 3,
|
289
|
+
'finance/staking-defi/sol/apy-history': 5 / 3,
|
263
290
|
'finance/savings/lending-rate-summary': 5 / 3,
|
264
291
|
'finance/savings/lending-rate-history': 5 / 3,
|
292
|
+
'finance/fixed-loan/lending-offers': 10 / 3,
|
293
|
+
'finance/fixed-loan/lending-apy-history': 10 / 3,
|
294
|
+
'finance/fixed-loan/pending-lending-volume': 10 / 3,
|
265
295
|
# public broker
|
266
296
|
'finance/sfp/dcd/products': 2 / 3,
|
267
297
|
# copytrading
|
@@ -271,6 +301,7 @@ class okx(Exchange, ImplicitAPI):
|
|
271
301
|
'copytrading/public-preference-currency': 4,
|
272
302
|
'copytrading/public-current-subpositions': 4,
|
273
303
|
'copytrading/public-subpositions-history': 4,
|
304
|
+
'support/announcements-types': 20,
|
274
305
|
},
|
275
306
|
},
|
276
307
|
'private': {
|
@@ -322,12 +353,14 @@ class okx(Exchange, ImplicitAPI):
|
|
322
353
|
'asset/convert/history': 5 / 3,
|
323
354
|
'asset/monthly-statement': 2,
|
324
355
|
# account
|
356
|
+
'account/instruments': 1,
|
325
357
|
'account/balance': 2,
|
326
358
|
'account/positions': 2,
|
327
359
|
'account/positions-history': 100,
|
328
360
|
'account/account-position-risk': 2,
|
329
361
|
'account/bills': 5 / 3,
|
330
362
|
'account/bills-archive': 5 / 3,
|
363
|
+
'account/bills-history-archive': 2,
|
331
364
|
'account/config': 4,
|
332
365
|
'account/max-size': 1,
|
333
366
|
'account/max-avail-size': 1,
|
@@ -349,6 +382,12 @@ class okx(Exchange, ImplicitAPI):
|
|
349
382
|
'account/greeks': 2,
|
350
383
|
'account/position-tiers': 2,
|
351
384
|
'account/mmp-config': 4,
|
385
|
+
'account/fixed-loan/borrowing-limit': 4,
|
386
|
+
'account/fixed-loan/borrowing-quote': 5,
|
387
|
+
'account/fixed-loan/borrowing-orders-list': 5,
|
388
|
+
'account/spot-manual-borrow-repay': 10,
|
389
|
+
'account/set-auto-repay': 4,
|
390
|
+
'account/spot-borrow-repay-history': 4,
|
352
391
|
# subaccount
|
353
392
|
'users/subaccount/list': 10,
|
354
393
|
'account/subaccount/balances': 10 / 3,
|
@@ -385,6 +424,9 @@ class okx(Exchange, ImplicitAPI):
|
|
385
424
|
# eth staking
|
386
425
|
'finance/staking-defi/eth/balance': 5 / 3,
|
387
426
|
'finance/staking-defi/eth/purchase-redeem-history': 5 / 3,
|
427
|
+
'finance/staking-defi/eth/product-info': 3,
|
428
|
+
'finance/staking-defi/sol/balance': 5 / 3,
|
429
|
+
'finance/staking-defi/sol/purchase-redeem-history': 5 / 3,
|
388
430
|
# copytrading
|
389
431
|
'copytrading/current-subpositions': 1,
|
390
432
|
'copytrading/subpositions-history': 1,
|
@@ -412,6 +454,7 @@ class okx(Exchange, ImplicitAPI):
|
|
412
454
|
# affiliate
|
413
455
|
'affiliate/invitee/detail': 1,
|
414
456
|
'users/partner/if-rebate': 1,
|
457
|
+
'support/announcements': 4,
|
415
458
|
},
|
416
459
|
'post': {
|
417
460
|
# rfq
|
@@ -432,6 +475,7 @@ class okx(Exchange, ImplicitAPI):
|
|
432
475
|
'sprd/cancel-order': 1,
|
433
476
|
'sprd/mass-cancel': 1,
|
434
477
|
'sprd/amend-order': 1,
|
478
|
+
'sprd/cancel-all-after': 10,
|
435
479
|
# trade
|
436
480
|
'trade/order': 1 / 3,
|
437
481
|
'trade/batch-orders': 1 / 15,
|
@@ -474,6 +518,11 @@ class okx(Exchange, ImplicitAPI):
|
|
474
518
|
'account/set-account-level': 4,
|
475
519
|
'account/mmp-reset': 4,
|
476
520
|
'account/mmp-config': 100,
|
521
|
+
'account/fixed-loan/borrowing-order': 5,
|
522
|
+
'account/fixed-loan/amend-borrowing-order': 5,
|
523
|
+
'account/fixed-loan/manual-reborrow': 5,
|
524
|
+
'account/fixed-loan/repay-borrowing-order': 5,
|
525
|
+
'account/bills-history-archive': 72000, # 12 req/day
|
477
526
|
# subaccount
|
478
527
|
'users/subaccount/modify-apikey': 10,
|
479
528
|
'asset/subaccount/transfer': 10,
|
@@ -490,6 +539,7 @@ class okx(Exchange, ImplicitAPI):
|
|
490
539
|
'tradingBot/grid/compute-margin-balance': 1,
|
491
540
|
'tradingBot/grid/margin-balance': 1,
|
492
541
|
'tradingBot/grid/min-investment': 1,
|
542
|
+
'tradingBot/grid/adjust-investment': 1,
|
493
543
|
'tradingBot/signal/create-signal': 1,
|
494
544
|
'tradingBot/signal/order-algo': 1,
|
495
545
|
'tradingBot/signal/stop-order-algo': 1,
|
@@ -511,6 +561,8 @@ class okx(Exchange, ImplicitAPI):
|
|
511
561
|
# eth staking
|
512
562
|
'finance/staking-defi/eth/purchase': 5,
|
513
563
|
'finance/staking-defi/eth/redeem': 5,
|
564
|
+
'finance/staking-defi/sol/purchase': 5,
|
565
|
+
'finance/staking-defi/sol/redeem': 5,
|
514
566
|
# copytrading
|
515
567
|
'copytrading/algo-order': 1,
|
516
568
|
'copytrading/close-subposition': 1,
|
@@ -567,6 +619,7 @@ class okx(Exchange, ImplicitAPI):
|
|
567
619
|
# General Class
|
568
620
|
'1': ExchangeError, # Operation failed
|
569
621
|
'2': ExchangeError, # Bulk operation partially succeeded
|
622
|
+
'4088': ManualInteractionNeeded, # {"code":"4088","data":[],"msg":"You can’t trade or deposit until you’ve verified your identity again. Head to Identity Verification to complete it."}
|
570
623
|
'50000': BadRequest, # Body can not be empty
|
571
624
|
'50001': OnMaintenance, # Matching engine upgrading. Please try again later
|
572
625
|
'50002': BadRequest, # Json data format error
|
@@ -596,6 +649,7 @@ class okx(Exchange, ImplicitAPI):
|
|
596
649
|
'50027': PermissionDenied, # The account is restricted from trading
|
597
650
|
'50028': ExchangeError, # Unable to take the order, please reach out to support center for details
|
598
651
|
'50044': BadRequest, # Must select one broker type
|
652
|
+
'50061': ExchangeError, # You've reached the maximum order rate limit for self account.
|
599
653
|
'50062': ExchangeError, # This feature is currently unavailable.
|
600
654
|
# API Class
|
601
655
|
'50100': ExchangeError, # API frozen, please contact customer service
|
@@ -783,6 +837,18 @@ class okx(Exchange, ImplicitAPI):
|
|
783
837
|
# SPOT/MARGIN error codes 54000-54999
|
784
838
|
'54000': ExchangeError, # Margin transactions unavailable
|
785
839
|
'54001': ExchangeError, # Only Multi-currency margin account can be set to borrow coins automatically
|
840
|
+
'54008': InvalidOrder, # This operation is disabled by the 'mass cancel order' endpoint. Please enable it using self endpoint.
|
841
|
+
'54009': InvalidOrder, # The range of {param0} should be [{param1}, {param2}].
|
842
|
+
'54011': InvalidOrder, # 200 Pre-market trading contracts are only allowed to reduce the number of positions within 1 hour before delivery. Please modify or cancel the order.
|
843
|
+
# Trading bot Error Code from 55100 to 55999
|
844
|
+
'55100': InvalidOrder, # Take profit % should be within the range of {parameter1}-{parameter2}
|
845
|
+
'55101': InvalidOrder, # Stop loss % should be within the range of {parameter1}-{parameter2}
|
846
|
+
'55102': InvalidOrder, # Take profit % should be greater than the current bot’s PnL%
|
847
|
+
'55103': InvalidOrder, # Stop loss % should be less than the current bot’s PnL%
|
848
|
+
'55104': InvalidOrder, # Only futures grid supports take profit or stop loss based on profit percentage
|
849
|
+
'55111': InvalidOrder, # This signal name is in use, please try a new name
|
850
|
+
'55112': InvalidOrder, # This signal does not exist
|
851
|
+
'55113': InvalidOrder, # Create signal strategies with leverage greater than the maximum leverage of the instruments
|
786
852
|
# FUNDING error codes 58000-58999
|
787
853
|
'58000': ExchangeError, # Account type {0} does not supported when getting the sub-account balance
|
788
854
|
'58001': AuthenticationError, # Incorrect trade password
|
@@ -858,6 +924,11 @@ class okx(Exchange, ImplicitAPI):
|
|
858
924
|
'59301': ExchangeError, # Margin adjustment failed for exceeding the max limit
|
859
925
|
'59313': ExchangeError, # Unable to repay. You haven't borrowed any {ccy} {ccyPair} in Quick margin mode.
|
860
926
|
'59401': ExchangeError, # Holdings already reached the limit
|
927
|
+
'59410': OperationRejected, # You can only borrow self crypto if it supports borrowing and borrowing is enabled.
|
928
|
+
'59411': InsufficientFunds, # Manual borrowing failed. Your account's free margin is insufficient
|
929
|
+
'59412': OperationRejected, # Manual borrowing failed. The amount exceeds your borrowing limit.
|
930
|
+
'59413': OperationRejected, # You didn't borrow self crypto. No repayment needed.
|
931
|
+
'59414': BadRequest, # Manual borrowing failed. The minimum borrowing limit is {param0}.needed.
|
861
932
|
'59500': ExchangeError, # Only the APIKey of the main account has permission
|
862
933
|
'59501': ExchangeError, # Only 50 APIKeys can be created per account
|
863
934
|
'59502': ExchangeError, # Note name cannot be duplicate with the currently created APIKey note name
|
@@ -889,10 +960,36 @@ class okx(Exchange, ImplicitAPI):
|
|
889
960
|
'60017': BadRequest, # Invalid url path
|
890
961
|
'60018': BadRequest, # The {0} {1} {2} {3} {4} does not exist
|
891
962
|
'60019': BadRequest, # Invalid op {op}
|
963
|
+
'60020': ExchangeError, # APIKey subscription amount exceeds the limit
|
964
|
+
'60021': AccountNotEnabled, # This operation does not support multiple accounts login
|
965
|
+
'60022': AuthenticationError, # Bulk login partially succeeded
|
966
|
+
'60023': DDoSProtection, # Bulk login requests too frequent
|
967
|
+
'60024': AuthenticationError, # Wrong passphrase
|
968
|
+
'60025': ExchangeError, # Token subscription amount exceeds the limit
|
969
|
+
'60026': AuthenticationError, # Batch login by APIKey and token simultaneously is not supported
|
970
|
+
'60027': ArgumentsRequired, # Parameter {0} can not be empty
|
971
|
+
'60028': NotSupported, # The current operation is not supported by self URL
|
972
|
+
'60029': AccountNotEnabled, # Only users who are VIP5 and above in trading fee tier are allowed to subscribe to books-l2-tbt channel
|
973
|
+
'60030': AccountNotEnabled, # Only users who are VIP4 and above in trading fee tier are allowed to subscribe to books50-l2-tbt channel
|
974
|
+
'60031': AuthenticationError, # The WebSocket endpoint does not support multiple account batch login,
|
975
|
+
'60032': AuthenticationError, # API key doesn't exist,
|
892
976
|
'63999': ExchangeError, # Internal system error
|
977
|
+
'64000': BadRequest, # Subscription parameter uly is unavailable anymore, please replace uly with instFamily. More details can refer to: https://www.okx.com/help-center/changes-to-v5-api-websocket-subscription-parameter-and-url,
|
978
|
+
'64001': BadRequest, # This channel has been migrated to the business URL. Please subscribe using the new URL. More details can refer to: https://www.okx.com/help-center/changes-to-v5-api-websocket-subscription-parameter-and-url,
|
979
|
+
'64002': BadRequest, # This channel is not supported by business URL. Please use "/private" URL(for private channels), or "/public" URL(for public channels). More details can refer to: https://www.okx.com/help-center/changes-to-v5-api-websocket-subscription-parameter-and-url,
|
980
|
+
'64003': AccountNotEnabled, # Your trading fee tier doesnt meet the requirement to access self channel
|
893
981
|
'70010': BadRequest, # Timestamp parameters need to be in Unix timestamp format in milliseconds.
|
894
982
|
'70013': BadRequest, # endTs needs to be bigger than or equal to beginTs.
|
895
983
|
'70016': BadRequest, # Please specify your instrument settings for at least one instType.
|
984
|
+
'1009': BadRequest, # Request message exceeds the maximum frame length
|
985
|
+
'4001': AuthenticationError, # Login Failed
|
986
|
+
'4002': BadRequest, # Invalid Request
|
987
|
+
'4003': RateLimitExceeded, # APIKey subscription amount exceeds the limit 100
|
988
|
+
'4004': NetworkError, # No data received in 30s
|
989
|
+
'4005': ExchangeNotAvailable, # Buffer is full, cannot write data
|
990
|
+
'4006': BadRequest, # Abnormal disconnection
|
991
|
+
'4007': AuthenticationError, # API key has been updated or deleted. Please reconnect.
|
992
|
+
'4008': RateLimitExceeded, # The number of subscribed channels exceeds the maximum limit.
|
896
993
|
},
|
897
994
|
'broad': {
|
898
995
|
'Internal Server Error': ExchangeNotAvailable, # {"code":500,"data":{},"detailMsg":"","error_code":"500","error_message":"Internal Server Error","msg":"Internal Server Error"}
|
@@ -924,7 +1021,7 @@ class okx(Exchange, ImplicitAPI):
|
|
924
1021
|
'BHP': 'BHP',
|
925
1022
|
'APT': 'Aptos',
|
926
1023
|
'ARBONE': 'Arbitrum One',
|
927
|
-
'AVAXC': 'Avalanche C',
|
1024
|
+
'AVAXC': 'Avalanche C-Chain',
|
928
1025
|
'AVAXX': 'Avalanche X-Chain',
|
929
1026
|
'ARK': 'ARK',
|
930
1027
|
'AR': 'Arweave',
|
@@ -997,6 +1094,7 @@ class okx(Exchange, ImplicitAPI):
|
|
997
1094
|
'ZEC': 'Zcash',
|
998
1095
|
'ZIL': 'Zilliqa',
|
999
1096
|
'ZKSYNC': 'ZKSYNC',
|
1097
|
+
'OMNI': 'Omni',
|
1000
1098
|
# 'NEON3': 'N3', # tbd
|
1001
1099
|
# undetermined : "CELO-TOKEN", "Digital Cash", Khala
|
1002
1100
|
# todo: uncomment below after consensus
|
@@ -1042,6 +1140,8 @@ class okx(Exchange, ImplicitAPI):
|
|
1042
1140
|
'createOrder': 'privatePostTradeBatchOrders', # or 'privatePostTradeOrder' or 'privatePostTradeOrderAlgo'
|
1043
1141
|
'createMarketBuyOrderRequiresPrice': False,
|
1044
1142
|
'fetchMarkets': ['spot', 'future', 'swap', 'option'], # spot, future, swap, option
|
1143
|
+
'timeDifference': 0, # the difference between system clock and exchange server clock
|
1144
|
+
'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
|
1045
1145
|
'defaultType': 'spot', # 'funding', 'spot', 'margin', 'future', 'swap', 'option'
|
1046
1146
|
# 'fetchBalance': {
|
1047
1147
|
# 'type': 'spot', # 'funding', 'trading', 'spot'
|
@@ -1108,6 +1208,96 @@ class okx(Exchange, ImplicitAPI):
|
|
1108
1208
|
},
|
1109
1209
|
'brokerId': 'e847386590ce4dBC',
|
1110
1210
|
},
|
1211
|
+
'features': {
|
1212
|
+
'default': {
|
1213
|
+
'sandbox': True,
|
1214
|
+
'createOrder': {
|
1215
|
+
'marginMode': True,
|
1216
|
+
'triggerPrice': True,
|
1217
|
+
'triggerPriceType': {
|
1218
|
+
'last': True,
|
1219
|
+
'mark': True,
|
1220
|
+
'index': True,
|
1221
|
+
},
|
1222
|
+
'triggerDirection': False,
|
1223
|
+
'stopLossPrice': True,
|
1224
|
+
'takeProfitPrice': True,
|
1225
|
+
'attachedStopLossTakeProfit': {
|
1226
|
+
'triggerPriceType': {
|
1227
|
+
'last': True,
|
1228
|
+
'mark': True,
|
1229
|
+
'index': True,
|
1230
|
+
},
|
1231
|
+
'price': True,
|
1232
|
+
},
|
1233
|
+
'timeInForce': {
|
1234
|
+
'IOC': True,
|
1235
|
+
'FOK': True,
|
1236
|
+
'PO': True,
|
1237
|
+
'GTD': False,
|
1238
|
+
},
|
1239
|
+
'hedged': True,
|
1240
|
+
'trailing': True,
|
1241
|
+
'iceberg': True, # todo implement
|
1242
|
+
'leverage': False,
|
1243
|
+
'selfTradePrevention': True, # todo implement
|
1244
|
+
'marketBuyByCost': True,
|
1245
|
+
'marketBuyRequiresPrice': False,
|
1246
|
+
},
|
1247
|
+
'createOrders': {
|
1248
|
+
'max': 20,
|
1249
|
+
},
|
1250
|
+
'fetchMyTrades': {
|
1251
|
+
'marginMode': False,
|
1252
|
+
'daysBack': 90,
|
1253
|
+
'limit': 100,
|
1254
|
+
'untilDays': 10000,
|
1255
|
+
},
|
1256
|
+
'fetchOrder': {
|
1257
|
+
'marginMode': False,
|
1258
|
+
'trigger': True,
|
1259
|
+
'trailing': True,
|
1260
|
+
},
|
1261
|
+
'fetchOpenOrders': {
|
1262
|
+
'marginMode': False,
|
1263
|
+
'limit': 100,
|
1264
|
+
'trigger': True,
|
1265
|
+
'trailing': True,
|
1266
|
+
},
|
1267
|
+
'fetchOrders': None, # not supported
|
1268
|
+
'fetchClosedOrders': {
|
1269
|
+
'marginMode': False,
|
1270
|
+
'limit': 100,
|
1271
|
+
'daysBack': 90, # 3 months
|
1272
|
+
'daysBackCanceled': 1 / 12, # 2 hour
|
1273
|
+
'untilDays': None,
|
1274
|
+
'trigger': True,
|
1275
|
+
'trailing': True,
|
1276
|
+
},
|
1277
|
+
'fetchOHLCV': {
|
1278
|
+
'limit': 300,
|
1279
|
+
},
|
1280
|
+
},
|
1281
|
+
'spot': {
|
1282
|
+
'extends': 'default',
|
1283
|
+
},
|
1284
|
+
'swap': {
|
1285
|
+
'linear': {
|
1286
|
+
'extends': 'default',
|
1287
|
+
},
|
1288
|
+
'inverse': {
|
1289
|
+
'extends': 'default',
|
1290
|
+
},
|
1291
|
+
},
|
1292
|
+
'future': {
|
1293
|
+
'linear': {
|
1294
|
+
'extends': 'default',
|
1295
|
+
},
|
1296
|
+
'inverse': {
|
1297
|
+
'extends': 'default',
|
1298
|
+
},
|
1299
|
+
},
|
1300
|
+
},
|
1111
1301
|
'commonCurrencies': {
|
1112
1302
|
# the exchange refers to ERC20 version of Aeternity(AEToken)
|
1113
1303
|
'AE': 'AET', # https://github.com/ccxt/ccxt/issues/4981
|
@@ -1115,26 +1305,18 @@ class okx(Exchange, ImplicitAPI):
|
|
1115
1305
|
},
|
1116
1306
|
})
|
1117
1307
|
|
1118
|
-
def handle_market_type_and_params(self, methodName, market=None, params={}):
|
1308
|
+
def handle_market_type_and_params(self, methodName: str, market: Market = None, params={}, defaultValue=None) -> Any:
|
1119
1309
|
instType = self.safe_string(params, 'instType')
|
1120
1310
|
params = self.omit(params, 'instType')
|
1121
1311
|
type = self.safe_string(params, 'type')
|
1122
1312
|
if (type is None) and (instType is not None):
|
1123
1313
|
params['type'] = instType
|
1124
|
-
return super(okx, self).handle_market_type_and_params(methodName, market, params)
|
1314
|
+
return super(okx, self).handle_market_type_and_params(methodName, market, params, defaultValue)
|
1125
1315
|
|
1126
1316
|
def convert_to_instrument_type(self, type):
|
1127
|
-
exchangeTypes = self.
|
1317
|
+
exchangeTypes = self.safe_dict(self.options, 'exchangeType', {})
|
1128
1318
|
return self.safe_string(exchangeTypes, type, type)
|
1129
1319
|
|
1130
|
-
def convert_expire_date(self, date):
|
1131
|
-
# parse YYMMDD to timestamp
|
1132
|
-
year = date[0:2]
|
1133
|
-
month = date[2:4]
|
1134
|
-
day = date[4:6]
|
1135
|
-
reconstructedDate = '20' + year + '-' + month + '-' + day + 'T00:00:00Z'
|
1136
|
-
return reconstructedDate
|
1137
|
-
|
1138
1320
|
def create_expired_option_market(self, symbol: str):
|
1139
1321
|
# support expired option contracts
|
1140
1322
|
quote = 'USD'
|
@@ -1196,7 +1378,7 @@ class okx(Exchange, ImplicitAPI):
|
|
1196
1378
|
'info': None,
|
1197
1379
|
}
|
1198
1380
|
|
1199
|
-
def safe_market(self, marketId=None, market=None, delimiter=None, marketType=None):
|
1381
|
+
def safe_market(self, marketId: Str = None, market: Market = None, delimiter: Str = None, marketType: Str = None) -> MarketInterface:
|
1200
1382
|
isOption = (marketId is not None) and ((marketId.find('-C') > -1) or (marketId.find('-P') > -1))
|
1201
1383
|
if isOption and not (marketId in self.markets_by_id):
|
1202
1384
|
# handle expired option contracts
|
@@ -1206,7 +1388,9 @@ class okx(Exchange, ImplicitAPI):
|
|
1206
1388
|
async def fetch_status(self, params={}):
|
1207
1389
|
"""
|
1208
1390
|
the latest known information on the availability of the exchange API
|
1209
|
-
|
1391
|
+
|
1392
|
+
https://www.okx.com/docs-v5/en/#status-get-status
|
1393
|
+
|
1210
1394
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1211
1395
|
:returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
|
1212
1396
|
"""
|
@@ -1231,9 +1415,9 @@ class okx(Exchange, ImplicitAPI):
|
|
1231
1415
|
# ]
|
1232
1416
|
# }
|
1233
1417
|
#
|
1234
|
-
data = self.
|
1418
|
+
data = self.safe_list(response, 'data', [])
|
1235
1419
|
dataLength = len(data)
|
1236
|
-
update = {
|
1420
|
+
update: dict = {
|
1237
1421
|
'updated': None,
|
1238
1422
|
'status': 'ok' if (dataLength == 0) else 'maintenance',
|
1239
1423
|
'eta': None,
|
@@ -1258,7 +1442,9 @@ class okx(Exchange, ImplicitAPI):
|
|
1258
1442
|
async def fetch_time(self, params={}):
|
1259
1443
|
"""
|
1260
1444
|
fetches the current integer timestamp in milliseconds from the exchange server
|
1261
|
-
|
1445
|
+
|
1446
|
+
https://www.okx.com/docs-v5/en/#public-data-rest-api-get-system-time
|
1447
|
+
|
1262
1448
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1263
1449
|
:returns int: the current integer timestamp in milliseconds from the exchange server
|
1264
1450
|
"""
|
@@ -1272,14 +1458,16 @@ class okx(Exchange, ImplicitAPI):
|
|
1272
1458
|
# "msg": ""
|
1273
1459
|
# }
|
1274
1460
|
#
|
1275
|
-
data = self.
|
1276
|
-
first = self.
|
1461
|
+
data = self.safe_list(response, 'data', [])
|
1462
|
+
first = self.safe_dict(data, 0, {})
|
1277
1463
|
return self.safe_integer(first, 'ts')
|
1278
1464
|
|
1279
1465
|
async def fetch_accounts(self, params={}) -> List[Account]:
|
1280
1466
|
"""
|
1281
1467
|
fetch all the accounts associated with a profile
|
1282
|
-
|
1468
|
+
|
1469
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-account-configuration
|
1470
|
+
|
1283
1471
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1284
1472
|
:returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
|
1285
1473
|
"""
|
@@ -1303,7 +1491,7 @@ class okx(Exchange, ImplicitAPI):
|
|
1303
1491
|
# "msg": ""
|
1304
1492
|
# }
|
1305
1493
|
#
|
1306
|
-
data = self.
|
1494
|
+
data = self.safe_list(response, 'data', [])
|
1307
1495
|
result = []
|
1308
1496
|
for i in range(0, len(data)):
|
1309
1497
|
account = data[i]
|
@@ -1318,14 +1506,21 @@ class okx(Exchange, ImplicitAPI):
|
|
1318
1506
|
})
|
1319
1507
|
return result
|
1320
1508
|
|
1321
|
-
|
1509
|
+
def nonce(self):
|
1510
|
+
return self.milliseconds() - self.options['timeDifference']
|
1511
|
+
|
1512
|
+
async def fetch_markets(self, params={}) -> List[Market]:
|
1322
1513
|
"""
|
1323
1514
|
retrieves data on all markets for okx
|
1324
|
-
|
1515
|
+
|
1516
|
+
https://www.okx.com/docs-v5/en/#rest-api-public-data-get-instruments
|
1517
|
+
|
1325
1518
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1326
1519
|
:returns dict[]: an array of objects representing market data
|
1327
1520
|
"""
|
1328
|
-
|
1521
|
+
if self.options['adjustForTimeDifference']:
|
1522
|
+
await self.load_time_difference()
|
1523
|
+
types = self.safe_list(self.options, 'fetchMarkets', [])
|
1329
1524
|
promises = []
|
1330
1525
|
result = []
|
1331
1526
|
for i in range(0, len(types)):
|
@@ -1335,7 +1530,7 @@ class okx(Exchange, ImplicitAPI):
|
|
1335
1530
|
result = self.array_concat(result, promises[i])
|
1336
1531
|
return result
|
1337
1532
|
|
1338
|
-
def parse_market(self, market) -> Market:
|
1533
|
+
def parse_market(self, market: dict) -> Market:
|
1339
1534
|
#
|
1340
1535
|
# {
|
1341
1536
|
# "alias": "", # self_week, next_week, quarter, next_quarter
|
@@ -1422,7 +1617,7 @@ class okx(Exchange, ImplicitAPI):
|
|
1422
1617
|
symbol = symbol + '-' + ymd + '-' + strikePrice + '-' + optionType
|
1423
1618
|
optionType = 'put' if (optionType == 'P') else 'call'
|
1424
1619
|
tickSize = self.safe_string(market, 'tickSz')
|
1425
|
-
fees = self.
|
1620
|
+
fees = self.safe_dict_2(self.fees, type, 'trading', {})
|
1426
1621
|
maxLeverage = self.safe_string(market, 'lever', '1')
|
1427
1622
|
maxLeverage = Precise.string_max(maxLeverage, '1')
|
1428
1623
|
maxSpotCost = self.safe_number(market, 'maxMktSz')
|
@@ -1448,7 +1643,7 @@ class okx(Exchange, ImplicitAPI):
|
|
1448
1643
|
'contractSize': self.safe_number(market, 'ctVal') if contract else None,
|
1449
1644
|
'expiry': expiry,
|
1450
1645
|
'expiryDatetime': self.iso8601(expiry),
|
1451
|
-
'strike': strikePrice,
|
1646
|
+
'strike': self.parse_number(strikePrice),
|
1452
1647
|
'optionType': optionType,
|
1453
1648
|
'created': self.safe_integer(market, 'listTime'),
|
1454
1649
|
'precision': {
|
@@ -1477,11 +1672,11 @@ class okx(Exchange, ImplicitAPI):
|
|
1477
1672
|
})
|
1478
1673
|
|
1479
1674
|
async def fetch_markets_by_type(self, type, params={}):
|
1480
|
-
request = {
|
1675
|
+
request: dict = {
|
1481
1676
|
'instType': self.convert_to_instrument_type(type),
|
1482
1677
|
}
|
1483
1678
|
if type == 'option':
|
1484
|
-
optionsUnderlying = self.
|
1679
|
+
optionsUnderlying = self.safe_list(self.options, 'defaultUnderlying', ['BTC-USD', 'ETH-USD'])
|
1485
1680
|
promises = []
|
1486
1681
|
for i in range(0, len(optionsUnderlying)):
|
1487
1682
|
underlying = optionsUnderlying[i]
|
@@ -1490,8 +1685,8 @@ class okx(Exchange, ImplicitAPI):
|
|
1490
1685
|
promisesResult = await asyncio.gather(*promises)
|
1491
1686
|
markets = []
|
1492
1687
|
for i in range(0, len(promisesResult)):
|
1493
|
-
res = self.
|
1494
|
-
options = self.
|
1688
|
+
res = self.safe_dict(promisesResult, i, {})
|
1689
|
+
options = self.safe_list(res, 'data', [])
|
1495
1690
|
markets = self.array_concat(markets, options)
|
1496
1691
|
return self.parse_markets(markets)
|
1497
1692
|
response = await self.publicGetPublicInstruments(self.extend(request, params))
|
@@ -1528,21 +1723,15 @@ class okx(Exchange, ImplicitAPI):
|
|
1528
1723
|
# "msg": ""
|
1529
1724
|
# }
|
1530
1725
|
#
|
1531
|
-
dataResponse = self.
|
1726
|
+
dataResponse = self.safe_list(response, 'data', [])
|
1532
1727
|
return self.parse_markets(dataResponse)
|
1533
1728
|
|
1534
|
-
def
|
1535
|
-
networksById = {
|
1536
|
-
'Bitcoin': 'BTC',
|
1537
|
-
'Omni': 'OMNI',
|
1538
|
-
'TRON': 'TRC20',
|
1539
|
-
}
|
1540
|
-
return self.safe_string(networksById, networkId, networkId)
|
1541
|
-
|
1542
|
-
async def fetch_currencies(self, params={}):
|
1729
|
+
async def fetch_currencies(self, params={}) -> Currencies:
|
1543
1730
|
"""
|
1544
1731
|
fetches all available currencies on an exchange
|
1545
|
-
|
1732
|
+
|
1733
|
+
https://www.okx.com/docs-v5/en/#rest-api-funding-get-currencies
|
1734
|
+
|
1546
1735
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1547
1736
|
:returns dict: an associative dictionary of currencies
|
1548
1737
|
"""
|
@@ -1602,8 +1791,8 @@ class okx(Exchange, ImplicitAPI):
|
|
1602
1791
|
# "msg": ""
|
1603
1792
|
# }
|
1604
1793
|
#
|
1605
|
-
data = self.
|
1606
|
-
result = {}
|
1794
|
+
data = self.safe_list(response, 'data', [])
|
1795
|
+
result: dict = {}
|
1607
1796
|
dataByCurrencyId = self.group_by(data, 'ccy')
|
1608
1797
|
currencyIds = list(dataByCurrencyId.keys())
|
1609
1798
|
for i in range(0, len(currencyIds)):
|
@@ -1611,24 +1800,24 @@ class okx(Exchange, ImplicitAPI):
|
|
1611
1800
|
currency = self.safe_currency(currencyId)
|
1612
1801
|
code = currency['code']
|
1613
1802
|
chains = dataByCurrencyId[currencyId]
|
1614
|
-
networks = {}
|
1803
|
+
networks: dict = {}
|
1615
1804
|
currencyActive = False
|
1616
1805
|
depositEnabled = False
|
1617
1806
|
withdrawEnabled = False
|
1618
1807
|
maxPrecision = None
|
1619
1808
|
for j in range(0, len(chains)):
|
1620
1809
|
chain = chains[j]
|
1621
|
-
canDeposit = self.
|
1810
|
+
canDeposit = self.safe_bool(chain, 'canDep')
|
1622
1811
|
depositEnabled = canDeposit if (canDeposit) else depositEnabled
|
1623
|
-
canWithdraw = self.
|
1812
|
+
canWithdraw = self.safe_bool(chain, 'canWd')
|
1624
1813
|
withdrawEnabled = canWithdraw if (canWithdraw) else withdrawEnabled
|
1625
|
-
canInternal = self.
|
1814
|
+
canInternal = self.safe_bool(chain, 'canInternal')
|
1626
1815
|
active = True if (canDeposit and canWithdraw and canInternal) else False
|
1627
1816
|
currencyActive = active if (active) else currencyActive
|
1628
1817
|
networkId = self.safe_string(chain, 'chain')
|
1629
1818
|
if (networkId is not None) and (networkId.find('-') >= 0):
|
1630
|
-
parts = networkId.split('-')
|
1631
|
-
chainPart =
|
1819
|
+
parts = networkId.split('-')[1:]
|
1820
|
+
chainPart = '-'.join(parts)
|
1632
1821
|
networkCode = self.network_id_to_code(chainPart, currency['code'])
|
1633
1822
|
precision = self.parse_precision(self.safe_string(chain, 'wdTickSz'))
|
1634
1823
|
if maxPrecision is None:
|
@@ -1641,7 +1830,7 @@ class okx(Exchange, ImplicitAPI):
|
|
1641
1830
|
'active': active,
|
1642
1831
|
'deposit': canDeposit,
|
1643
1832
|
'withdraw': canWithdraw,
|
1644
|
-
'fee': self.safe_number(chain, '
|
1833
|
+
'fee': self.safe_number(chain, 'fee'),
|
1645
1834
|
'precision': self.parse_number(precision),
|
1646
1835
|
'limits': {
|
1647
1836
|
'withdraw': {
|
@@ -1651,9 +1840,9 @@ class okx(Exchange, ImplicitAPI):
|
|
1651
1840
|
},
|
1652
1841
|
'info': chain,
|
1653
1842
|
}
|
1654
|
-
firstChain = self.
|
1843
|
+
firstChain = self.safe_dict(chains, 0, {})
|
1655
1844
|
result[code] = {
|
1656
|
-
'info':
|
1845
|
+
'info': chains,
|
1657
1846
|
'code': code,
|
1658
1847
|
'id': currencyId,
|
1659
1848
|
'name': self.safe_string(firstChain, 'name'),
|
@@ -1675,7 +1864,9 @@ class okx(Exchange, ImplicitAPI):
|
|
1675
1864
|
async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
1676
1865
|
"""
|
1677
1866
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
1678
|
-
|
1867
|
+
|
1868
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-order-book
|
1869
|
+
|
1679
1870
|
:param str symbol: unified symbol of the market to fetch the order book for
|
1680
1871
|
:param int [limit]: the maximum amount of order book entries to return
|
1681
1872
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1684,7 +1875,7 @@ class okx(Exchange, ImplicitAPI):
|
|
1684
1875
|
"""
|
1685
1876
|
await self.load_markets()
|
1686
1877
|
market = self.market(symbol)
|
1687
|
-
request = {
|
1878
|
+
request: dict = {
|
1688
1879
|
'instId': market['id'],
|
1689
1880
|
}
|
1690
1881
|
method = None
|
@@ -1720,12 +1911,19 @@ class okx(Exchange, ImplicitAPI):
|
|
1720
1911
|
# ]
|
1721
1912
|
# }
|
1722
1913
|
#
|
1723
|
-
data = self.
|
1724
|
-
first = self.
|
1914
|
+
data = self.safe_list(response, 'data', [])
|
1915
|
+
first = self.safe_dict(data, 0, {})
|
1725
1916
|
timestamp = self.safe_integer(first, 'ts')
|
1726
1917
|
return self.parse_order_book(first, symbol, timestamp)
|
1727
1918
|
|
1728
|
-
def parse_ticker(self, ticker, market: Market = None) -> Ticker:
|
1919
|
+
def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
|
1920
|
+
#
|
1921
|
+
# {
|
1922
|
+
# "instType":"SWAP",
|
1923
|
+
# "instId":"BTC-USDT-SWAP",
|
1924
|
+
# "markPx":"200",
|
1925
|
+
# "ts":"1597026383085"
|
1926
|
+
# }
|
1729
1927
|
#
|
1730
1928
|
# {
|
1731
1929
|
# "instType": "SPOT",
|
@@ -1745,6 +1943,16 @@ class okx(Exchange, ImplicitAPI):
|
|
1745
1943
|
# "sodUtc0": "0.07872",
|
1746
1944
|
# "sodUtc8": "0.07345"
|
1747
1945
|
# }
|
1946
|
+
# {
|
1947
|
+
# instId: 'LTC-USDT',
|
1948
|
+
# idxPx: '65.74',
|
1949
|
+
# open24h: '65.37',
|
1950
|
+
# high24h: '66.15',
|
1951
|
+
# low24h: '64.97',
|
1952
|
+
# sodUtc0: '65.68',
|
1953
|
+
# sodUtc8: '65.54',
|
1954
|
+
# ts: '1728467346900'
|
1955
|
+
# },
|
1748
1956
|
#
|
1749
1957
|
timestamp = self.safe_integer(ticker, 'ts')
|
1750
1958
|
marketId = self.safe_string(ticker, 'instId')
|
@@ -1777,20 +1985,24 @@ class okx(Exchange, ImplicitAPI):
|
|
1777
1985
|
'average': None,
|
1778
1986
|
'baseVolume': baseVolume,
|
1779
1987
|
'quoteVolume': quoteVolume,
|
1988
|
+
'markPrice': self.safe_string(ticker, 'markPx'),
|
1989
|
+
'indexPrice': self.safe_string(ticker, 'idxPx'),
|
1780
1990
|
'info': ticker,
|
1781
1991
|
}, market)
|
1782
1992
|
|
1783
1993
|
async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
|
1784
1994
|
"""
|
1785
1995
|
fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
1786
|
-
|
1996
|
+
|
1997
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-ticker
|
1998
|
+
|
1787
1999
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
1788
2000
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1789
2001
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1790
2002
|
"""
|
1791
2003
|
await self.load_markets()
|
1792
2004
|
market = self.market(symbol)
|
1793
|
-
request = {
|
2005
|
+
request: dict = {
|
1794
2006
|
'instId': market['id'],
|
1795
2007
|
}
|
1796
2008
|
response = await self.publicGetMarketTicker(self.extend(request, params))
|
@@ -1820,20 +2032,33 @@ class okx(Exchange, ImplicitAPI):
|
|
1820
2032
|
# ]
|
1821
2033
|
# }
|
1822
2034
|
#
|
1823
|
-
data = self.
|
1824
|
-
first = self.
|
2035
|
+
data = self.safe_list(response, 'data', [])
|
2036
|
+
first = self.safe_dict(data, 0, {})
|
1825
2037
|
return self.parse_ticker(first, market)
|
1826
2038
|
|
1827
|
-
async def
|
2039
|
+
async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
2040
|
+
"""
|
2041
|
+
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
2042
|
+
|
2043
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-tickers
|
2044
|
+
|
2045
|
+
:param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
2046
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2047
|
+
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
2048
|
+
"""
|
1828
2049
|
await self.load_markets()
|
1829
|
-
|
1830
|
-
|
2050
|
+
symbols = self.market_symbols(symbols)
|
2051
|
+
market = self.get_market_from_symbols(symbols)
|
2052
|
+
marketType = None
|
2053
|
+
marketType, params = self.handle_market_type_and_params('fetchTickers', market, params)
|
2054
|
+
request: dict = {
|
2055
|
+
'instType': self.convert_to_instrument_type(marketType),
|
1831
2056
|
}
|
1832
|
-
if
|
1833
|
-
defaultUnderlying = self.
|
2057
|
+
if marketType == 'option':
|
2058
|
+
defaultUnderlying = self.safe_string(self.options, 'defaultUnderlying', 'BTC-USD')
|
1834
2059
|
currencyId = self.safe_string_2(params, 'uly', 'marketId', defaultUnderlying)
|
1835
2060
|
if currencyId is None:
|
1836
|
-
raise ArgumentsRequired(self.id + '
|
2061
|
+
raise ArgumentsRequired(self.id + ' fetchTickers() requires an underlying uly or marketId parameter for options markets')
|
1837
2062
|
else:
|
1838
2063
|
request['uly'] = currencyId
|
1839
2064
|
response = await self.publicGetMarketTickers(self.extend(request, params))
|
@@ -1863,27 +2088,72 @@ class okx(Exchange, ImplicitAPI):
|
|
1863
2088
|
# ]
|
1864
2089
|
# }
|
1865
2090
|
#
|
1866
|
-
tickers = self.
|
2091
|
+
tickers = self.safe_list(response, 'data', [])
|
1867
2092
|
return self.parse_tickers(tickers, symbols)
|
1868
2093
|
|
1869
|
-
async def
|
2094
|
+
async def fetch_mark_price(self, symbol: str, params={}) -> Ticker:
|
2095
|
+
"""
|
2096
|
+
fetches mark price for the market
|
2097
|
+
|
2098
|
+
https://www.okx.com/docs-v5/en/#public-data-rest-api-get-mark-price
|
2099
|
+
|
2100
|
+
:param str symbol: unified symbol of the market to fetch the ticker for
|
2101
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2102
|
+
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
2103
|
+
"""
|
2104
|
+
await self.load_markets()
|
2105
|
+
market = self.market(symbol)
|
2106
|
+
request: dict = {
|
2107
|
+
'instId': market['id'],
|
2108
|
+
}
|
2109
|
+
response = await self.publicGetPublicMarkPrice(self.extend(request, params))
|
2110
|
+
#
|
2111
|
+
# {
|
2112
|
+
# "code": "0",
|
2113
|
+
# "data": [
|
2114
|
+
# {
|
2115
|
+
# "instId": "ETH-USDT",
|
2116
|
+
# "instType": "MARGIN",
|
2117
|
+
# "markPx": "2403.98",
|
2118
|
+
# "ts": "1728578500703"
|
2119
|
+
# }
|
2120
|
+
# ],
|
2121
|
+
# "msg": ""
|
2122
|
+
# }
|
2123
|
+
#
|
2124
|
+
data = self.safe_list(response, 'data')
|
2125
|
+
return self.parse_ticker(self.safe_dict(data, 0), market)
|
2126
|
+
|
2127
|
+
async def fetch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
|
1870
2128
|
"""
|
1871
2129
|
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
1872
|
-
|
1873
|
-
|
2130
|
+
|
2131
|
+
https://www.okx.com/docs-v5/en/#public-data-rest-api-get-mark-price
|
2132
|
+
|
2133
|
+
:param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
1874
2134
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1875
2135
|
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1876
2136
|
"""
|
1877
2137
|
await self.load_markets()
|
1878
2138
|
symbols = self.market_symbols(symbols)
|
1879
|
-
|
1880
|
-
|
1881
|
-
|
1882
|
-
|
1883
|
-
|
1884
|
-
|
2139
|
+
market = self.get_market_from_symbols(symbols)
|
2140
|
+
marketType = None
|
2141
|
+
marketType, params = self.handle_market_type_and_params('fetchTickers', market, params, 'swap')
|
2142
|
+
request: dict = {
|
2143
|
+
'instType': self.convert_to_instrument_type(marketType),
|
2144
|
+
}
|
2145
|
+
if marketType == 'option':
|
2146
|
+
defaultUnderlying = self.safe_string(self.options, 'defaultUnderlying', 'BTC-USD')
|
2147
|
+
currencyId = self.safe_string_2(params, 'uly', 'marketId', defaultUnderlying)
|
2148
|
+
if currencyId is None:
|
2149
|
+
raise ArgumentsRequired(self.id + ' fetchMarkPrices() requires an underlying uly or marketId parameter for options markets')
|
2150
|
+
else:
|
2151
|
+
request['uly'] = currencyId
|
2152
|
+
response = await self.publicGetPublicMarkPrice(self.extend(request, params))
|
2153
|
+
tickers = self.safe_list(response, 'data', [])
|
2154
|
+
return self.parse_tickers(tickers, symbols)
|
1885
2155
|
|
1886
|
-
def parse_trade(self, trade, market: Market = None) -> Trade:
|
2156
|
+
def parse_trade(self, trade: dict, market: Market = None) -> Trade:
|
1887
2157
|
#
|
1888
2158
|
# public fetchTrades
|
1889
2159
|
#
|
@@ -1976,12 +2246,15 @@ class okx(Exchange, ImplicitAPI):
|
|
1976
2246
|
async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
1977
2247
|
"""
|
1978
2248
|
get the list of most recent trades for a particular symbol
|
1979
|
-
|
1980
|
-
|
2249
|
+
|
2250
|
+
https://www.okx.com/docs-v5/en/#rest-api-market-data-get-trades
|
2251
|
+
https://www.okx.com/docs-v5/en/#rest-api-public-data-get-option-trades
|
2252
|
+
|
1981
2253
|
:param str symbol: unified symbol of the market to fetch trades for
|
1982
2254
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
1983
2255
|
:param int [limit]: the maximum amount of trades to fetch
|
1984
2256
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2257
|
+
:param str [params.method]: 'publicGetMarketTrades' or 'publicGetMarketHistoryTrades' default is 'publicGetMarketTrades'
|
1985
2258
|
:param boolean [params.paginate]: *only applies to publicGetMarketHistoryTrades* default False, when True will automatically paginate by calling self endpoint multiple times
|
1986
2259
|
:returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
1987
2260
|
"""
|
@@ -1991,7 +2264,7 @@ class okx(Exchange, ImplicitAPI):
|
|
1991
2264
|
if paginate:
|
1992
2265
|
return await self.fetch_paginated_call_cursor('fetchTrades', symbol, since, limit, params, 'tradeId', 'after', None, 100)
|
1993
2266
|
market = self.market(symbol)
|
1994
|
-
request = {
|
2267
|
+
request: dict = {
|
1995
2268
|
'instId': market['id'],
|
1996
2269
|
}
|
1997
2270
|
response = None
|
@@ -2040,7 +2313,7 @@ class okx(Exchange, ImplicitAPI):
|
|
2040
2313
|
# "msg": ""
|
2041
2314
|
# }
|
2042
2315
|
#
|
2043
|
-
data = self.
|
2316
|
+
data = self.safe_list(response, 'data', [])
|
2044
2317
|
return self.parse_trades(data, market, since, limit)
|
2045
2318
|
|
2046
2319
|
def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
|
@@ -2072,12 +2345,14 @@ class okx(Exchange, ImplicitAPI):
|
|
2072
2345
|
async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
2073
2346
|
"""
|
2074
2347
|
fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2079
|
-
|
2080
|
-
|
2348
|
+
|
2349
|
+
https://www.okx.com/docs-v5/en/#rest-api-market-data-get-candlesticks
|
2350
|
+
https://www.okx.com/docs-v5/en/#rest-api-market-data-get-candlesticks-history
|
2351
|
+
https://www.okx.com/docs-v5/en/#rest-api-market-data-get-mark-price-candlesticks
|
2352
|
+
https://www.okx.com/docs-v5/en/#rest-api-market-data-get-mark-price-candlesticks-history
|
2353
|
+
https://www.okx.com/docs-v5/en/#rest-api-market-data-get-index-candlesticks
|
2354
|
+
https://www.okx.com/docs-v5/en/#rest-api-market-data-get-index-candlesticks-history
|
2355
|
+
|
2081
2356
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
2082
2357
|
:param str timeframe: the length of time each candle represents
|
2083
2358
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
@@ -2096,7 +2371,7 @@ class okx(Exchange, ImplicitAPI):
|
|
2096
2371
|
return await self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 200)
|
2097
2372
|
price = self.safe_string(params, 'price')
|
2098
2373
|
params = self.omit(params, 'price')
|
2099
|
-
options = self.
|
2374
|
+
options = self.safe_dict(self.options, 'fetchOHLCV', {})
|
2100
2375
|
timezone = self.safe_string(options, 'timezone', 'UTC')
|
2101
2376
|
if limit is None:
|
2102
2377
|
limit = 100 # default 100, max 100
|
@@ -2104,7 +2379,7 @@ class okx(Exchange, ImplicitAPI):
|
|
2104
2379
|
bar = self.safe_string(self.timeframes, timeframe, timeframe)
|
2105
2380
|
if (timezone == 'UTC') and (duration >= 21600): # if utc and timeframe >= 6h
|
2106
2381
|
bar += timezone.lower()
|
2107
|
-
request = {
|
2382
|
+
request: dict = {
|
2108
2383
|
'instId': market['id'],
|
2109
2384
|
'bar': bar,
|
2110
2385
|
'limit': limit,
|
@@ -2156,13 +2431,15 @@ class okx(Exchange, ImplicitAPI):
|
|
2156
2431
|
# ]
|
2157
2432
|
# }
|
2158
2433
|
#
|
2159
|
-
data = self.
|
2434
|
+
data = self.safe_list(response, 'data', [])
|
2160
2435
|
return self.parse_ohlcvs(data, market, timeframe, since, limit)
|
2161
2436
|
|
2162
2437
|
async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
2163
2438
|
"""
|
2164
2439
|
fetches historical funding rate prices
|
2165
|
-
|
2440
|
+
|
2441
|
+
https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate-history
|
2442
|
+
|
2166
2443
|
:param str symbol: unified symbol of the market to fetch the funding rate history for
|
2167
2444
|
:param int [since]: timestamp in ms of the earliest funding rate to fetch
|
2168
2445
|
:param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
|
@@ -2178,7 +2455,7 @@ class okx(Exchange, ImplicitAPI):
|
|
2178
2455
|
if paginate:
|
2179
2456
|
return await self.fetch_paginated_call_deterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params, 100)
|
2180
2457
|
market = self.market(symbol)
|
2181
|
-
request = {
|
2458
|
+
request: dict = {
|
2182
2459
|
'instId': market['id'],
|
2183
2460
|
}
|
2184
2461
|
if since is not None:
|
@@ -2209,7 +2486,7 @@ class okx(Exchange, ImplicitAPI):
|
|
2209
2486
|
# }
|
2210
2487
|
#
|
2211
2488
|
rates = []
|
2212
|
-
data = self.
|
2489
|
+
data = self.safe_list(response, 'data', [])
|
2213
2490
|
for i in range(0, len(data)):
|
2214
2491
|
rate = data[i]
|
2215
2492
|
timestamp = self.safe_integer(rate, 'fundingTime')
|
@@ -2230,11 +2507,11 @@ class okx(Exchange, ImplicitAPI):
|
|
2230
2507
|
return self.parse_trading_balance(response)
|
2231
2508
|
|
2232
2509
|
def parse_trading_balance(self, response):
|
2233
|
-
result = {'info': response}
|
2234
|
-
data = self.
|
2235
|
-
first = self.
|
2510
|
+
result: dict = {'info': response}
|
2511
|
+
data = self.safe_list(response, 'data', [])
|
2512
|
+
first = self.safe_dict(data, 0, {})
|
2236
2513
|
timestamp = self.safe_integer(first, 'uTime')
|
2237
|
-
details = self.
|
2514
|
+
details = self.safe_list(first, 'details', [])
|
2238
2515
|
for i in range(0, len(details)):
|
2239
2516
|
balance = details[i]
|
2240
2517
|
currencyId = self.safe_string(balance, 'ccy')
|
@@ -2255,8 +2532,8 @@ class okx(Exchange, ImplicitAPI):
|
|
2255
2532
|
return self.safe_balance(result)
|
2256
2533
|
|
2257
2534
|
def parse_funding_balance(self, response):
|
2258
|
-
result = {'info': response}
|
2259
|
-
data = self.
|
2535
|
+
result: dict = {'info': response}
|
2536
|
+
data = self.safe_list(response, 'data', [])
|
2260
2537
|
for i in range(0, len(data)):
|
2261
2538
|
balance = data[i]
|
2262
2539
|
currencyId = self.safe_string(balance, 'ccy')
|
@@ -2269,7 +2546,7 @@ class okx(Exchange, ImplicitAPI):
|
|
2269
2546
|
result[code] = account
|
2270
2547
|
return self.safe_balance(result)
|
2271
2548
|
|
2272
|
-
def parse_trading_fee(self, fee, market: Market = None):
|
2549
|
+
def parse_trading_fee(self, fee: dict, market: Market = None) -> TradingFeeInterface:
|
2273
2550
|
# https://www.okx.com/docs-v5/en/#rest-api-account-get-fee-rates
|
2274
2551
|
#
|
2275
2552
|
# {
|
@@ -2289,19 +2566,23 @@ class okx(Exchange, ImplicitAPI):
|
|
2289
2566
|
# OKX returns the fees values opposed to other exchanges, so the sign needs to be flipped
|
2290
2567
|
'maker': self.parse_number(Precise.string_neg(self.safe_string_2(fee, 'maker', 'makerU'))),
|
2291
2568
|
'taker': self.parse_number(Precise.string_neg(self.safe_string_2(fee, 'taker', 'takerU'))),
|
2569
|
+
'percentage': None,
|
2570
|
+
'tierBased': None,
|
2292
2571
|
}
|
2293
2572
|
|
2294
|
-
async def fetch_trading_fee(self, symbol: str, params={}):
|
2573
|
+
async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
|
2295
2574
|
"""
|
2296
2575
|
fetch the trading fees for a market
|
2297
|
-
|
2576
|
+
|
2577
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-fee-rates
|
2578
|
+
|
2298
2579
|
:param str symbol: unified market symbol
|
2299
2580
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2300
2581
|
:returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
|
2301
2582
|
"""
|
2302
2583
|
await self.load_markets()
|
2303
2584
|
market = self.market(symbol)
|
2304
|
-
request = {
|
2585
|
+
request: dict = {
|
2305
2586
|
'instType': self.convert_to_instrument_type(market['type']), # SPOT, MARGIN, SWAP, FUTURES, OPTION
|
2306
2587
|
# "instId": market["id"], # only applicable to SPOT/MARGIN
|
2307
2588
|
# "uly": market["id"], # only applicable to FUTURES/SWAP/OPTION
|
@@ -2332,21 +2613,24 @@ class okx(Exchange, ImplicitAPI):
|
|
2332
2613
|
# "msg": ""
|
2333
2614
|
# }
|
2334
2615
|
#
|
2335
|
-
data = self.
|
2336
|
-
first = self.
|
2616
|
+
data = self.safe_list(response, 'data', [])
|
2617
|
+
first = self.safe_dict(data, 0, {})
|
2337
2618
|
return self.parse_trading_fee(first, market)
|
2338
2619
|
|
2339
2620
|
async def fetch_balance(self, params={}) -> Balances:
|
2340
2621
|
"""
|
2341
2622
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
2342
|
-
|
2343
|
-
|
2623
|
+
|
2624
|
+
https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-balance
|
2625
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-balance
|
2626
|
+
|
2344
2627
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2628
|
+
:param str [params.type]: wallet type, ['funding' or 'trading'] default is 'trading'
|
2345
2629
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
2346
2630
|
"""
|
2347
2631
|
await self.load_markets()
|
2348
2632
|
marketType, query = self.handle_market_type_and_params('fetchBalance', None, params)
|
2349
|
-
request = {
|
2633
|
+
request: dict = {
|
2350
2634
|
# 'ccy': 'BTC,ETH', # comma-separated list of currency ids
|
2351
2635
|
}
|
2352
2636
|
response = None
|
@@ -2460,7 +2744,9 @@ class okx(Exchange, ImplicitAPI):
|
|
2460
2744
|
|
2461
2745
|
async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
|
2462
2746
|
"""
|
2463
|
-
|
2747
|
+
|
2748
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order
|
2749
|
+
|
2464
2750
|
create a market buy order by providing the symbol and cost
|
2465
2751
|
:param str symbol: unified symbol of the market to create an order in
|
2466
2752
|
:param float cost: how much you want to trade in units of the quote currency
|
@@ -2471,13 +2757,17 @@ class okx(Exchange, ImplicitAPI):
|
|
2471
2757
|
market = self.market(symbol)
|
2472
2758
|
if not market['spot']:
|
2473
2759
|
raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot markets only')
|
2474
|
-
|
2475
|
-
|
2476
|
-
|
2760
|
+
req = {
|
2761
|
+
'createMarketBuyOrderRequiresPrice': False,
|
2762
|
+
'tgtCcy': 'quote_ccy',
|
2763
|
+
}
|
2764
|
+
return await self.create_order(symbol, 'market', 'buy', cost, None, self.extend(req, params))
|
2477
2765
|
|
2478
2766
|
async def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}):
|
2479
2767
|
"""
|
2480
|
-
|
2768
|
+
|
2769
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order
|
2770
|
+
|
2481
2771
|
create a market buy order by providing the symbol and cost
|
2482
2772
|
:param str symbol: unified symbol of the market to create an order in
|
2483
2773
|
:param float cost: how much you want to trade in units of the quote currency
|
@@ -2488,13 +2778,15 @@ class okx(Exchange, ImplicitAPI):
|
|
2488
2778
|
market = self.market(symbol)
|
2489
2779
|
if not market['spot']:
|
2490
2780
|
raise NotSupported(self.id + ' createMarketSellOrderWithCost() supports spot markets only')
|
2491
|
-
|
2492
|
-
|
2493
|
-
|
2781
|
+
req = {
|
2782
|
+
'createMarketBuyOrderRequiresPrice': False,
|
2783
|
+
'tgtCcy': 'quote_ccy',
|
2784
|
+
}
|
2785
|
+
return await self.create_order(symbol, 'market', 'sell', cost, None, self.extend(req, params))
|
2494
2786
|
|
2495
2787
|
def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
2496
2788
|
market = self.market(symbol)
|
2497
|
-
request = {
|
2789
|
+
request: dict = {
|
2498
2790
|
'instId': market['id'],
|
2499
2791
|
# 'ccy': currency['id'], # only applicable to cross MARGIN orders in single-currency margin
|
2500
2792
|
# 'clOrdId': clientOrderId, # up to 32 characters, must be unique
|
@@ -2537,6 +2829,8 @@ class okx(Exchange, ImplicitAPI):
|
|
2537
2829
|
takeProfitDefined = (takeProfit is not None)
|
2538
2830
|
trailingPercent = self.safe_string_2(params, 'trailingPercent', 'callbackRatio')
|
2539
2831
|
isTrailingPercentOrder = trailingPercent is not None
|
2832
|
+
trigger = (triggerPrice is not None) or (type == 'trigger')
|
2833
|
+
isReduceOnly = self.safe_value(params, 'reduceOnly', False)
|
2540
2834
|
defaultMarginMode = self.safe_string_2(self.options, 'defaultMarginMode', 'marginMode', 'cross')
|
2541
2835
|
marginMode = self.safe_string_2(params, 'marginMode', 'tdMode') # cross or isolated, tdMode not ommited so be extended into the request
|
2542
2836
|
margin = False
|
@@ -2558,6 +2852,20 @@ class okx(Exchange, ImplicitAPI):
|
|
2558
2852
|
positionSide, params = self.handle_option_and_params(params, 'createOrder', 'positionSide')
|
2559
2853
|
if positionSide is not None:
|
2560
2854
|
request['posSide'] = positionSide
|
2855
|
+
else:
|
2856
|
+
hedged = None
|
2857
|
+
hedged, params = self.handle_option_and_params(params, 'createOrder', 'hedged')
|
2858
|
+
if hedged:
|
2859
|
+
isBuy = (side == 'buy')
|
2860
|
+
isProtective = (takeProfitPrice is not None) or (stopLossPrice is not None) or isReduceOnly
|
2861
|
+
if isProtective:
|
2862
|
+
# in case of protective orders, the posSide should be opposite of position side
|
2863
|
+
# reduceOnly is emulated and not natively supported by the exchange
|
2864
|
+
request['posSide'] = 'short' if isBuy else 'long'
|
2865
|
+
if isReduceOnly:
|
2866
|
+
params = self.omit(params, 'reduceOnly')
|
2867
|
+
else:
|
2868
|
+
request['posSide'] = 'long' if isBuy else 'short'
|
2561
2869
|
request['tdMode'] = marginMode
|
2562
2870
|
isMarketOrder = type == 'market'
|
2563
2871
|
postOnly = False
|
@@ -2565,7 +2873,6 @@ class okx(Exchange, ImplicitAPI):
|
|
2565
2873
|
params = self.omit(params, ['currency', 'ccy', 'marginMode', 'timeInForce', 'stopPrice', 'triggerPrice', 'clientOrderId', 'stopLossPrice', 'takeProfitPrice', 'slOrdPx', 'tpOrdPx', 'margin', 'stopLoss', 'takeProfit', 'trailingPercent'])
|
2566
2874
|
ioc = (timeInForce == 'IOC') or (type == 'ioc')
|
2567
2875
|
fok = (timeInForce == 'FOK') or (type == 'fok')
|
2568
|
-
trigger = (triggerPrice is not None) or (type == 'trigger')
|
2569
2876
|
conditional = (stopLossPrice is not None) or (takeProfitPrice is not None) or (type == 'conditional')
|
2570
2877
|
marketIOC = (isMarketOrder and ioc) or (type == 'optimal_limit_ioc')
|
2571
2878
|
defaultTgtCcy = self.safe_string(self.options, 'tgtCcy', 'base_ccy')
|
@@ -2702,14 +3009,16 @@ class okx(Exchange, ImplicitAPI):
|
|
2702
3009
|
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
2703
3010
|
"""
|
2704
3011
|
create a trade order
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
3012
|
+
|
3013
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order
|
3014
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-multiple-orders
|
3015
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-place-algo-order
|
3016
|
+
|
2708
3017
|
:param str symbol: unified symbol of the market to create an order in
|
2709
3018
|
:param str type: 'market' or 'limit'
|
2710
3019
|
:param str side: 'buy' or 'sell'
|
2711
3020
|
:param float amount: how much of currency you want to trade in units of base currency
|
2712
|
-
:param float [price]: the price at which the order is to be
|
3021
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
2713
3022
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2714
3023
|
:param bool [params.reduceOnly]: a mark to reduce the position size for margin, swap and future orders
|
2715
3024
|
:param bool [params.postOnly]: True to place a post only order
|
@@ -2724,6 +3033,7 @@ class okx(Exchange, ImplicitAPI):
|
|
2724
3033
|
:param str [params.positionSide]: if position mode is one-way: set to 'net', if position mode is hedge-mode: set to 'long' or 'short'
|
2725
3034
|
:param str [params.trailingPercent]: the percent to trail away from the current market price
|
2726
3035
|
:param str [params.tpOrdKind]: 'condition' or 'limit', the default is 'condition'
|
3036
|
+
:param bool [params.hedged]: *swap and future only* True for hedged mode, False for one way mode
|
2727
3037
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2728
3038
|
"""
|
2729
3039
|
await self.load_markets()
|
@@ -2747,8 +3057,8 @@ class okx(Exchange, ImplicitAPI):
|
|
2747
3057
|
response = await self.privatePostTradeOrderAlgo(request)
|
2748
3058
|
else:
|
2749
3059
|
response = await self.privatePostTradeBatchOrders(request)
|
2750
|
-
data = self.
|
2751
|
-
first = self.
|
3060
|
+
data = self.safe_list(response, 'data', [])
|
3061
|
+
first = self.safe_dict(data, 0, {})
|
2752
3062
|
order = self.parse_order(first, market)
|
2753
3063
|
order['type'] = type
|
2754
3064
|
order['side'] = side
|
@@ -2757,8 +3067,11 @@ class okx(Exchange, ImplicitAPI):
|
|
2757
3067
|
async def create_orders(self, orders: List[OrderRequest], params={}):
|
2758
3068
|
"""
|
2759
3069
|
create a list of trade orders
|
2760
|
-
|
3070
|
+
|
3071
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-multiple-orders
|
3072
|
+
|
2761
3073
|
: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
|
3074
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2762
3075
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2763
3076
|
"""
|
2764
3077
|
await self.load_markets()
|
@@ -2770,7 +3083,7 @@ class okx(Exchange, ImplicitAPI):
|
|
2770
3083
|
side = self.safe_string(rawOrder, 'side')
|
2771
3084
|
amount = self.safe_value(rawOrder, 'amount')
|
2772
3085
|
price = self.safe_value(rawOrder, 'price')
|
2773
|
-
orderParams = self.
|
3086
|
+
orderParams = self.safe_dict(rawOrder, 'params', {})
|
2774
3087
|
extendedParams = self.extend(orderParams, params) # the request does not accept extra params since it's a list, so we're extending each order with the common params
|
2775
3088
|
orderRequest = self.create_order_request(marketId, type, side, amount, price, extendedParams)
|
2776
3089
|
ordersRequests.append(orderRequest)
|
@@ -2797,12 +3110,12 @@ class okx(Exchange, ImplicitAPI):
|
|
2797
3110
|
# "msg": "",
|
2798
3111
|
# "outTime": "1697979038586493"
|
2799
3112
|
# }
|
2800
|
-
data = self.
|
3113
|
+
data = self.safe_list(response, 'data', [])
|
2801
3114
|
return self.parse_orders(data)
|
2802
3115
|
|
2803
3116
|
def edit_order_request(self, id: str, symbol, type, side, amount=None, price=None, params={}):
|
2804
3117
|
market = self.market(symbol)
|
2805
|
-
request = {
|
3118
|
+
request: dict = {
|
2806
3119
|
'instId': market['id'],
|
2807
3120
|
}
|
2808
3121
|
isAlgoOrder = None
|
@@ -2873,20 +3186,22 @@ class okx(Exchange, ImplicitAPI):
|
|
2873
3186
|
if not isAlgoOrder:
|
2874
3187
|
if price is not None:
|
2875
3188
|
request['newPx'] = self.price_to_precision(symbol, price)
|
2876
|
-
params = self.omit(params, ['clOrdId', 'clientOrderId', 'takeProfitPrice', 'stopLossPrice', 'stopLoss', 'takeProfit'])
|
3189
|
+
params = self.omit(params, ['clOrdId', 'clientOrderId', 'takeProfitPrice', 'stopLossPrice', 'stopLoss', 'takeProfit', 'postOnly'])
|
2877
3190
|
return self.extend(request, params)
|
2878
3191
|
|
2879
3192
|
async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
2880
3193
|
"""
|
2881
3194
|
edit a trade order
|
2882
|
-
|
2883
|
-
|
3195
|
+
|
3196
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-amend-order
|
3197
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-amend-algo-order
|
3198
|
+
|
2884
3199
|
:param str id: order id
|
2885
3200
|
:param str symbol: unified symbol of the market to create an order in
|
2886
3201
|
:param str type: 'market' or 'limit'
|
2887
3202
|
:param str side: 'buy' or 'sell'
|
2888
3203
|
:param float amount: how much of the currency you want to trade in units of the base currency
|
2889
|
-
:param float [price]: the price at which the order is to be
|
3204
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
2890
3205
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2891
3206
|
:param str [params.clientOrderId]: client order id, uses id if not passed
|
2892
3207
|
:param float [params.stopLossPrice]: stop loss trigger price
|
@@ -2932,8 +3247,8 @@ class okx(Exchange, ImplicitAPI):
|
|
2932
3247
|
# "msg": ""
|
2933
3248
|
# }
|
2934
3249
|
#
|
2935
|
-
data = self.
|
2936
|
-
first = self.
|
3250
|
+
data = self.safe_list(response, 'data', [])
|
3251
|
+
first = self.safe_dict(data, 0, {})
|
2937
3252
|
order = self.parse_order(first, market)
|
2938
3253
|
order['type'] = type
|
2939
3254
|
order['side'] = side
|
@@ -2942,8 +3257,10 @@ class okx(Exchange, ImplicitAPI):
|
|
2942
3257
|
async def cancel_order(self, id: str, symbol: Str = None, params={}):
|
2943
3258
|
"""
|
2944
3259
|
cancels an open order
|
2945
|
-
|
2946
|
-
|
3260
|
+
|
3261
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-order
|
3262
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order
|
3263
|
+
|
2947
3264
|
:param str id: order id
|
2948
3265
|
:param str symbol: unified symbol of the market the order was made in
|
2949
3266
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -2953,14 +3270,14 @@ class okx(Exchange, ImplicitAPI):
|
|
2953
3270
|
"""
|
2954
3271
|
if symbol is None:
|
2955
3272
|
raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
|
2956
|
-
|
3273
|
+
trigger = self.safe_value_2(params, 'stop', 'trigger')
|
2957
3274
|
trailing = self.safe_bool(params, 'trailing', False)
|
2958
|
-
if
|
3275
|
+
if trigger or trailing:
|
2959
3276
|
orderInner = await self.cancel_orders([id], symbol, params)
|
2960
3277
|
return self.safe_value(orderInner, 0)
|
2961
3278
|
await self.load_markets()
|
2962
3279
|
market = self.market(symbol)
|
2963
|
-
request = {
|
3280
|
+
request: dict = {
|
2964
3281
|
'instId': market['id'],
|
2965
3282
|
# 'ordId': id, # either ordId or clOrdId is required
|
2966
3283
|
# 'clOrdId': clientOrderId,
|
@@ -2974,12 +3291,12 @@ class okx(Exchange, ImplicitAPI):
|
|
2974
3291
|
response = await self.privatePostTradeCancelOrder(self.extend(request, query))
|
2975
3292
|
# {"code":"0","data":[{"clOrdId":"","ordId":"317251910906576896","sCode":"0","sMsg":""}],"msg":""}
|
2976
3293
|
data = self.safe_value(response, 'data', [])
|
2977
|
-
order = self.
|
3294
|
+
order = self.safe_dict(data, 0)
|
2978
3295
|
return self.parse_order(order, market)
|
2979
3296
|
|
2980
3297
|
def parse_ids(self, ids):
|
2981
3298
|
"""
|
2982
|
-
|
3299
|
+
@ignore
|
2983
3300
|
:param string[]|str ids: order ids
|
2984
3301
|
:returns str[]: list of order ids
|
2985
3302
|
"""
|
@@ -2991,8 +3308,10 @@ class okx(Exchange, ImplicitAPI):
|
|
2991
3308
|
async def cancel_orders(self, ids, symbol: Str = None, params={}):
|
2992
3309
|
"""
|
2993
3310
|
cancel multiple orders
|
2994
|
-
|
2995
|
-
|
3311
|
+
|
3312
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-multiple-orders
|
3313
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order
|
3314
|
+
|
2996
3315
|
:param str[] ids: order ids
|
2997
3316
|
:param str symbol: unified market symbol
|
2998
3317
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -3011,9 +3330,9 @@ class okx(Exchange, ImplicitAPI):
|
|
3011
3330
|
method = self.safe_string(params, 'method', defaultMethod)
|
3012
3331
|
clientOrderIds = self.parse_ids(self.safe_value_2(params, 'clOrdId', 'clientOrderId'))
|
3013
3332
|
algoIds = self.parse_ids(self.safe_value(params, 'algoId'))
|
3014
|
-
|
3333
|
+
trigger = self.safe_value_2(params, 'stop', 'trigger')
|
3015
3334
|
trailing = self.safe_bool(params, 'trailing', False)
|
3016
|
-
if
|
3335
|
+
if trigger or trailing:
|
3017
3336
|
method = 'privatePostTradeCancelAlgos'
|
3018
3337
|
if clientOrderIds is None:
|
3019
3338
|
ids = self.parse_ids(ids)
|
@@ -3024,7 +3343,7 @@ class okx(Exchange, ImplicitAPI):
|
|
3024
3343
|
'instId': market['id'],
|
3025
3344
|
})
|
3026
3345
|
for i in range(0, len(ids)):
|
3027
|
-
if trailing or
|
3346
|
+
if trailing or trigger:
|
3028
3347
|
request.append({
|
3029
3348
|
'algoId': ids[i],
|
3030
3349
|
'instId': market['id'],
|
@@ -3074,11 +3393,116 @@ class okx(Exchange, ImplicitAPI):
|
|
3074
3393
|
# "msg": ""
|
3075
3394
|
# }
|
3076
3395
|
#
|
3077
|
-
ordersData = self.
|
3396
|
+
ordersData = self.safe_list(response, 'data', [])
|
3078
3397
|
return self.parse_orders(ordersData, market, None, None, params)
|
3079
3398
|
|
3080
|
-
def
|
3081
|
-
|
3399
|
+
async def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
|
3400
|
+
"""
|
3401
|
+
cancel multiple orders for multiple symbols
|
3402
|
+
|
3403
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-multiple-orders
|
3404
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order
|
3405
|
+
|
3406
|
+
:param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol, example [{"id": "a", "symbol": "BTC/USDT"}, {"id": "b", "symbol": "ETH/USDT"}]
|
3407
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3408
|
+
:param boolean [params.trigger]: whether the order is a stop/trigger order
|
3409
|
+
:param boolean [params.trailing]: set to True if you want to cancel trailing orders
|
3410
|
+
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
3411
|
+
"""
|
3412
|
+
await self.load_markets()
|
3413
|
+
request = []
|
3414
|
+
options = self.safe_dict(self.options, 'cancelOrders', {})
|
3415
|
+
defaultMethod = self.safe_string(options, 'method', 'privatePostTradeCancelBatchOrders')
|
3416
|
+
method = self.safe_string(params, 'method', defaultMethod)
|
3417
|
+
trigger = self.safe_bool_2(params, 'stop', 'trigger')
|
3418
|
+
trailing = self.safe_bool(params, 'trailing', False)
|
3419
|
+
isStopOrTrailing = trigger or trailing
|
3420
|
+
if isStopOrTrailing:
|
3421
|
+
method = 'privatePostTradeCancelAlgos'
|
3422
|
+
for i in range(0, len(orders)):
|
3423
|
+
order = orders[i]
|
3424
|
+
id = self.safe_string(order, 'id')
|
3425
|
+
clientOrderId = self.safe_string_2(order, 'clOrdId', 'clientOrderId')
|
3426
|
+
symbol = self.safe_string(order, 'symbol')
|
3427
|
+
market = self.market(symbol)
|
3428
|
+
idKey = 'ordId'
|
3429
|
+
if isStopOrTrailing:
|
3430
|
+
idKey = 'algoId'
|
3431
|
+
elif clientOrderId is not None:
|
3432
|
+
idKey = 'clOrdId'
|
3433
|
+
requestItem: dict = {
|
3434
|
+
'instId': market['id'],
|
3435
|
+
}
|
3436
|
+
requestItem[idKey] = clientOrderId if (clientOrderId is not None) else id
|
3437
|
+
request.append(requestItem)
|
3438
|
+
response = None
|
3439
|
+
if method == 'privatePostTradeCancelAlgos':
|
3440
|
+
response = await self.privatePostTradeCancelAlgos(request) # * dont self.extend with params, otherwise ARRAY will be turned into OBJECT
|
3441
|
+
else:
|
3442
|
+
response = await self.privatePostTradeCancelBatchOrders(request) # * dont self.extend with params, otherwise ARRAY will be turned into OBJECT
|
3443
|
+
#
|
3444
|
+
# {
|
3445
|
+
# "code": "0",
|
3446
|
+
# "data": [
|
3447
|
+
# {
|
3448
|
+
# "clOrdId": "e123456789ec4dBC1123456ba123b45e",
|
3449
|
+
# "ordId": "405071912345641543",
|
3450
|
+
# "sCode": "0",
|
3451
|
+
# "sMsg": ""
|
3452
|
+
# },
|
3453
|
+
# ...
|
3454
|
+
# ],
|
3455
|
+
# "msg": ""
|
3456
|
+
# }
|
3457
|
+
#
|
3458
|
+
# Algo order
|
3459
|
+
#
|
3460
|
+
# {
|
3461
|
+
# "code": "0",
|
3462
|
+
# "data": [
|
3463
|
+
# {
|
3464
|
+
# "algoId": "431375349042380800",
|
3465
|
+
# "sCode": "0",
|
3466
|
+
# "sMsg": ""
|
3467
|
+
# }
|
3468
|
+
# ],
|
3469
|
+
# "msg": ""
|
3470
|
+
# }
|
3471
|
+
#
|
3472
|
+
ordersData = self.safe_list(response, 'data', [])
|
3473
|
+
return self.parse_orders(ordersData, None, None, None, params)
|
3474
|
+
|
3475
|
+
async def cancel_all_orders_after(self, timeout: Int, params={}):
|
3476
|
+
"""
|
3477
|
+
dead man's switch, cancel all orders after the given timeout
|
3478
|
+
|
3479
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-all-after
|
3480
|
+
|
3481
|
+
:param number timeout: time in milliseconds, 0 represents cancel the timer
|
3482
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3483
|
+
:returns dict: the api result
|
3484
|
+
"""
|
3485
|
+
await self.load_markets()
|
3486
|
+
request: dict = {
|
3487
|
+
'timeOut': self.parse_to_int(timeout / 1000) if (timeout > 0) else 0,
|
3488
|
+
}
|
3489
|
+
response = await self.privatePostTradeCancelAllAfter(self.extend(request, params))
|
3490
|
+
#
|
3491
|
+
# {
|
3492
|
+
# "code":"0",
|
3493
|
+
# "msg":"",
|
3494
|
+
# "data":[
|
3495
|
+
# {
|
3496
|
+
# "triggerTime":"1587971460",
|
3497
|
+
# "ts":"1587971400"
|
3498
|
+
# }
|
3499
|
+
# ]
|
3500
|
+
# }
|
3501
|
+
#
|
3502
|
+
return response
|
3503
|
+
|
3504
|
+
def parse_order_status(self, status: Str):
|
3505
|
+
statuses: dict = {
|
3082
3506
|
'canceled': 'canceled',
|
3083
3507
|
'order_failed': 'canceled',
|
3084
3508
|
'live': 'open',
|
@@ -3088,7 +3512,7 @@ class okx(Exchange, ImplicitAPI):
|
|
3088
3512
|
}
|
3089
3513
|
return self.safe_string(statuses, status, status)
|
3090
3514
|
|
3091
|
-
def parse_order(self, order, market: Market = None) -> Order:
|
3515
|
+
def parse_order(self, order: dict, market: Market = None) -> Order:
|
3092
3516
|
#
|
3093
3517
|
# createOrder
|
3094
3518
|
#
|
@@ -3254,7 +3678,6 @@ class okx(Exchange, ImplicitAPI):
|
|
3254
3678
|
clientOrderId = None # fix empty clientOrderId string
|
3255
3679
|
stopLossPrice = self.safe_number_2(order, 'slTriggerPx', 'slOrdPx')
|
3256
3680
|
takeProfitPrice = self.safe_number_2(order, 'tpTriggerPx', 'tpOrdPx')
|
3257
|
-
stopPrice = self.safe_number_n(order, ['triggerPx', 'moveTriggerPx'])
|
3258
3681
|
reduceOnlyRaw = self.safe_string(order, 'reduceOnly')
|
3259
3682
|
reduceOnly = False
|
3260
3683
|
if reduceOnly is not None:
|
@@ -3275,8 +3698,7 @@ class okx(Exchange, ImplicitAPI):
|
|
3275
3698
|
'price': price,
|
3276
3699
|
'stopLossPrice': stopLossPrice,
|
3277
3700
|
'takeProfitPrice': takeProfitPrice,
|
3278
|
-
'
|
3279
|
-
'triggerPrice': stopPrice,
|
3701
|
+
'triggerPrice': self.safe_number_n(order, ['triggerPx', 'moveTriggerPx']),
|
3280
3702
|
'average': average,
|
3281
3703
|
'cost': cost,
|
3282
3704
|
'amount': amount,
|
@@ -3291,8 +3713,10 @@ class okx(Exchange, ImplicitAPI):
|
|
3291
3713
|
async def fetch_order(self, id: str, symbol: Str = None, params={}):
|
3292
3714
|
"""
|
3293
3715
|
fetch an order by the id
|
3294
|
-
|
3295
|
-
|
3716
|
+
|
3717
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-details
|
3718
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-details
|
3719
|
+
|
3296
3720
|
:param str id: the order id
|
3297
3721
|
:param str symbol: unified market symbol
|
3298
3722
|
:param dict [params]: extra and exchange specific parameters
|
@@ -3303,7 +3727,7 @@ class okx(Exchange, ImplicitAPI):
|
|
3303
3727
|
raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
|
3304
3728
|
await self.load_markets()
|
3305
3729
|
market = self.market(symbol)
|
3306
|
-
request = {
|
3730
|
+
request: dict = {
|
3307
3731
|
'instId': market['id'],
|
3308
3732
|
# 'clOrdId': 'abcdef12345', # optional, [a-z0-9]{1,32}
|
3309
3733
|
# 'ordId': id,
|
@@ -3313,8 +3737,8 @@ class okx(Exchange, ImplicitAPI):
|
|
3313
3737
|
options = self.safe_value(self.options, 'fetchOrder', {})
|
3314
3738
|
defaultMethod = self.safe_string(options, 'method', 'privateGetTradeOrder')
|
3315
3739
|
method = self.safe_string(params, 'method', defaultMethod)
|
3316
|
-
|
3317
|
-
if
|
3740
|
+
trigger = self.safe_value_2(params, 'stop', 'trigger')
|
3741
|
+
if trigger:
|
3318
3742
|
method = 'privateGetTradeOrderAlgo'
|
3319
3743
|
if clientOrderId is not None:
|
3320
3744
|
request['algoClOrdId'] = clientOrderId
|
@@ -3428,19 +3852,21 @@ class okx(Exchange, ImplicitAPI):
|
|
3428
3852
|
# }
|
3429
3853
|
#
|
3430
3854
|
data = self.safe_value(response, 'data', [])
|
3431
|
-
order = self.
|
3855
|
+
order = self.safe_dict(data, 0)
|
3432
3856
|
return self.parse_order(order, market)
|
3433
3857
|
|
3434
3858
|
async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
3435
3859
|
"""
|
3436
3860
|
fetch all unfilled currently open orders
|
3437
|
-
|
3438
|
-
|
3861
|
+
|
3862
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-list
|
3863
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-list
|
3864
|
+
|
3439
3865
|
:param str symbol: unified market symbol
|
3440
3866
|
:param int [since]: the earliest time in ms to fetch open orders for
|
3441
3867
|
:param int [limit]: the maximum number of open orders structures to retrieve
|
3442
3868
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3443
|
-
:param bool [params.
|
3869
|
+
:param bool [params.trigger]: True if fetching trigger or conditional orders
|
3444
3870
|
:param str [params.ordType]: "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"
|
3445
3871
|
:param str [params.algoId]: Algo ID "'433845797218942976'"
|
3446
3872
|
: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)
|
@@ -3452,7 +3878,7 @@ class okx(Exchange, ImplicitAPI):
|
|
3452
3878
|
paginate, params = self.handle_option_and_params(params, 'fetchOpenOrders', 'paginate')
|
3453
3879
|
if paginate:
|
3454
3880
|
return await self.fetch_paginated_call_dynamic('fetchOpenOrders', symbol, since, limit, params)
|
3455
|
-
request = {
|
3881
|
+
request: dict = {
|
3456
3882
|
# 'instType': 'SPOT', # SPOT, MARGIN, SWAP, FUTURES, OPTION
|
3457
3883
|
# 'uly': currency['id'],
|
3458
3884
|
# 'instId': market['id'],
|
@@ -3473,13 +3899,13 @@ class okx(Exchange, ImplicitAPI):
|
|
3473
3899
|
defaultMethod = self.safe_string(options, 'method', 'privateGetTradeOrdersPending')
|
3474
3900
|
method = self.safe_string(params, 'method', defaultMethod)
|
3475
3901
|
ordType = self.safe_string(params, 'ordType')
|
3476
|
-
|
3902
|
+
trigger = self.safe_value_2(params, 'stop', 'trigger')
|
3477
3903
|
trailing = self.safe_bool(params, 'trailing', False)
|
3478
|
-
if trailing or
|
3904
|
+
if trailing or trigger or (ordType in algoOrderTypes):
|
3479
3905
|
method = 'privateGetTradeOrdersAlgoPending'
|
3480
3906
|
if trailing:
|
3481
3907
|
request['ordType'] = 'move_order_stop'
|
3482
|
-
elif
|
3908
|
+
elif trigger and (ordType is None):
|
3483
3909
|
request['ordType'] = 'trigger'
|
3484
3910
|
query = self.omit(params, ['method', 'stop', 'trigger', 'trailing'])
|
3485
3911
|
response = None
|
@@ -3582,19 +4008,21 @@ class okx(Exchange, ImplicitAPI):
|
|
3582
4008
|
# "msg": ""
|
3583
4009
|
# }
|
3584
4010
|
#
|
3585
|
-
data = self.
|
4011
|
+
data = self.safe_list(response, 'data', [])
|
3586
4012
|
return self.parse_orders(data, market, since, limit)
|
3587
4013
|
|
3588
4014
|
async def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
3589
4015
|
"""
|
3590
4016
|
fetches information on multiple canceled orders made by the user
|
3591
|
-
|
3592
|
-
|
4017
|
+
|
4018
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-history-last-7-days
|
4019
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-history
|
4020
|
+
|
3593
4021
|
:param str symbol: unified market symbol of the market orders were made in
|
3594
4022
|
:param int [since]: timestamp in ms of the earliest order, default is None
|
3595
4023
|
:param int [limit]: max number of orders to return, default is None
|
3596
4024
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3597
|
-
:param bool [params.
|
4025
|
+
:param bool [params.trigger]: True if fetching trigger or conditional orders
|
3598
4026
|
:param str [params.ordType]: "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"
|
3599
4027
|
:param str [params.algoId]: Algo ID "'433845797218942976'"
|
3600
4028
|
:param int [params.until]: timestamp in ms to fetch orders for
|
@@ -3602,7 +4030,7 @@ class okx(Exchange, ImplicitAPI):
|
|
3602
4030
|
:returns dict: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
3603
4031
|
"""
|
3604
4032
|
await self.load_markets()
|
3605
|
-
request = {
|
4033
|
+
request: dict = {
|
3606
4034
|
# 'instType': type.upper(), # SPOT, MARGIN, SWAP, FUTURES, OPTION
|
3607
4035
|
# 'uly': currency['id'],
|
3608
4036
|
# 'instId': market['id'],
|
@@ -3629,27 +4057,27 @@ class okx(Exchange, ImplicitAPI):
|
|
3629
4057
|
defaultMethod = self.safe_string(options, 'method', 'privateGetTradeOrdersHistory')
|
3630
4058
|
method = self.safe_string(params, 'method', defaultMethod)
|
3631
4059
|
ordType = self.safe_string(params, 'ordType')
|
3632
|
-
|
4060
|
+
trigger = self.safe_value_2(params, 'stop', 'trigger')
|
3633
4061
|
trailing = self.safe_bool(params, 'trailing', False)
|
3634
4062
|
if trailing:
|
3635
4063
|
method = 'privateGetTradeOrdersAlgoHistory'
|
3636
4064
|
request['ordType'] = 'move_order_stop'
|
3637
|
-
elif
|
4065
|
+
elif trigger or (ordType in algoOrderTypes):
|
3638
4066
|
method = 'privateGetTradeOrdersAlgoHistory'
|
3639
4067
|
algoId = self.safe_string(params, 'algoId')
|
3640
4068
|
if algoId is not None:
|
3641
4069
|
request['algoId'] = algoId
|
3642
4070
|
params = self.omit(params, 'algoId')
|
3643
|
-
if
|
4071
|
+
if trigger:
|
3644
4072
|
if ordType is None:
|
3645
4073
|
raise ArgumentsRequired(self.id + ' fetchCanceledOrders() requires an "ordType" string parameter, "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"')
|
3646
4074
|
else:
|
3647
4075
|
if since is not None:
|
3648
4076
|
request['begin'] = since
|
3649
|
-
until = self.
|
4077
|
+
until = self.safe_integer(query, 'until')
|
3650
4078
|
if until is not None:
|
3651
4079
|
request['end'] = until
|
3652
|
-
query = self.omit(query, ['until'
|
4080
|
+
query = self.omit(query, ['until'])
|
3653
4081
|
send = self.omit(query, ['method', 'stop', 'trigger', 'trailing'])
|
3654
4082
|
response = None
|
3655
4083
|
if method == 'privateGetTradeOrdersAlgoHistory':
|
@@ -3755,15 +4183,17 @@ class okx(Exchange, ImplicitAPI):
|
|
3755
4183
|
# "msg": ""
|
3756
4184
|
# }
|
3757
4185
|
#
|
3758
|
-
data = self.
|
4186
|
+
data = self.safe_list(response, 'data', [])
|
3759
4187
|
return self.parse_orders(data, market, since, limit)
|
3760
4188
|
|
3761
4189
|
async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
3762
4190
|
"""
|
3763
4191
|
fetches information on multiple closed orders made by the user
|
3764
|
-
|
3765
|
-
|
3766
|
-
|
4192
|
+
|
4193
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-history-last-7-days
|
4194
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-history
|
4195
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-history-last-3-months
|
4196
|
+
|
3767
4197
|
:param str symbol: unified market symbol of the market orders were made in
|
3768
4198
|
:param int [since]: the earliest time in ms to fetch orders for
|
3769
4199
|
:param int [limit]: the maximum number of order structures to retrieve
|
@@ -3782,7 +4212,7 @@ class okx(Exchange, ImplicitAPI):
|
|
3782
4212
|
paginate, params = self.handle_option_and_params(params, 'fetchClosedOrders', 'paginate')
|
3783
4213
|
if paginate:
|
3784
4214
|
return await self.fetch_paginated_call_dynamic('fetchClosedOrders', symbol, since, limit, params)
|
3785
|
-
request = {
|
4215
|
+
request: dict = {
|
3786
4216
|
# 'instType': type.upper(), # SPOT, MARGIN, SWAP, FUTURES, OPTION
|
3787
4217
|
# 'uly': currency['id'],
|
3788
4218
|
# 'instId': market['id'],
|
@@ -3808,23 +4238,23 @@ class okx(Exchange, ImplicitAPI):
|
|
3808
4238
|
defaultMethod = self.safe_string(options, 'method', 'privateGetTradeOrdersHistory')
|
3809
4239
|
method = self.safe_string(params, 'method', defaultMethod)
|
3810
4240
|
ordType = self.safe_string(params, 'ordType')
|
3811
|
-
|
4241
|
+
trigger = self.safe_bool_2(params, 'stop', 'trigger')
|
3812
4242
|
trailing = self.safe_bool(params, 'trailing', False)
|
3813
|
-
if trailing or
|
4243
|
+
if trailing or trigger or (ordType in algoOrderTypes):
|
3814
4244
|
method = 'privateGetTradeOrdersAlgoHistory'
|
3815
4245
|
request['state'] = 'effective'
|
3816
4246
|
if trailing:
|
3817
4247
|
request['ordType'] = 'move_order_stop'
|
3818
|
-
elif
|
4248
|
+
elif trigger:
|
3819
4249
|
if ordType is None:
|
3820
4250
|
request['ordType'] = 'trigger'
|
3821
4251
|
else:
|
3822
4252
|
if since is not None:
|
3823
4253
|
request['begin'] = since
|
3824
|
-
until = self.
|
4254
|
+
until = self.safe_integer(query, 'until')
|
3825
4255
|
if until is not None:
|
3826
4256
|
request['end'] = until
|
3827
|
-
query = self.omit(query, ['until'
|
4257
|
+
query = self.omit(query, ['until'])
|
3828
4258
|
request['state'] = 'filled'
|
3829
4259
|
send = self.omit(query, ['method', 'stop', 'trigger', 'trailing'])
|
3830
4260
|
response = None
|
@@ -3929,13 +4359,15 @@ class okx(Exchange, ImplicitAPI):
|
|
3929
4359
|
# "msg": ""
|
3930
4360
|
# }
|
3931
4361
|
#
|
3932
|
-
data = self.
|
4362
|
+
data = self.safe_list(response, 'data', [])
|
3933
4363
|
return self.parse_orders(data, market, since, limit)
|
3934
4364
|
|
3935
4365
|
async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
3936
4366
|
"""
|
3937
4367
|
fetch all trades made by the user
|
3938
|
-
|
4368
|
+
|
4369
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-transaction-details-last-3-months
|
4370
|
+
|
3939
4371
|
:param str symbol: unified market symbol
|
3940
4372
|
:param int [since]: the earliest time in ms to fetch trades for
|
3941
4373
|
:param int [limit]: the maximum number of trades structures to retrieve
|
@@ -3949,7 +4381,7 @@ class okx(Exchange, ImplicitAPI):
|
|
3949
4381
|
paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
|
3950
4382
|
if paginate:
|
3951
4383
|
return await self.fetch_paginated_call_dynamic('fetchMyTrades', symbol, since, limit, params)
|
3952
|
-
request = {
|
4384
|
+
request: dict = {
|
3953
4385
|
# 'instType': 'SPOT', # SPOT, MARGIN, SWAP, FUTURES, OPTION
|
3954
4386
|
# 'uly': currency['id'],
|
3955
4387
|
# 'instId': market['id'],
|
@@ -3995,13 +4427,15 @@ class okx(Exchange, ImplicitAPI):
|
|
3995
4427
|
# "msg": ""
|
3996
4428
|
# }
|
3997
4429
|
#
|
3998
|
-
data = self.
|
4430
|
+
data = self.safe_list(response, 'data', [])
|
3999
4431
|
return self.parse_trades(data, market, since, limit, query)
|
4000
4432
|
|
4001
4433
|
async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
4002
4434
|
"""
|
4003
4435
|
fetch all the trades made from a single order
|
4004
|
-
|
4436
|
+
|
4437
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-transaction-details-last-3-months
|
4438
|
+
|
4005
4439
|
:param str id: order id
|
4006
4440
|
:param str symbol: unified market symbol
|
4007
4441
|
:param int [since]: the earliest time in ms to fetch trades for
|
@@ -4009,7 +4443,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4009
4443
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4010
4444
|
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
4011
4445
|
"""
|
4012
|
-
request = {
|
4446
|
+
request: dict = {
|
4013
4447
|
# 'instrument_id': market['id'],
|
4014
4448
|
'ordId': id,
|
4015
4449
|
# 'after': '1', # return the page after the specified page number
|
@@ -4018,31 +4452,33 @@ class okx(Exchange, ImplicitAPI):
|
|
4018
4452
|
}
|
4019
4453
|
return await self.fetch_my_trades(symbol, since, limit, self.extend(request, params))
|
4020
4454
|
|
4021
|
-
async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
|
4455
|
+
async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
|
4022
4456
|
"""
|
4023
4457
|
fetch the history of changes, actions done by the user or operations that altered balance of the user
|
4024
|
-
|
4025
|
-
|
4026
|
-
|
4027
|
-
|
4458
|
+
|
4459
|
+
https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-7-days
|
4460
|
+
https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-3-months
|
4461
|
+
https://www.okx.com/docs-v5/en/#rest-api-funding-asset-bills-details
|
4462
|
+
|
4463
|
+
:param str [code]: unified currency code, default is None
|
4028
4464
|
:param int [since]: timestamp in ms of the earliest ledger entry, default is None
|
4029
|
-
:param int [limit]: max number of ledger
|
4465
|
+
:param int [limit]: max number of ledger entries to return, default is None
|
4030
4466
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4031
4467
|
:param str [params.marginMode]: 'cross' or 'isolated'
|
4032
4468
|
:param int [params.until]: the latest time in ms to fetch entries for
|
4033
|
-
:param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [
|
4034
|
-
:returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger
|
4469
|
+
: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)
|
4470
|
+
:returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
|
4035
4471
|
"""
|
4036
4472
|
await self.load_markets()
|
4037
4473
|
paginate = False
|
4038
4474
|
paginate, params = self.handle_option_and_params(params, 'fetchLedger', 'paginate')
|
4039
4475
|
if paginate:
|
4040
4476
|
return await self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params)
|
4041
|
-
options = self.
|
4477
|
+
options = self.safe_dict(self.options, 'fetchLedger', {})
|
4042
4478
|
method = self.safe_string(options, 'method')
|
4043
4479
|
method = self.safe_string(params, 'method', method)
|
4044
4480
|
params = self.omit(params, 'method')
|
4045
|
-
request = {
|
4481
|
+
request: dict = {
|
4046
4482
|
# 'instType': None, # 'SPOT', 'MARGIN', 'SWAP', 'FUTURES", 'OPTION'
|
4047
4483
|
# 'ccy': None, # currency['id'],
|
4048
4484
|
# 'mgnMode': None, # 'isolated', 'cross'
|
@@ -4127,11 +4563,11 @@ class okx(Exchange, ImplicitAPI):
|
|
4127
4563
|
# ]
|
4128
4564
|
# }
|
4129
4565
|
#
|
4130
|
-
data = self.
|
4566
|
+
data = self.safe_list(response, 'data', [])
|
4131
4567
|
return self.parse_ledger(data, currency, since, limit)
|
4132
4568
|
|
4133
4569
|
def parse_ledger_entry_type(self, type):
|
4134
|
-
types = {
|
4570
|
+
types: dict = {
|
4135
4571
|
'1': 'transfer', # transfer
|
4136
4572
|
'2': 'trade', # trade
|
4137
4573
|
'3': 'trade', # delivery
|
@@ -4146,7 +4582,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4146
4582
|
}
|
4147
4583
|
return self.safe_string(types, type, type)
|
4148
4584
|
|
4149
|
-
def parse_ledger_entry(self, item, currency: Currency = None):
|
4585
|
+
def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
|
4150
4586
|
#
|
4151
4587
|
# privateGetAccountBills, privateGetAccountBillsArchive
|
4152
4588
|
#
|
@@ -4183,14 +4619,9 @@ class okx(Exchange, ImplicitAPI):
|
|
4183
4619
|
# "ts": "1597026383085"
|
4184
4620
|
# }
|
4185
4621
|
#
|
4186
|
-
|
4187
|
-
|
4188
|
-
|
4189
|
-
referenceAccount = None
|
4190
|
-
type = self.parse_ledger_entry_type(self.safe_string(item, 'type'))
|
4191
|
-
code = self.safe_currency_code(self.safe_string(item, 'ccy'), currency)
|
4192
|
-
amountString = self.safe_string(item, 'balChg')
|
4193
|
-
amount = self.parse_number(amountString)
|
4622
|
+
currencyId = self.safe_string(item, 'ccy')
|
4623
|
+
code = self.safe_currency_code(currencyId, currency)
|
4624
|
+
currency = self.safe_currency(currencyId, currency)
|
4194
4625
|
timestamp = self.safe_integer(item, 'ts')
|
4195
4626
|
feeCostString = self.safe_string(item, 'fee')
|
4196
4627
|
fee = None
|
@@ -4199,31 +4630,27 @@ class okx(Exchange, ImplicitAPI):
|
|
4199
4630
|
'cost': self.parse_number(Precise.string_neg(feeCostString)),
|
4200
4631
|
'currency': code,
|
4201
4632
|
}
|
4202
|
-
before = None
|
4203
|
-
afterString = self.safe_string(item, 'bal')
|
4204
|
-
after = self.parse_number(afterString)
|
4205
|
-
status = 'ok'
|
4206
4633
|
marketId = self.safe_string(item, 'instId')
|
4207
4634
|
symbol = self.safe_symbol(marketId, None, '-')
|
4208
|
-
return {
|
4209
|
-
'id': id,
|
4635
|
+
return self.safe_ledger_entry({
|
4210
4636
|
'info': item,
|
4637
|
+
'id': self.safe_string(item, 'billId'),
|
4211
4638
|
'timestamp': timestamp,
|
4212
4639
|
'datetime': self.iso8601(timestamp),
|
4213
|
-
'account':
|
4214
|
-
'referenceId':
|
4215
|
-
'referenceAccount':
|
4216
|
-
'type': type,
|
4640
|
+
'account': None,
|
4641
|
+
'referenceId': self.safe_string(item, 'ordId'),
|
4642
|
+
'referenceAccount': None,
|
4643
|
+
'type': self.parse_ledger_entry_type(self.safe_string(item, 'type')),
|
4217
4644
|
'currency': code,
|
4218
4645
|
'symbol': symbol,
|
4219
|
-
'amount':
|
4220
|
-
'before':
|
4221
|
-
'after':
|
4222
|
-
'status':
|
4646
|
+
'amount': self.safe_number(item, 'balChg'),
|
4647
|
+
'before': None,
|
4648
|
+
'after': self.safe_number(item, 'bal'),
|
4649
|
+
'status': 'ok',
|
4223
4650
|
'fee': fee,
|
4224
|
-
}
|
4651
|
+
}, currency)
|
4225
4652
|
|
4226
|
-
def parse_deposit_address(self, depositAddress, currency: Currency = None):
|
4653
|
+
def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
|
4227
4654
|
#
|
4228
4655
|
# {
|
4229
4656
|
# "addr": "okbtothemoon",
|
@@ -4311,24 +4738,26 @@ class okx(Exchange, ImplicitAPI):
|
|
4311
4738
|
networkCode = self.network_id_to_code(network, code)
|
4312
4739
|
self.check_address(address)
|
4313
4740
|
return {
|
4741
|
+
'info': depositAddress,
|
4314
4742
|
'currency': code,
|
4743
|
+
'network': networkCode,
|
4315
4744
|
'address': address,
|
4316
4745
|
'tag': tag,
|
4317
|
-
'network': networkCode,
|
4318
|
-
'info': depositAddress,
|
4319
4746
|
}
|
4320
4747
|
|
4321
|
-
async def fetch_deposit_addresses_by_network(self, code: str, params={}):
|
4748
|
+
async def fetch_deposit_addresses_by_network(self, code: str, params={}) -> List[DepositAddress]:
|
4322
4749
|
"""
|
4323
4750
|
fetch a dictionary of addresses for a currency, indexed by network
|
4324
|
-
|
4751
|
+
|
4752
|
+
https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
|
4753
|
+
|
4325
4754
|
:param str code: unified currency code of the currency for the deposit address
|
4326
4755
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4327
4756
|
:returns dict: a dictionary of `address structures <https://docs.ccxt.com/#/?id=address-structure>` indexed by the network
|
4328
4757
|
"""
|
4329
4758
|
await self.load_markets()
|
4330
4759
|
currency = self.currency(code)
|
4331
|
-
request = {
|
4760
|
+
request: dict = {
|
4332
4761
|
'ccy': currency['id'],
|
4333
4762
|
}
|
4334
4763
|
response = await self.privateGetAssetDepositAddress(self.extend(request, params))
|
@@ -4353,48 +4782,47 @@ class okx(Exchange, ImplicitAPI):
|
|
4353
4782
|
# ]
|
4354
4783
|
# }
|
4355
4784
|
#
|
4356
|
-
data = self.
|
4785
|
+
data = self.safe_list(response, 'data', [])
|
4357
4786
|
filtered = self.filter_by(data, 'selected', True)
|
4358
4787
|
parsed = self.parse_deposit_addresses(filtered, [currency['code']], False)
|
4359
4788
|
return self.index_by(parsed, 'network')
|
4360
4789
|
|
4361
|
-
async def fetch_deposit_address(self, code: str, params={}):
|
4790
|
+
async def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
|
4362
4791
|
"""
|
4363
4792
|
fetch the deposit address for a currency associated with self account
|
4364
|
-
|
4793
|
+
|
4794
|
+
https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
|
4795
|
+
|
4365
4796
|
:param str code: unified currency code
|
4366
4797
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4798
|
+
:param str [params.network]: the network name for the deposit address
|
4367
4799
|
:returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
|
4368
4800
|
"""
|
4801
|
+
await self.load_markets()
|
4369
4802
|
rawNetwork = self.safe_string_upper(params, 'network')
|
4370
|
-
networks = self.safe_value(self.options, 'networks', {})
|
4371
|
-
network = self.safe_string(networks, rawNetwork, rawNetwork)
|
4372
4803
|
params = self.omit(params, 'network')
|
4804
|
+
code = self.safe_currency_code(code)
|
4805
|
+
network = self.network_id_to_code(rawNetwork, code)
|
4373
4806
|
response = await self.fetch_deposit_addresses_by_network(code, params)
|
4374
|
-
|
4375
|
-
|
4376
|
-
result = self.safe_value(response, code)
|
4807
|
+
if network is not None:
|
4808
|
+
result = self.safe_dict(response, network)
|
4377
4809
|
if result is None:
|
4378
|
-
|
4379
|
-
result = self.safe_value(response, alias)
|
4380
|
-
if result is None:
|
4381
|
-
defaultNetwork = self.safe_string(self.options, 'defaultNetwork', 'ERC20')
|
4382
|
-
result = self.safe_value(response, defaultNetwork)
|
4383
|
-
if result is None:
|
4384
|
-
values = list(response.values())
|
4385
|
-
result = self.safe_value(values, 0)
|
4386
|
-
if result is None:
|
4387
|
-
raise InvalidAddress(self.id + ' fetchDepositAddress() cannot find deposit address for ' + code)
|
4810
|
+
raise InvalidAddress(self.id + ' fetchDepositAddress() cannot find ' + network + ' deposit address for ' + code)
|
4388
4811
|
return result
|
4389
|
-
|
4390
|
-
if
|
4391
|
-
|
4392
|
-
return
|
4812
|
+
codeNetwork = self.network_id_to_code(code, code)
|
4813
|
+
if codeNetwork in response:
|
4814
|
+
return response[codeNetwork]
|
4815
|
+
# if the network is not specified, return the first address
|
4816
|
+
keys = list(response.keys())
|
4817
|
+
first = self.safe_string(keys, 0)
|
4818
|
+
return self.safe_dict(response, first)
|
4393
4819
|
|
4394
|
-
async def withdraw(self, code: str, amount: float, address, tag=None, params={}):
|
4820
|
+
async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
|
4395
4821
|
"""
|
4396
4822
|
make a withdrawal
|
4397
|
-
|
4823
|
+
|
4824
|
+
https://www.okx.com/docs-v5/en/#funding-account-rest-api-withdrawal
|
4825
|
+
|
4398
4826
|
:param str code: unified currency code
|
4399
4827
|
:param float amount: the amount to withdraw
|
4400
4828
|
:param str address: the address to withdraw to
|
@@ -4408,7 +4836,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4408
4836
|
currency = self.currency(code)
|
4409
4837
|
if (tag is not None) and (len(tag) > 0):
|
4410
4838
|
address = address + ':' + tag
|
4411
|
-
request = {
|
4839
|
+
request: dict = {
|
4412
4840
|
'ccy': currency['id'],
|
4413
4841
|
'toAddr': address,
|
4414
4842
|
'dest': '4', # 2 = OKCoin International, 3 = OKX 4 = others
|
@@ -4416,7 +4844,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4416
4844
|
}
|
4417
4845
|
network = self.safe_string(params, 'network') # self line allows the user to specify either ERC20 or ETH
|
4418
4846
|
if network is not None:
|
4419
|
-
networks = self.
|
4847
|
+
networks = self.safe_dict(self.options, 'networks', {})
|
4420
4848
|
network = self.safe_string(networks, network.upper(), network) # handle ETH>ERC20 alias
|
4421
4849
|
request['chain'] = currency['id'] + '-' + network
|
4422
4850
|
params = self.omit(params, 'network')
|
@@ -4424,23 +4852,12 @@ class okx(Exchange, ImplicitAPI):
|
|
4424
4852
|
if fee is None:
|
4425
4853
|
currencies = await self.fetch_currencies()
|
4426
4854
|
self.currencies = self.deep_extend(self.currencies, currencies)
|
4427
|
-
targetNetwork = self.
|
4855
|
+
targetNetwork = self.safe_dict(currency['networks'], self.network_id_to_code(network), {})
|
4428
4856
|
fee = self.safe_string(targetNetwork, 'fee')
|
4429
4857
|
if fee is None:
|
4430
4858
|
raise ArgumentsRequired(self.id + ' withdraw() requires a "fee" string parameter, network transaction fee must be ≥ 0. Withdrawals to OKCoin or OKX are fee-free, please set "0". Withdrawing to external digital asset address requires network transaction fee.')
|
4431
4859
|
request['fee'] = self.number_to_string(fee) # withdrawals to OKCoin or OKX are fee-free, please set 0
|
4432
|
-
|
4433
|
-
request['pwd'] = params['password']
|
4434
|
-
elif 'pwd' in params:
|
4435
|
-
request['pwd'] = params['pwd']
|
4436
|
-
else:
|
4437
|
-
options = self.safe_value(self.options, 'withdraw', {})
|
4438
|
-
password = self.safe_string_2(options, 'password', 'pwd')
|
4439
|
-
if password is not None:
|
4440
|
-
request['pwd'] = password
|
4441
|
-
query = self.omit(params, ['fee', 'password', 'pwd'])
|
4442
|
-
if not ('pwd' in request):
|
4443
|
-
raise ExchangeError(self.id + ' withdraw() requires a password parameter or a pwd parameter, it must be the funding password, not the API passphrase')
|
4860
|
+
query = self.omit(params, ['fee'])
|
4444
4861
|
response = await self.privatePostAssetWithdrawal(self.extend(request, query))
|
4445
4862
|
#
|
4446
4863
|
# {
|
@@ -4455,14 +4872,16 @@ class okx(Exchange, ImplicitAPI):
|
|
4455
4872
|
# ]
|
4456
4873
|
# }
|
4457
4874
|
#
|
4458
|
-
data = self.
|
4459
|
-
transaction = self.
|
4875
|
+
data = self.safe_list(response, 'data', [])
|
4876
|
+
transaction = self.safe_dict(data, 0)
|
4460
4877
|
return self.parse_transaction(transaction, currency)
|
4461
4878
|
|
4462
4879
|
async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
4463
4880
|
"""
|
4464
4881
|
fetch all deposits made to an account
|
4465
|
-
|
4882
|
+
|
4883
|
+
https://www.okx.com/docs-v5/en/#rest-api-funding-get-deposit-history
|
4884
|
+
|
4466
4885
|
:param str code: unified currency code
|
4467
4886
|
:param int [since]: the earliest time in ms to fetch deposits for
|
4468
4887
|
:param int [limit]: the maximum number of deposits structures to retrieve
|
@@ -4476,7 +4895,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4476
4895
|
paginate, params = self.handle_option_and_params(params, 'fetchDeposits', 'paginate')
|
4477
4896
|
if paginate:
|
4478
4897
|
return await self.fetch_paginated_call_dynamic('fetchDeposits', code, since, limit, params)
|
4479
|
-
request = {
|
4898
|
+
request: dict = {
|
4480
4899
|
# 'ccy': currency['id'],
|
4481
4900
|
# 'state': 2, # 0 waiting for confirmation, 1 deposit credited, 2 deposit successful
|
4482
4901
|
# 'after': since,
|
@@ -4531,20 +4950,22 @@ class okx(Exchange, ImplicitAPI):
|
|
4531
4950
|
# ]
|
4532
4951
|
# }
|
4533
4952
|
#
|
4534
|
-
data = self.
|
4953
|
+
data = self.safe_list(response, 'data', [])
|
4535
4954
|
return self.parse_transactions(data, currency, since, limit, params)
|
4536
4955
|
|
4537
4956
|
async def fetch_deposit(self, id: str, code: Str = None, params={}):
|
4538
4957
|
"""
|
4539
4958
|
fetch data on a currency deposit via the deposit id
|
4540
|
-
|
4959
|
+
|
4960
|
+
https://www.okx.com/docs-v5/en/#rest-api-funding-get-deposit-history
|
4961
|
+
|
4541
4962
|
:param str id: deposit id
|
4542
4963
|
:param str code: filter by currency code
|
4543
4964
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4544
4965
|
:returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
|
4545
4966
|
"""
|
4546
4967
|
await self.load_markets()
|
4547
|
-
request = {
|
4968
|
+
request: dict = {
|
4548
4969
|
'depId': id,
|
4549
4970
|
}
|
4550
4971
|
currency = None
|
@@ -4553,13 +4974,15 @@ class okx(Exchange, ImplicitAPI):
|
|
4553
4974
|
request['ccy'] = currency['id']
|
4554
4975
|
response = await self.privateGetAssetDepositHistory(self.extend(request, params))
|
4555
4976
|
data = self.safe_value(response, 'data')
|
4556
|
-
deposit = self.
|
4977
|
+
deposit = self.safe_dict(data, 0, {})
|
4557
4978
|
return self.parse_transaction(deposit, currency)
|
4558
4979
|
|
4559
4980
|
async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
4560
4981
|
"""
|
4561
4982
|
fetch all withdrawals made from an account
|
4562
|
-
|
4983
|
+
|
4984
|
+
https://www.okx.com/docs-v5/en/#rest-api-funding-get-withdrawal-history
|
4985
|
+
|
4563
4986
|
:param str code: unified currency code
|
4564
4987
|
:param int [since]: the earliest time in ms to fetch withdrawals for
|
4565
4988
|
:param int [limit]: the maximum number of withdrawals structures to retrieve
|
@@ -4573,7 +4996,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4573
4996
|
paginate, params = self.handle_option_and_params(params, 'fetchWithdrawals', 'paginate')
|
4574
4997
|
if paginate:
|
4575
4998
|
return await self.fetch_paginated_call_dynamic('fetchWithdrawals', code, since, limit, params)
|
4576
|
-
request = {
|
4999
|
+
request: dict = {
|
4577
5000
|
# 'ccy': currency['id'],
|
4578
5001
|
# 'state': 2, # -3: pending cancel, -2 canceled, -1 failed, 0, pending, 1 sending, 2 sent, 3 awaiting email verification, 4 awaiting manual verification, 5 awaiting identity verification
|
4579
5002
|
# 'after': since,
|
@@ -4620,20 +5043,22 @@ class okx(Exchange, ImplicitAPI):
|
|
4620
5043
|
# ]
|
4621
5044
|
# }
|
4622
5045
|
#
|
4623
|
-
data = self.
|
5046
|
+
data = self.safe_list(response, 'data', [])
|
4624
5047
|
return self.parse_transactions(data, currency, since, limit, params)
|
4625
5048
|
|
4626
5049
|
async def fetch_withdrawal(self, id: str, code: Str = None, params={}):
|
4627
5050
|
"""
|
4628
5051
|
fetch data on a currency withdrawal via the withdrawal id
|
4629
|
-
|
5052
|
+
|
5053
|
+
https://www.okx.com/docs-v5/en/#rest-api-funding-get-withdrawal-history
|
5054
|
+
|
4630
5055
|
:param str id: withdrawal id
|
4631
5056
|
:param str code: unified currency code of the currency withdrawn, default is None
|
4632
5057
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4633
5058
|
:returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
|
4634
5059
|
"""
|
4635
5060
|
await self.load_markets()
|
4636
|
-
request = {
|
5061
|
+
request: dict = {
|
4637
5062
|
'wdId': id,
|
4638
5063
|
}
|
4639
5064
|
currency = None
|
@@ -4662,11 +5087,11 @@ class okx(Exchange, ImplicitAPI):
|
|
4662
5087
|
# "msg": ''
|
4663
5088
|
# }
|
4664
5089
|
#
|
4665
|
-
data = self.
|
4666
|
-
withdrawal = self.
|
5090
|
+
data = self.safe_list(response, 'data', [])
|
5091
|
+
withdrawal = self.safe_dict(data, 0, {})
|
4667
5092
|
return self.parse_transaction(withdrawal)
|
4668
5093
|
|
4669
|
-
def parse_transaction_status(self, status):
|
5094
|
+
def parse_transaction_status(self, status: Str):
|
4670
5095
|
#
|
4671
5096
|
# deposit statuses
|
4672
5097
|
#
|
@@ -4690,7 +5115,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4690
5115
|
# "5": "awaiting identity verification"
|
4691
5116
|
# }
|
4692
5117
|
#
|
4693
|
-
statuses = {
|
5118
|
+
statuses: dict = {
|
4694
5119
|
'-3': 'pending',
|
4695
5120
|
'-2': 'canceled',
|
4696
5121
|
'-1': 'failed',
|
@@ -4700,10 +5125,18 @@ class okx(Exchange, ImplicitAPI):
|
|
4700
5125
|
'3': 'pending',
|
4701
5126
|
'4': 'pending',
|
4702
5127
|
'5': 'pending',
|
5128
|
+
'6': 'pending',
|
5129
|
+
'7': 'pending',
|
5130
|
+
'8': 'pending',
|
5131
|
+
'9': 'pending',
|
5132
|
+
'10': 'pending',
|
5133
|
+
'12': 'pending',
|
5134
|
+
'15': 'pending',
|
5135
|
+
'16': 'pending',
|
4703
5136
|
}
|
4704
5137
|
return self.safe_string(statuses, status, status)
|
4705
5138
|
|
4706
|
-
def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
|
5139
|
+
def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
|
4707
5140
|
#
|
4708
5141
|
# withdraw
|
4709
5142
|
#
|
@@ -4799,7 +5232,9 @@ class okx(Exchange, ImplicitAPI):
|
|
4799
5232
|
async def fetch_leverage(self, symbol: str, params={}) -> Leverage:
|
4800
5233
|
"""
|
4801
5234
|
fetch the set leverage for a market
|
4802
|
-
|
5235
|
+
|
5236
|
+
https://www.okx.com/docs-v5/en/#rest-api-account-get-leverage
|
5237
|
+
|
4803
5238
|
:param str symbol: unified market symbol
|
4804
5239
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4805
5240
|
:param str [params.marginMode]: 'cross' or 'isolated'
|
@@ -4813,7 +5248,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4813
5248
|
if (marginMode != 'cross') and (marginMode != 'isolated'):
|
4814
5249
|
raise BadRequest(self.id + ' fetchLeverage() requires a marginMode parameter that must be either cross or isolated')
|
4815
5250
|
market = self.market(symbol)
|
4816
|
-
request = {
|
5251
|
+
request: dict = {
|
4817
5252
|
'instId': market['id'],
|
4818
5253
|
'mgnMode': marginMode,
|
4819
5254
|
}
|
@@ -4835,7 +5270,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4835
5270
|
data = self.safe_list(response, 'data', [])
|
4836
5271
|
return self.parse_leverage(data, market)
|
4837
5272
|
|
4838
|
-
def parse_leverage(self, leverage, market=None) -> Leverage:
|
5273
|
+
def parse_leverage(self, leverage: dict, market: Market = None) -> Leverage:
|
4839
5274
|
marketId = None
|
4840
5275
|
marginMode = None
|
4841
5276
|
longLeverage = None
|
@@ -4863,7 +5298,9 @@ class okx(Exchange, ImplicitAPI):
|
|
4863
5298
|
async def fetch_position(self, symbol: str, params={}):
|
4864
5299
|
"""
|
4865
5300
|
fetch data on a single open contract trade position
|
4866
|
-
|
5301
|
+
|
5302
|
+
https://www.okx.com/docs-v5/en/#rest-api-account-get-positions
|
5303
|
+
|
4867
5304
|
:param str symbol: unified market symbol of the market the position is held in, default is None
|
4868
5305
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4869
5306
|
:param str [params.instType]: MARGIN, SWAP, FUTURES, OPTION
|
@@ -4872,7 +5309,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4872
5309
|
await self.load_markets()
|
4873
5310
|
market = self.market(symbol)
|
4874
5311
|
type, query = self.handle_market_type_and_params('fetchPosition', market, params)
|
4875
|
-
request = {
|
5312
|
+
request: dict = {
|
4876
5313
|
# instType str No Instrument type, MARGIN, SWAP, FUTURES, OPTION
|
4877
5314
|
'instId': market['id'],
|
4878
5315
|
# posId str No Single position ID or multiple position IDs(no more than 20) separated with comma
|
@@ -4926,16 +5363,18 @@ class okx(Exchange, ImplicitAPI):
|
|
4926
5363
|
# ]
|
4927
5364
|
# }
|
4928
5365
|
#
|
4929
|
-
data = self.
|
4930
|
-
position = self.
|
5366
|
+
data = self.safe_list(response, 'data', [])
|
5367
|
+
position = self.safe_dict(data, 0)
|
4931
5368
|
if position is None:
|
4932
5369
|
return None
|
4933
5370
|
return self.parse_position(position, market)
|
4934
5371
|
|
4935
5372
|
async def fetch_positions(self, symbols: Strings = None, params={}):
|
4936
5373
|
"""
|
4937
|
-
|
4938
|
-
|
5374
|
+
|
5375
|
+
https://www.okx.com/docs-v5/en/#rest-api-account-get-positions
|
5376
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-positions-history history
|
5377
|
+
|
4939
5378
|
fetch all open positions
|
4940
5379
|
:param str[]|None symbols: list of unified market symbols
|
4941
5380
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -4943,7 +5382,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4943
5382
|
:returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
4944
5383
|
"""
|
4945
5384
|
await self.load_markets()
|
4946
|
-
request = {
|
5385
|
+
request: dict = {
|
4947
5386
|
# 'instType': 'MARGIN', # optional string, MARGIN, SWAP, FUTURES, OPTION
|
4948
5387
|
# 'instId': market['id'], # optional string, e.g. 'BTC-USD-190927-5000-C'
|
4949
5388
|
# 'posId': '307173036051017730', # optional string, Single or multiple position IDs(no more than 20) separated with commas
|
@@ -4957,7 +5396,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4957
5396
|
marketIdsLength = len(marketIds)
|
4958
5397
|
if marketIdsLength > 0:
|
4959
5398
|
request['instId'] = ','.join(marketIds)
|
4960
|
-
fetchPositionsOptions = self.
|
5399
|
+
fetchPositionsOptions = self.safe_dict(self.options, 'fetchPositions', {})
|
4961
5400
|
method = self.safe_string(fetchPositionsOptions, 'method', 'privateGetAccountPositions')
|
4962
5401
|
response = None
|
4963
5402
|
if method == 'privateGetAccountPositionsHistory':
|
@@ -5010,15 +5449,17 @@ class okx(Exchange, ImplicitAPI):
|
|
5010
5449
|
# ]
|
5011
5450
|
# }
|
5012
5451
|
#
|
5013
|
-
positions = self.
|
5452
|
+
positions = self.safe_list(response, 'data', [])
|
5014
5453
|
result = []
|
5015
5454
|
for i in range(0, len(positions)):
|
5016
5455
|
result.append(self.parse_position(positions[i]))
|
5017
|
-
return self.filter_by_array_positions(result, 'symbol', symbols, False)
|
5456
|
+
return self.filter_by_array_positions(result, 'symbol', self.market_symbols(symbols), False)
|
5018
5457
|
|
5019
5458
|
async def fetch_positions_for_symbol(self, symbol: str, params={}):
|
5020
5459
|
"""
|
5021
|
-
|
5460
|
+
|
5461
|
+
https://www.okx.com/docs-v5/en/#rest-api-account-get-positions
|
5462
|
+
|
5022
5463
|
fetch all open positions for specific symbol
|
5023
5464
|
:param str symbol: unified market symbol
|
5024
5465
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -5027,7 +5468,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5027
5468
|
"""
|
5028
5469
|
return await self.fetch_positions([symbol], params)
|
5029
5470
|
|
5030
|
-
def parse_position(self, position, market: Market = None):
|
5471
|
+
def parse_position(self, position: dict, market: Market = None):
|
5031
5472
|
#
|
5032
5473
|
# {
|
5033
5474
|
# "adl": "3",
|
@@ -5095,7 +5536,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5095
5536
|
# }
|
5096
5537
|
#
|
5097
5538
|
marketId = self.safe_string(position, 'instId')
|
5098
|
-
market = self.safe_market(marketId, market)
|
5539
|
+
market = self.safe_market(marketId, market, None, 'contract')
|
5099
5540
|
symbol = market['symbol']
|
5100
5541
|
pos = self.safe_string(position, 'pos') # 'pos' field: One way mode: 0 if position is not open, 1 if open | Two way(hedge) mode: -1 if short, 1 if long, 0 if position is not open
|
5101
5542
|
contractsAbs = Precise.string_abs(pos)
|
@@ -5188,7 +5629,9 @@ class okx(Exchange, ImplicitAPI):
|
|
5188
5629
|
async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
5189
5630
|
"""
|
5190
5631
|
transfer currency internally between wallets on the same account
|
5191
|
-
|
5632
|
+
|
5633
|
+
https://www.okx.com/docs-v5/en/#rest-api-funding-funds-transfer
|
5634
|
+
|
5192
5635
|
:param str code: unified currency code
|
5193
5636
|
:param float amount: amount to transfer
|
5194
5637
|
:param str fromAccount: account to transfer from
|
@@ -5198,10 +5641,10 @@ class okx(Exchange, ImplicitAPI):
|
|
5198
5641
|
"""
|
5199
5642
|
await self.load_markets()
|
5200
5643
|
currency = self.currency(code)
|
5201
|
-
accountsByType = self.
|
5644
|
+
accountsByType = self.safe_dict(self.options, 'accountsByType', {})
|
5202
5645
|
fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
|
5203
5646
|
toId = self.safe_string(accountsByType, toAccount, toAccount)
|
5204
|
-
request = {
|
5647
|
+
request: dict = {
|
5205
5648
|
'ccy': currency['id'],
|
5206
5649
|
'amt': self.currency_to_precision(code, amount),
|
5207
5650
|
'type': '0', # 0 = transfer within account by default, 1 = master account to sub-account, 2 = sub-account to master account, 3 = sub-account to master account(Only applicable to APIKey from sub-account), 4 = sub-account to sub-account
|
@@ -5238,11 +5681,11 @@ class okx(Exchange, ImplicitAPI):
|
|
5238
5681
|
# ]
|
5239
5682
|
# }
|
5240
5683
|
#
|
5241
|
-
data = self.
|
5242
|
-
rawTransfer = self.
|
5684
|
+
data = self.safe_list(response, 'data', [])
|
5685
|
+
rawTransfer = self.safe_dict(data, 0, {})
|
5243
5686
|
return self.parse_transfer(rawTransfer, currency)
|
5244
5687
|
|
5245
|
-
def parse_transfer(self, transfer, currency: Currency = None):
|
5688
|
+
def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
|
5246
5689
|
#
|
5247
5690
|
# transfer
|
5248
5691
|
#
|
@@ -5301,7 +5744,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5301
5744
|
amount = self.safe_number(transfer, 'amt')
|
5302
5745
|
fromAccountId = self.safe_string(transfer, 'from')
|
5303
5746
|
toAccountId = self.safe_string(transfer, 'to')
|
5304
|
-
accountsById = self.
|
5747
|
+
accountsById = self.safe_dict(self.options, 'accountsById', {})
|
5305
5748
|
timestamp = self.safe_integer(transfer, 'ts')
|
5306
5749
|
balanceChange = self.safe_string(transfer, 'sz')
|
5307
5750
|
if balanceChange is not None:
|
@@ -5318,15 +5761,15 @@ class okx(Exchange, ImplicitAPI):
|
|
5318
5761
|
'status': self.parse_transfer_status(self.safe_string(transfer, 'state')),
|
5319
5762
|
}
|
5320
5763
|
|
5321
|
-
def parse_transfer_status(self, status):
|
5322
|
-
statuses = {
|
5764
|
+
def parse_transfer_status(self, status: Str) -> Str:
|
5765
|
+
statuses: dict = {
|
5323
5766
|
'success': 'ok',
|
5324
5767
|
}
|
5325
5768
|
return self.safe_string(statuses, status, status)
|
5326
5769
|
|
5327
|
-
async def fetch_transfer(self, id: str, code: Str = None, params={}):
|
5770
|
+
async def fetch_transfer(self, id: str, code: Str = None, params={}) -> TransferEntry:
|
5328
5771
|
await self.load_markets()
|
5329
|
-
request = {
|
5772
|
+
request: dict = {
|
5330
5773
|
'transId': id,
|
5331
5774
|
# 'type': 0, # default is 0 transfer within account, 1 master to sub, 2 sub to master
|
5332
5775
|
}
|
@@ -5351,14 +5794,16 @@ class okx(Exchange, ImplicitAPI):
|
|
5351
5794
|
# "msg": ""
|
5352
5795
|
# }
|
5353
5796
|
#
|
5354
|
-
data = self.
|
5355
|
-
transfer = self.
|
5797
|
+
data = self.safe_list(response, 'data', [])
|
5798
|
+
transfer = self.safe_dict(data, 0)
|
5356
5799
|
return self.parse_transfer(transfer)
|
5357
5800
|
|
5358
|
-
async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
|
5801
|
+
async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[TransferEntry]:
|
5359
5802
|
"""
|
5360
5803
|
fetch a history of internal transfers made on an account
|
5361
|
-
|
5804
|
+
|
5805
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months
|
5806
|
+
|
5362
5807
|
:param str code: unified currency code of the currency transferred
|
5363
5808
|
:param int [since]: the earliest time in ms to fetch transfers for
|
5364
5809
|
:param int [limit]: the maximum number of transfers structures to retrieve
|
@@ -5367,7 +5812,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5367
5812
|
"""
|
5368
5813
|
await self.load_markets()
|
5369
5814
|
currency = None
|
5370
|
-
request = {
|
5815
|
+
request: dict = {
|
5371
5816
|
'type': '1', # https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-3-months
|
5372
5817
|
}
|
5373
5818
|
if code is not None:
|
@@ -5410,7 +5855,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5410
5855
|
# "msg": ""
|
5411
5856
|
# }
|
5412
5857
|
#
|
5413
|
-
transfers = self.
|
5858
|
+
transfers = self.safe_list(response, 'data', [])
|
5414
5859
|
return self.parse_transfers(transfers, currency, since, limit, params)
|
5415
5860
|
|
5416
5861
|
def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
|
@@ -5440,7 +5885,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5440
5885
|
if clientOrderId is None:
|
5441
5886
|
params['clOrdId'] = brokerId + self.uuid16()
|
5442
5887
|
params['tag'] = brokerId
|
5443
|
-
timestamp = self.iso8601(self.
|
5888
|
+
timestamp = self.iso8601(self.nonce())
|
5444
5889
|
headers = {
|
5445
5890
|
'OK-ACCESS-KEY': self.apiKey,
|
5446
5891
|
'OK-ACCESS-PASSPHRASE': self.password,
|
@@ -5464,7 +5909,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5464
5909
|
headers['OK-ACCESS-SIGN'] = signature
|
5465
5910
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
5466
5911
|
|
5467
|
-
def parse_funding_rate(self, contract, market: Market = None):
|
5912
|
+
def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
|
5468
5913
|
#
|
5469
5914
|
# {
|
5470
5915
|
# "fundingRate": "0.00027815",
|
@@ -5474,6 +5919,22 @@ class okx(Exchange, ImplicitAPI):
|
|
5474
5919
|
# "nextFundingRate": "0.00017",
|
5475
5920
|
# "nextFundingTime": "1634284800000"
|
5476
5921
|
# }
|
5922
|
+
# ws
|
5923
|
+
# {
|
5924
|
+
# "fundingRate":"0.0001875391284828",
|
5925
|
+
# "fundingTime":"1700726400000",
|
5926
|
+
# "instId":"BTC-USD-SWAP",
|
5927
|
+
# "instType":"SWAP",
|
5928
|
+
# "method": "next_period",
|
5929
|
+
# "maxFundingRate":"0.00375",
|
5930
|
+
# "minFundingRate":"-0.00375",
|
5931
|
+
# "nextFundingRate":"0.0002608059239328",
|
5932
|
+
# "nextFundingTime":"1700755200000",
|
5933
|
+
# "premium": "0.0001233824646391",
|
5934
|
+
# "settFundingRate":"0.0001699799259033",
|
5935
|
+
# "settState":"settled",
|
5936
|
+
# "ts":"1700724675402"
|
5937
|
+
# }
|
5477
5938
|
#
|
5478
5939
|
# in the response above nextFundingRate is actually two funding rates from now
|
5479
5940
|
#
|
@@ -5482,6 +5943,9 @@ class okx(Exchange, ImplicitAPI):
|
|
5482
5943
|
symbol = self.safe_symbol(marketId, market)
|
5483
5944
|
nextFundingRate = self.safe_number(contract, 'nextFundingRate')
|
5484
5945
|
fundingTime = self.safe_integer(contract, 'fundingTime')
|
5946
|
+
fundingTimeString = self.safe_string(contract, 'fundingTime')
|
5947
|
+
nextFundingTimeString = self.safe_string(contract, 'nextFundingRate')
|
5948
|
+
millisecondsInterval = Precise.string_sub(nextFundingTimeString, fundingTimeString)
|
5485
5949
|
# https://www.okx.com/support/hc/en-us/articles/360053909272-Ⅸ-Introduction-to-perpetual-swap-funding-fee
|
5486
5950
|
# > The current interest is 0.
|
5487
5951
|
return {
|
@@ -5502,12 +5966,37 @@ class okx(Exchange, ImplicitAPI):
|
|
5502
5966
|
'previousFundingRate': None,
|
5503
5967
|
'previousFundingTimestamp': None,
|
5504
5968
|
'previousFundingDatetime': None,
|
5969
|
+
'interval': self.parse_funding_interval(millisecondsInterval),
|
5505
5970
|
}
|
5506
5971
|
|
5507
|
-
|
5972
|
+
def parse_funding_interval(self, interval):
|
5973
|
+
intervals: dict = {
|
5974
|
+
'3600000': '1h',
|
5975
|
+
'14400000': '4h',
|
5976
|
+
'28800000': '8h',
|
5977
|
+
'57600000': '16h',
|
5978
|
+
'86400000': '24h',
|
5979
|
+
}
|
5980
|
+
return self.safe_string(intervals, interval, interval)
|
5981
|
+
|
5982
|
+
async def fetch_funding_interval(self, symbol: str, params={}) -> FundingRate:
|
5983
|
+
"""
|
5984
|
+
fetch the current funding rate interval
|
5985
|
+
|
5986
|
+
https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate
|
5987
|
+
|
5988
|
+
:param str symbol: unified market symbol
|
5989
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
5990
|
+
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
5991
|
+
"""
|
5992
|
+
return await self.fetch_funding_rate(symbol, params)
|
5993
|
+
|
5994
|
+
async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
5508
5995
|
"""
|
5509
5996
|
fetch the current funding rate
|
5510
|
-
|
5997
|
+
|
5998
|
+
https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate
|
5999
|
+
|
5511
6000
|
:param str symbol: unified market symbol
|
5512
6001
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
5513
6002
|
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
@@ -5516,7 +6005,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5516
6005
|
market = self.market(symbol)
|
5517
6006
|
if not market['swap']:
|
5518
6007
|
raise ExchangeError(self.id + ' fetchFundingRate() is only valid for swap markets')
|
5519
|
-
request = {
|
6008
|
+
request: dict = {
|
5520
6009
|
'instId': market['id'],
|
5521
6010
|
}
|
5522
6011
|
response = await self.publicGetPublicFundingRate(self.extend(request, params))
|
@@ -5536,14 +6025,16 @@ class okx(Exchange, ImplicitAPI):
|
|
5536
6025
|
# "msg": ""
|
5537
6026
|
# }
|
5538
6027
|
#
|
5539
|
-
data = self.
|
5540
|
-
entry = self.
|
6028
|
+
data = self.safe_list(response, 'data', [])
|
6029
|
+
entry = self.safe_dict(data, 0, {})
|
5541
6030
|
return self.parse_funding_rate(entry, market)
|
5542
6031
|
|
5543
6032
|
async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
5544
6033
|
"""
|
5545
6034
|
fetch the history of funding payments paid and received on self account
|
5546
|
-
|
6035
|
+
|
6036
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months
|
6037
|
+
|
5547
6038
|
:param str symbol: unified market symbol
|
5548
6039
|
:param int [since]: the earliest time in ms to fetch funding history for
|
5549
6040
|
:param int [limit]: the maximum number of funding history structures to retrieve
|
@@ -5551,7 +6042,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5551
6042
|
:returns dict: a `funding history structure <https://docs.ccxt.com/#/?id=funding-history-structure>`
|
5552
6043
|
"""
|
5553
6044
|
await self.load_markets()
|
5554
|
-
request = {
|
6045
|
+
request: dict = {
|
5555
6046
|
# 'instType': 'SPOT', # SPOT, MARGIN, SWAP, FUTURES, OPTION
|
5556
6047
|
# 'ccy': currency['id'],
|
5557
6048
|
# 'mgnMode': 'isolated', # isolated, cross
|
@@ -5669,7 +6160,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5669
6160
|
# "type": "8"
|
5670
6161
|
# }
|
5671
6162
|
#
|
5672
|
-
data = self.
|
6163
|
+
data = self.safe_list(response, 'data', [])
|
5673
6164
|
result = []
|
5674
6165
|
for i in range(0, len(data)):
|
5675
6166
|
entry = data[i]
|
@@ -5693,12 +6184,14 @@ class okx(Exchange, ImplicitAPI):
|
|
5693
6184
|
async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
|
5694
6185
|
"""
|
5695
6186
|
set the level of leverage for a market
|
5696
|
-
|
6187
|
+
|
6188
|
+
https://www.okx.com/docs-v5/en/#rest-api-account-set-leverage
|
6189
|
+
|
5697
6190
|
:param float leverage: the rate of leverage
|
5698
6191
|
:param str symbol: unified market symbol
|
5699
6192
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
5700
6193
|
:param str [params.marginMode]: 'cross' or 'isolated'
|
5701
|
-
:param str [params.posSide]: 'long' or 'short' for isolated margin long/short mode on futures and swap markets
|
6194
|
+
:param str [params.posSide]: 'long' or 'short' or 'net' for isolated margin long/short mode on futures and swap markets, default is 'net'
|
5702
6195
|
:returns dict: response from the exchange
|
5703
6196
|
"""
|
5704
6197
|
if symbol is None:
|
@@ -5715,17 +6208,16 @@ class okx(Exchange, ImplicitAPI):
|
|
5715
6208
|
marginMode = self.safe_string(params, 'mgnMode', 'cross') # cross marginMode
|
5716
6209
|
if (marginMode != 'cross') and (marginMode != 'isolated'):
|
5717
6210
|
raise BadRequest(self.id + ' setLeverage() requires a marginMode parameter that must be either cross or isolated')
|
5718
|
-
request = {
|
6211
|
+
request: dict = {
|
5719
6212
|
'lever': leverage,
|
5720
6213
|
'mgnMode': marginMode,
|
5721
6214
|
'instId': market['id'],
|
5722
6215
|
}
|
5723
|
-
posSide = self.safe_string(params, 'posSide')
|
6216
|
+
posSide = self.safe_string(params, 'posSide', 'net')
|
5724
6217
|
if marginMode == 'isolated':
|
5725
|
-
if posSide is None:
|
5726
|
-
raise ArgumentsRequired(self.id + ' setLeverage() requires a posSide argument for isolated margin')
|
5727
6218
|
if posSide != 'long' and posSide != 'short' and posSide != 'net':
|
5728
6219
|
raise BadRequest(self.id + ' setLeverage() requires the posSide argument to be either "long", "short" or "net"')
|
6220
|
+
request['posSide'] = posSide
|
5729
6221
|
response = await self.privatePostAccountSetLeverage(self.extend(request, params))
|
5730
6222
|
#
|
5731
6223
|
# {
|
@@ -5743,10 +6235,44 @@ class okx(Exchange, ImplicitAPI):
|
|
5743
6235
|
#
|
5744
6236
|
return response
|
5745
6237
|
|
6238
|
+
async def fetch_position_mode(self, symbol: Str = None, params={}):
|
6239
|
+
"""
|
6240
|
+
|
6241
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-account-configuration
|
6242
|
+
|
6243
|
+
fetchs the position mode, hedged or one way, hedged for binance is set identically for all linear markets or all inverse markets
|
6244
|
+
:param str symbol: unified symbol of the market to fetch the order book for
|
6245
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
6246
|
+
:param str [params.accountId]: if you have multiple accounts, you must specify the account id to fetch the position mode
|
6247
|
+
:returns dict: an object detailing whether the market is in hedged or one-way mode
|
6248
|
+
"""
|
6249
|
+
accounts = await self.fetch_accounts()
|
6250
|
+
length = len(accounts)
|
6251
|
+
selectedAccount = None
|
6252
|
+
if length > 1:
|
6253
|
+
accountId = self.safe_string(params, 'accountId')
|
6254
|
+
if accountId is None:
|
6255
|
+
accountIds = self.get_list_from_object_values(accounts, 'id')
|
6256
|
+
raise ExchangeError(self.id + ' fetchPositionMode() can not detect position mode, because you have multiple accounts. Set params["accountId"] to desired id from: ' + ', '.join(accountIds))
|
6257
|
+
else:
|
6258
|
+
accountsById = self.index_by(accounts, 'id')
|
6259
|
+
selectedAccount = self.safe_dict(accountsById, accountId)
|
6260
|
+
else:
|
6261
|
+
selectedAccount = accounts[0]
|
6262
|
+
mainAccount = selectedAccount['info']
|
6263
|
+
posMode = self.safe_string(mainAccount, 'posMode') # long_short_mode, net_mode
|
6264
|
+
isHedged = posMode == 'long_short_mode'
|
6265
|
+
return {
|
6266
|
+
'info': mainAccount,
|
6267
|
+
'hedged': isHedged,
|
6268
|
+
}
|
6269
|
+
|
5746
6270
|
async def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
|
5747
6271
|
"""
|
5748
6272
|
set hedged to True or False for a market
|
5749
|
-
|
6273
|
+
|
6274
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-set-position-mode
|
6275
|
+
|
5750
6276
|
:param bool hedged: set to True to use long_short_mode, False for net_mode
|
5751
6277
|
:param str symbol: not used by okx setPositionMode
|
5752
6278
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -5757,7 +6283,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5757
6283
|
hedgeMode = 'long_short_mode'
|
5758
6284
|
else:
|
5759
6285
|
hedgeMode = 'net_mode'
|
5760
|
-
request = {
|
6286
|
+
request: dict = {
|
5761
6287
|
'posMode': hedgeMode,
|
5762
6288
|
}
|
5763
6289
|
response = await self.privatePostAccountSetPositionMode(self.extend(request, params))
|
@@ -5777,7 +6303,9 @@ class okx(Exchange, ImplicitAPI):
|
|
5777
6303
|
async def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
|
5778
6304
|
"""
|
5779
6305
|
set margin mode to 'cross' or 'isolated'
|
5780
|
-
|
6306
|
+
|
6307
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-set-leverage
|
6308
|
+
|
5781
6309
|
:param str marginMode: 'cross' or 'isolated'
|
5782
6310
|
:param str symbol: unified market symbol
|
5783
6311
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -5797,7 +6325,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5797
6325
|
if (lever is None) or (lever < 1) or (lever > 125):
|
5798
6326
|
raise BadRequest(self.id + ' setMarginMode() params["lever"] should be between 1 and 125')
|
5799
6327
|
params = self.omit(params, ['leverage'])
|
5800
|
-
request = {
|
6328
|
+
request: dict = {
|
5801
6329
|
'lever': lever,
|
5802
6330
|
'mgnMode': marginMode,
|
5803
6331
|
'instId': market['id'],
|
@@ -5819,10 +6347,12 @@ class okx(Exchange, ImplicitAPI):
|
|
5819
6347
|
#
|
5820
6348
|
return response
|
5821
6349
|
|
5822
|
-
async def fetch_cross_borrow_rates(self, params={}):
|
6350
|
+
async def fetch_cross_borrow_rates(self, params={}) -> CrossBorrowRates:
|
5823
6351
|
"""
|
5824
6352
|
fetch the borrow interest rates of all currencies
|
5825
|
-
|
6353
|
+
|
6354
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-interest-rate
|
6355
|
+
|
5826
6356
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
5827
6357
|
:returns dict: a list of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>`
|
5828
6358
|
"""
|
@@ -5840,23 +6370,25 @@ class okx(Exchange, ImplicitAPI):
|
|
5840
6370
|
# ],
|
5841
6371
|
# }
|
5842
6372
|
#
|
5843
|
-
data = self.
|
6373
|
+
data = self.safe_list(response, 'data', [])
|
5844
6374
|
rates = []
|
5845
6375
|
for i in range(0, len(data)):
|
5846
6376
|
rates.append(self.parse_borrow_rate(data[i]))
|
5847
6377
|
return rates
|
5848
6378
|
|
5849
|
-
async def fetch_cross_borrow_rate(self, code: str, params={}):
|
6379
|
+
async def fetch_cross_borrow_rate(self, code: str, params={}) -> CrossBorrowRate:
|
5850
6380
|
"""
|
5851
6381
|
fetch the rate of interest to borrow a currency for margin trading
|
5852
|
-
|
6382
|
+
|
6383
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-interest-rate
|
6384
|
+
|
5853
6385
|
:param str code: unified currency code
|
5854
6386
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
5855
6387
|
:returns dict: a `borrow rate structure <https://docs.ccxt.com/#/?id=borrow-rate-structure>`
|
5856
6388
|
"""
|
5857
6389
|
await self.load_markets()
|
5858
6390
|
currency = self.currency(code)
|
5859
|
-
request = {
|
6391
|
+
request: dict = {
|
5860
6392
|
'ccy': currency['id'],
|
5861
6393
|
}
|
5862
6394
|
response = await self.privateGetAccountInterestRate(self.extend(request, params))
|
@@ -5873,8 +6405,8 @@ class okx(Exchange, ImplicitAPI):
|
|
5873
6405
|
# "msg": ""
|
5874
6406
|
# }
|
5875
6407
|
#
|
5876
|
-
data = self.
|
5877
|
-
rate = self.
|
6408
|
+
data = self.safe_list(response, 'data', [])
|
6409
|
+
rate = self.safe_dict(data, 0, {})
|
5878
6410
|
return self.parse_borrow_rate(rate)
|
5879
6411
|
|
5880
6412
|
def parse_borrow_rate(self, info, currency: Currency = None):
|
@@ -5909,7 +6441,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5909
6441
|
# ...
|
5910
6442
|
# ]
|
5911
6443
|
#
|
5912
|
-
borrowRateHistories = {}
|
6444
|
+
borrowRateHistories: dict = {}
|
5913
6445
|
for i in range(0, len(response)):
|
5914
6446
|
item = response[i]
|
5915
6447
|
code = self.safe_currency_code(self.safe_string(item, 'ccy'))
|
@@ -5924,19 +6456,12 @@ class okx(Exchange, ImplicitAPI):
|
|
5924
6456
|
borrowRateHistories[code] = self.filter_by_currency_since_limit(borrowRateHistories[code], code, since, limit)
|
5925
6457
|
return borrowRateHistories
|
5926
6458
|
|
5927
|
-
def parse_borrow_rate_history(self, response, code, since, limit):
|
5928
|
-
result = []
|
5929
|
-
for i in range(0, len(response)):
|
5930
|
-
item = response[i]
|
5931
|
-
borrowRate = self.parse_borrow_rate(item)
|
5932
|
-
result.append(borrowRate)
|
5933
|
-
sorted = self.sort_by(result, 'timestamp')
|
5934
|
-
return self.filter_by_currency_since_limit(sorted, code, since, limit)
|
5935
|
-
|
5936
6459
|
async def fetch_borrow_rate_histories(self, codes=None, since: Int = None, limit: Int = None, params={}):
|
5937
6460
|
"""
|
5938
6461
|
retrieves a history of a multiple currencies borrow interest rate at specific time slots, returns all currencies if no symbols passed, default is None
|
5939
|
-
|
6462
|
+
|
6463
|
+
https://www.okx.com/docs-v5/en/#financial-product-savings-get-public-borrow-history-public
|
6464
|
+
|
5940
6465
|
:param str[]|None codes: list of unified currency codes, default is None
|
5941
6466
|
:param int [since]: timestamp in ms of the earliest borrowRate, default is None
|
5942
6467
|
:param int [limit]: max number of borrow rate prices to return, default is None
|
@@ -5944,7 +6469,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5944
6469
|
:returns dict: a dictionary of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>` indexed by the market symbol
|
5945
6470
|
"""
|
5946
6471
|
await self.load_markets()
|
5947
|
-
request = {
|
6472
|
+
request: dict = {
|
5948
6473
|
# 'ccy': currency['id'],
|
5949
6474
|
# 'after': self.milliseconds(), # Pagination of data to return records earlier than the requested ts,
|
5950
6475
|
# 'before': since, # Pagination of data to return records newer than the requested ts,
|
@@ -5969,13 +6494,15 @@ class okx(Exchange, ImplicitAPI):
|
|
5969
6494
|
# "msg": ""
|
5970
6495
|
# }
|
5971
6496
|
#
|
5972
|
-
data = self.
|
6497
|
+
data = self.safe_list(response, 'data', [])
|
5973
6498
|
return self.parse_borrow_rate_histories(data, codes, since, limit)
|
5974
6499
|
|
5975
6500
|
async def fetch_borrow_rate_history(self, code: str, since: Int = None, limit: Int = None, params={}):
|
5976
6501
|
"""
|
5977
6502
|
retrieves a history of a currencies borrow interest rate at specific time slots
|
5978
|
-
|
6503
|
+
|
6504
|
+
https://www.okx.com/docs-v5/en/#financial-product-savings-get-public-borrow-history-public
|
6505
|
+
|
5979
6506
|
:param str code: unified currency code
|
5980
6507
|
:param int [since]: timestamp for the earliest borrow rate
|
5981
6508
|
:param int [limit]: the maximum number of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>` to retrieve
|
@@ -5984,7 +6511,7 @@ class okx(Exchange, ImplicitAPI):
|
|
5984
6511
|
"""
|
5985
6512
|
await self.load_markets()
|
5986
6513
|
currency = self.currency(code)
|
5987
|
-
request = {
|
6514
|
+
request: dict = {
|
5988
6515
|
'ccy': currency['id'],
|
5989
6516
|
# 'after': self.milliseconds(), # Pagination of data to return records earlier than the requested ts,
|
5990
6517
|
# 'before': since, # Pagination of data to return records newer than the requested ts,
|
@@ -6009,15 +6536,15 @@ class okx(Exchange, ImplicitAPI):
|
|
6009
6536
|
# "msg": ""
|
6010
6537
|
# }
|
6011
6538
|
#
|
6012
|
-
data = self.
|
6539
|
+
data = self.safe_list(response, 'data', [])
|
6013
6540
|
return self.parse_borrow_rate_history(data, code, since, limit)
|
6014
6541
|
|
6015
|
-
async def modify_margin_helper(self, symbol: str, amount, type, params={}):
|
6542
|
+
async def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
|
6016
6543
|
await self.load_markets()
|
6017
6544
|
market = self.market(symbol)
|
6018
6545
|
posSide = self.safe_string(params, 'posSide', 'net')
|
6019
6546
|
params = self.omit(params, ['posSide'])
|
6020
|
-
request = {
|
6547
|
+
request: dict = {
|
6021
6548
|
'instId': market['id'],
|
6022
6549
|
'amt': amount,
|
6023
6550
|
'type': type,
|
@@ -6038,32 +6565,92 @@ class okx(Exchange, ImplicitAPI):
|
|
6038
6565
|
# "msg": ""
|
6039
6566
|
# }
|
6040
6567
|
#
|
6041
|
-
|
6042
|
-
|
6043
|
-
|
6044
|
-
|
6045
|
-
|
6046
|
-
|
6047
|
-
|
6048
|
-
|
6049
|
-
|
6050
|
-
|
6051
|
-
|
6568
|
+
data = self.safe_list(response, 'data', [])
|
6569
|
+
entry = self.safe_dict(data, 0, {})
|
6570
|
+
errorCode = self.safe_string(response, 'code')
|
6571
|
+
return self.extend(self.parse_margin_modification(entry, market), {
|
6572
|
+
'status': 'ok' if (errorCode == '0') else 'failed',
|
6573
|
+
})
|
6574
|
+
|
6575
|
+
def parse_margin_modification(self, data: dict, market: Market = None) -> MarginModification:
|
6576
|
+
#
|
6577
|
+
# addMargin/reduceMargin
|
6578
|
+
#
|
6579
|
+
# {
|
6580
|
+
# "amt": "0.01",
|
6581
|
+
# "instId": "ETH-USD-SWAP",
|
6582
|
+
# "posSide": "net",
|
6583
|
+
# "type": "reduce"
|
6584
|
+
# }
|
6585
|
+
#
|
6586
|
+
# fetchMarginAdjustmentHistory
|
6587
|
+
#
|
6588
|
+
# {
|
6589
|
+
# bal: '67621.4325135010619812',
|
6590
|
+
# balChg: '-10.0000000000000000',
|
6591
|
+
# billId: '691293628710342659',
|
6592
|
+
# ccy: 'USDT',
|
6593
|
+
# clOrdId: '',
|
6594
|
+
# execType: '',
|
6595
|
+
# fee: '0',
|
6596
|
+
# fillFwdPx: '',
|
6597
|
+
# fillIdxPx: '',
|
6598
|
+
# fillMarkPx: '',
|
6599
|
+
# fillMarkVol: '',
|
6600
|
+
# fillPxUsd: '',
|
6601
|
+
# fillPxVol: '',
|
6602
|
+
# fillTime: '1711089244850',
|
6603
|
+
# from: '',
|
6604
|
+
# instId: 'XRP-USDT-SWAP',
|
6605
|
+
# instType: 'SWAP',
|
6606
|
+
# interest: '0',
|
6607
|
+
# mgnMode: 'isolated',
|
6608
|
+
# notes: '',
|
6609
|
+
# ordId: '',
|
6610
|
+
# pnl: '0',
|
6611
|
+
# posBal: '73.12',
|
6612
|
+
# posBalChg: '10.00',
|
6613
|
+
# px: '',
|
6614
|
+
# subType: '160',
|
6615
|
+
# sz: '10',
|
6616
|
+
# tag: '',
|
6617
|
+
# to: '',
|
6618
|
+
# tradeId: '0',
|
6619
|
+
# ts: '1711089244699',
|
6620
|
+
# type: '6'
|
6621
|
+
# }
|
6622
|
+
#
|
6623
|
+
amountRaw = self.safe_string_2(data, 'amt', 'posBalChg')
|
6624
|
+
typeRaw = self.safe_string(data, 'type')
|
6625
|
+
type = None
|
6626
|
+
if typeRaw == '6':
|
6627
|
+
type = 'add' if Precise.string_gt(amountRaw, '0') else 'reduce'
|
6628
|
+
else:
|
6629
|
+
type = typeRaw
|
6630
|
+
amount = Precise.string_abs(amountRaw)
|
6631
|
+
marketId = self.safe_string(data, 'instId')
|
6052
6632
|
responseMarket = self.safe_market(marketId, market)
|
6053
6633
|
code = responseMarket['base'] if responseMarket['inverse'] else responseMarket['quote']
|
6634
|
+
timestamp = self.safe_integer(data, 'ts')
|
6054
6635
|
return {
|
6055
6636
|
'info': data,
|
6637
|
+
'symbol': responseMarket['symbol'],
|
6056
6638
|
'type': type,
|
6057
|
-
'
|
6639
|
+
'marginMode': 'isolated',
|
6640
|
+
'amount': self.parse_number(amount),
|
6058
6641
|
'code': code,
|
6059
|
-
'
|
6060
|
-
'status':
|
6642
|
+
'total': None,
|
6643
|
+
'status': None,
|
6644
|
+
'timestamp': timestamp,
|
6645
|
+
'datetime': self.iso8601(timestamp),
|
6061
6646
|
}
|
6062
6647
|
|
6063
|
-
async def reduce_margin(self, symbol: str, amount, params={}):
|
6648
|
+
async def reduce_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
|
6064
6649
|
"""
|
6065
6650
|
remove margin from a position
|
6066
|
-
|
6651
|
+
|
6652
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-increase-decrease-margin
|
6653
|
+
|
6067
6654
|
:param str symbol: unified market symbol
|
6068
6655
|
:param float amount: the amount of margin to remove
|
6069
6656
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -6071,10 +6658,12 @@ class okx(Exchange, ImplicitAPI):
|
|
6071
6658
|
"""
|
6072
6659
|
return await self.modify_margin_helper(symbol, amount, 'reduce', params)
|
6073
6660
|
|
6074
|
-
async def add_margin(self, symbol: str, amount, params={}):
|
6661
|
+
async def add_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
|
6075
6662
|
"""
|
6076
6663
|
add margin
|
6077
|
-
|
6664
|
+
|
6665
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-increase-decrease-margin
|
6666
|
+
|
6078
6667
|
:param str symbol: unified market symbol
|
6079
6668
|
:param float amount: amount of margin to add
|
6080
6669
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -6082,10 +6671,12 @@ class okx(Exchange, ImplicitAPI):
|
|
6082
6671
|
"""
|
6083
6672
|
return await self.modify_margin_helper(symbol, amount, 'add', params)
|
6084
6673
|
|
6085
|
-
async def fetch_market_leverage_tiers(self, symbol: str, params={}):
|
6674
|
+
async def fetch_market_leverage_tiers(self, symbol: str, params={}) -> List[LeverageTier]:
|
6086
6675
|
"""
|
6087
6676
|
retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes for a single market
|
6088
|
-
|
6677
|
+
|
6678
|
+
https://www.okx.com/docs-v5/en/#rest-api-public-data-get-position-tiers
|
6679
|
+
|
6089
6680
|
:param str symbol: unified market symbol
|
6090
6681
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
6091
6682
|
:param str [params.marginMode]: 'cross' or 'isolated'
|
@@ -6102,7 +6693,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6102
6693
|
marginMode, params = self.handle_margin_mode_and_params('fetchMarketLeverageTiers', params)
|
6103
6694
|
if marginMode is None:
|
6104
6695
|
marginMode = self.safe_string(params, 'tdMode', 'cross') # cross marginMode
|
6105
|
-
request = {
|
6696
|
+
request: dict = {
|
6106
6697
|
'instType': type,
|
6107
6698
|
'tdMode': marginMode,
|
6108
6699
|
'uly': uly,
|
@@ -6131,12 +6722,12 @@ class okx(Exchange, ImplicitAPI):
|
|
6131
6722
|
# ]
|
6132
6723
|
# }
|
6133
6724
|
#
|
6134
|
-
data = self.
|
6725
|
+
data = self.safe_list(response, 'data', [])
|
6135
6726
|
return self.parse_market_leverage_tiers(data, market)
|
6136
6727
|
|
6137
|
-
def parse_market_leverage_tiers(self, info, market: Market = None):
|
6728
|
+
def parse_market_leverage_tiers(self, info, market: Market = None) -> List[LeverageTier]:
|
6138
6729
|
"""
|
6139
|
-
|
6730
|
+
@ignore
|
6140
6731
|
:param dict info: Exchange response for 1 market
|
6141
6732
|
:param dict market: CCXT market
|
6142
6733
|
"""
|
@@ -6161,8 +6752,10 @@ class okx(Exchange, ImplicitAPI):
|
|
6161
6752
|
tiers = []
|
6162
6753
|
for i in range(0, len(info)):
|
6163
6754
|
tier = info[i]
|
6755
|
+
marketId = self.safe_string(tier, 'instId')
|
6164
6756
|
tiers.append({
|
6165
6757
|
'tier': self.safe_integer(tier, 'tier'),
|
6758
|
+
'symbol': self.safe_symbol(marketId, market),
|
6166
6759
|
'currency': market['quote'],
|
6167
6760
|
'minNotional': self.safe_number(tier, 'minSz'),
|
6168
6761
|
'maxNotional': self.safe_number(tier, 'maxSz'),
|
@@ -6172,10 +6765,12 @@ class okx(Exchange, ImplicitAPI):
|
|
6172
6765
|
})
|
6173
6766
|
return tiers
|
6174
6767
|
|
6175
|
-
async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
6768
|
+
async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
|
6176
6769
|
"""
|
6177
6770
|
fetch the interest owed by the user for borrowing currency for margin trading
|
6178
|
-
|
6771
|
+
|
6772
|
+
https://www.okx.com/docs-v5/en/#rest-api-account-get-interest-accrued-data
|
6773
|
+
|
6179
6774
|
:param str code: the unified currency code for the currency of the interest
|
6180
6775
|
:param str symbol: the market symbol of an isolated margin market, if None, the interest for cross margin markets is returned
|
6181
6776
|
:param int [since]: timestamp in ms of the earliest time to receive interest records for
|
@@ -6190,7 +6785,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6190
6785
|
marginMode, params = self.handle_margin_mode_and_params('fetchBorrowInterest', params)
|
6191
6786
|
if marginMode is None:
|
6192
6787
|
marginMode = self.safe_string(params, 'mgnMode', 'cross') # cross marginMode
|
6193
|
-
request = {
|
6788
|
+
request: dict = {
|
6194
6789
|
'mgnMode': marginMode,
|
6195
6790
|
}
|
6196
6791
|
market = None
|
@@ -6224,31 +6819,33 @@ class okx(Exchange, ImplicitAPI):
|
|
6224
6819
|
# "msg": ""
|
6225
6820
|
# }
|
6226
6821
|
#
|
6227
|
-
data = self.
|
6822
|
+
data = self.safe_list(response, 'data', [])
|
6228
6823
|
interest = self.parse_borrow_interests(data)
|
6229
6824
|
return self.filter_by_currency_since_limit(interest, code, since, limit)
|
6230
6825
|
|
6231
|
-
def parse_borrow_interest(self, info, market: Market = None):
|
6826
|
+
def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
|
6232
6827
|
instId = self.safe_string(info, 'instId')
|
6233
6828
|
if instId is not None:
|
6234
6829
|
market = self.safe_market(instId, market)
|
6235
6830
|
timestamp = self.safe_integer(info, 'ts')
|
6236
6831
|
return {
|
6832
|
+
'info': info,
|
6237
6833
|
'symbol': self.safe_string(market, 'symbol'),
|
6238
|
-
'marginMode': self.safe_string(info, 'mgnMode'),
|
6239
6834
|
'currency': self.safe_currency_code(self.safe_string(info, 'ccy')),
|
6240
6835
|
'interest': self.safe_number(info, 'interest'),
|
6241
6836
|
'interestRate': self.safe_number(info, 'interestRate'),
|
6242
6837
|
'amountBorrowed': self.safe_number(info, 'liab'),
|
6838
|
+
'marginMode': self.safe_string(info, 'mgnMode'),
|
6243
6839
|
'timestamp': timestamp, # Interest accrued time
|
6244
6840
|
'datetime': self.iso8601(timestamp),
|
6245
|
-
'info': info,
|
6246
6841
|
}
|
6247
6842
|
|
6248
6843
|
async def borrow_cross_margin(self, code: str, amount: float, params={}):
|
6249
6844
|
"""
|
6250
6845
|
create a loan to borrow margin(need to be VIP 5 and above)
|
6251
|
-
|
6846
|
+
|
6847
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-vip-loans-borrow-and-repay
|
6848
|
+
|
6252
6849
|
:param str code: unified currency code of the currency to borrow
|
6253
6850
|
:param float amount: the amount to borrow
|
6254
6851
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -6256,7 +6853,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6256
6853
|
"""
|
6257
6854
|
await self.load_markets()
|
6258
6855
|
currency = self.currency(code)
|
6259
|
-
request = {
|
6856
|
+
request: dict = {
|
6260
6857
|
'ccy': currency['id'],
|
6261
6858
|
'amt': self.currency_to_precision(code, amount),
|
6262
6859
|
'side': 'borrow',
|
@@ -6277,14 +6874,16 @@ class okx(Exchange, ImplicitAPI):
|
|
6277
6874
|
# "msg": ""
|
6278
6875
|
# }
|
6279
6876
|
#
|
6280
|
-
data = self.
|
6281
|
-
loan = self.
|
6877
|
+
data = self.safe_list(response, 'data', [])
|
6878
|
+
loan = self.safe_dict(data, 0, {})
|
6282
6879
|
return self.parse_margin_loan(loan, currency)
|
6283
6880
|
|
6284
6881
|
async def repay_cross_margin(self, code: str, amount, params={}):
|
6285
6882
|
"""
|
6286
6883
|
repay borrowed margin and interest
|
6287
|
-
|
6884
|
+
|
6885
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-vip-loans-borrow-and-repay
|
6886
|
+
|
6288
6887
|
:param str code: unified currency code of the currency to repay
|
6289
6888
|
:param float amount: the amount to repay
|
6290
6889
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -6297,7 +6896,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6297
6896
|
if id is None:
|
6298
6897
|
raise ArgumentsRequired(self.id + ' repayCrossMargin() requires an id parameter')
|
6299
6898
|
currency = self.currency(code)
|
6300
|
-
request = {
|
6899
|
+
request: dict = {
|
6301
6900
|
'ccy': currency['id'],
|
6302
6901
|
'amt': self.currency_to_precision(code, amount),
|
6303
6902
|
'side': 'repay',
|
@@ -6319,8 +6918,8 @@ class okx(Exchange, ImplicitAPI):
|
|
6319
6918
|
# "msg": ""
|
6320
6919
|
# }
|
6321
6920
|
#
|
6322
|
-
data = self.
|
6323
|
-
loan = self.
|
6921
|
+
data = self.safe_list(response, 'data', [])
|
6922
|
+
loan = self.safe_dict(data, 0, {})
|
6324
6923
|
return self.parse_margin_loan(loan, currency)
|
6325
6924
|
|
6326
6925
|
def parse_margin_loan(self, info, currency: Currency = None):
|
@@ -6349,7 +6948,9 @@ class okx(Exchange, ImplicitAPI):
|
|
6349
6948
|
async def fetch_open_interest(self, symbol: str, params={}):
|
6350
6949
|
"""
|
6351
6950
|
Retrieves the open interest of a currency
|
6352
|
-
|
6951
|
+
|
6952
|
+
https://www.okx.com/docs-v5/en/#rest-api-public-data-get-open-interest
|
6953
|
+
|
6353
6954
|
:param str symbol: Unified CCXT market symbol
|
6354
6955
|
:param dict [params]: exchange specific parameters
|
6355
6956
|
:returns dict} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure:
|
@@ -6360,7 +6961,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6360
6961
|
raise BadRequest(self.id + ' fetchOpenInterest() supports contract markets only')
|
6361
6962
|
type = self.convert_to_instrument_type(market['type'])
|
6362
6963
|
uly = self.safe_string(market['info'], 'uly')
|
6363
|
-
request = {
|
6964
|
+
request: dict = {
|
6364
6965
|
'instType': type,
|
6365
6966
|
'uly': uly,
|
6366
6967
|
'instId': market['id'],
|
@@ -6381,14 +6982,16 @@ class okx(Exchange, ImplicitAPI):
|
|
6381
6982
|
# "msg": ""
|
6382
6983
|
# }
|
6383
6984
|
#
|
6384
|
-
data = self.
|
6985
|
+
data = self.safe_list(response, 'data', [])
|
6385
6986
|
return self.parse_open_interest(data[0], market)
|
6386
6987
|
|
6387
6988
|
async def fetch_open_interest_history(self, symbol: str, timeframe='1d', since: Int = None, limit: Int = None, params={}):
|
6388
6989
|
"""
|
6389
6990
|
Retrieves the open interest history of a currency
|
6390
|
-
|
6391
|
-
|
6991
|
+
|
6992
|
+
https://www.okx.com/docs-v5/en/#rest-api-trading-data-get-contracts-open-interest-and-volume
|
6993
|
+
https://www.okx.com/docs-v5/en/#rest-api-trading-data-get-options-open-interest-and-volume
|
6994
|
+
|
6392
6995
|
:param str symbol: Unified CCXT currency code or unified symbol
|
6393
6996
|
:param str timeframe: "5m", "1h", or "1d" for option only "1d" or "8h"
|
6394
6997
|
:param int [since]: The time in ms of the earliest record to retrieve unix timestamp
|
@@ -6397,8 +7000,8 @@ class okx(Exchange, ImplicitAPI):
|
|
6397
7000
|
:param int [params.until]: The time in ms of the latest record to retrieve unix timestamp
|
6398
7001
|
:returns: An array of `open interest structures <https://docs.ccxt.com/#/?id=open-interest-structure>`
|
6399
7002
|
"""
|
6400
|
-
options = self.
|
6401
|
-
timeframes = self.
|
7003
|
+
options = self.safe_dict(self.options, 'fetchOpenInterestHistory', {})
|
7004
|
+
timeframes = self.safe_dict(options, 'timeframes', {})
|
6402
7005
|
timeframe = self.safe_string(timeframes, timeframe, timeframe)
|
6403
7006
|
if timeframe != '5m' and timeframe != '1H' and timeframe != '1D':
|
6404
7007
|
raise BadRequest(self.id + ' fetchOpenInterestHistory cannot only use the 5m, 1h, and 1d timeframe')
|
@@ -6412,7 +7015,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6412
7015
|
else:
|
6413
7016
|
currency = self.currency(symbol)
|
6414
7017
|
currencyId = currency['id']
|
6415
|
-
request = {
|
7018
|
+
request: dict = {
|
6416
7019
|
'ccy': currencyId,
|
6417
7020
|
'period': timeframe,
|
6418
7021
|
}
|
@@ -6424,10 +7027,10 @@ class okx(Exchange, ImplicitAPI):
|
|
6424
7027
|
else:
|
6425
7028
|
if since is not None:
|
6426
7029
|
request['begin'] = since
|
6427
|
-
until = self.
|
7030
|
+
until = self.safe_integer(params, 'until')
|
6428
7031
|
if until is not None:
|
6429
7032
|
request['end'] = until
|
6430
|
-
params = self.omit(params, ['until'
|
7033
|
+
params = self.omit(params, ['until'])
|
6431
7034
|
response = await self.publicGetRubikStatContractsOpenInterestVolume(self.extend(request, params))
|
6432
7035
|
#
|
6433
7036
|
# {
|
@@ -6443,8 +7046,8 @@ class okx(Exchange, ImplicitAPI):
|
|
6443
7046
|
# "msg": ''
|
6444
7047
|
# }
|
6445
7048
|
#
|
6446
|
-
data = self.
|
6447
|
-
return self.
|
7049
|
+
data = self.safe_list(response, 'data', [])
|
7050
|
+
return self.parse_open_interests_history(data, None, since, limit)
|
6448
7051
|
|
6449
7052
|
def parse_open_interest(self, interest, market: Market = None):
|
6450
7053
|
#
|
@@ -6463,6 +7066,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6463
7066
|
# "instType": "OPTION",
|
6464
7067
|
# "oi": "300",
|
6465
7068
|
# "oiCcy": "3",
|
7069
|
+
# "oiUsd": "3",
|
6466
7070
|
# "ts": "1684551166251"
|
6467
7071
|
# }
|
6468
7072
|
#
|
@@ -6485,7 +7089,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6485
7089
|
else:
|
6486
7090
|
baseVolume = self.safe_number(interest, 'oiCcy')
|
6487
7091
|
openInterestAmount = self.safe_number(interest, 'oi')
|
6488
|
-
openInterestValue = self.safe_number(interest, '
|
7092
|
+
openInterestValue = self.safe_number(interest, 'oiUsd')
|
6489
7093
|
return self.safe_open_interest({
|
6490
7094
|
'symbol': self.safe_symbol(id),
|
6491
7095
|
'baseVolume': baseVolume, # deprecated
|
@@ -6508,13 +7112,19 @@ class okx(Exchange, ImplicitAPI):
|
|
6508
7112
|
async def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
|
6509
7113
|
"""
|
6510
7114
|
fetch deposit and withdraw fees
|
6511
|
-
|
7115
|
+
|
7116
|
+
https://www.okx.com/docs-v5/en/#rest-api-funding-get-currencies
|
7117
|
+
|
6512
7118
|
:param str[]|None codes: list of unified currency codes
|
6513
7119
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
6514
7120
|
:returns dict[]: a list of `fees structures <https://docs.ccxt.com/#/?id=fee-structure>`
|
6515
7121
|
"""
|
6516
7122
|
await self.load_markets()
|
6517
|
-
|
7123
|
+
request = {}
|
7124
|
+
if codes is not None:
|
7125
|
+
ids = self.currency_ids(codes)
|
7126
|
+
request['ccy'] = ','.join(ids)
|
7127
|
+
response = await self.privateGetAssetCurrencies(self.extend(request, params))
|
6518
7128
|
#
|
6519
7129
|
# {
|
6520
7130
|
# "code": "0",
|
@@ -6558,7 +7168,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6558
7168
|
# "msg": ""
|
6559
7169
|
# }
|
6560
7170
|
#
|
6561
|
-
data = self.
|
7171
|
+
data = self.safe_list(response, 'data')
|
6562
7172
|
return self.parse_deposit_withdraw_fees(data, codes)
|
6563
7173
|
|
6564
7174
|
def parse_deposit_withdraw_fees(self, response, codes=None, currencyIdKey=None):
|
@@ -6583,7 +7193,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6583
7193
|
# }
|
6584
7194
|
# ]
|
6585
7195
|
#
|
6586
|
-
depositWithdrawFees = {}
|
7196
|
+
depositWithdrawFees: dict = {}
|
6587
7197
|
codes = self.market_codes(codes)
|
6588
7198
|
for i in range(0, len(response)):
|
6589
7199
|
feeInfo = response[i]
|
@@ -6595,14 +7205,16 @@ class okx(Exchange, ImplicitAPI):
|
|
6595
7205
|
depositWithdrawFees[code] = self.deposit_withdraw_fee({})
|
6596
7206
|
depositWithdrawFees[code]['info'][currencyId] = feeInfo
|
6597
7207
|
chain = self.safe_string(feeInfo, 'chain')
|
7208
|
+
if chain is None:
|
7209
|
+
continue
|
6598
7210
|
chainSplit = chain.split('-')
|
6599
7211
|
networkId = self.safe_value(chainSplit, 1)
|
6600
|
-
withdrawFee = self.safe_number(feeInfo, '
|
6601
|
-
withdrawResult = {
|
7212
|
+
withdrawFee = self.safe_number(feeInfo, 'fee')
|
7213
|
+
withdrawResult: dict = {
|
6602
7214
|
'fee': withdrawFee,
|
6603
7215
|
'percentage': False if (withdrawFee is not None) else None,
|
6604
7216
|
}
|
6605
|
-
depositResult = {
|
7217
|
+
depositResult: dict = {
|
6606
7218
|
'fee': None,
|
6607
7219
|
'percentage': None,
|
6608
7220
|
}
|
@@ -6621,7 +7233,9 @@ class okx(Exchange, ImplicitAPI):
|
|
6621
7233
|
async def fetch_settlement_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
6622
7234
|
"""
|
6623
7235
|
fetches historical settlement records
|
6624
|
-
|
7236
|
+
|
7237
|
+
https://www.okx.com/docs-v5/en/#rest-api-public-data-get-delivery-exercise-history
|
7238
|
+
|
6625
7239
|
:param str symbol: unified market symbol to fetch the settlement history for
|
6626
7240
|
:param int [since]: timestamp in ms
|
6627
7241
|
:param int [limit]: number of records
|
@@ -6636,7 +7250,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6636
7250
|
type, params = self.handle_market_type_and_params('fetchSettlementHistory', market, params)
|
6637
7251
|
if type != 'future' and type != 'option':
|
6638
7252
|
raise NotSupported(self.id + ' fetchSettlementHistory() supports futures and options markets only')
|
6639
|
-
request = {
|
7253
|
+
request: dict = {
|
6640
7254
|
'instType': self.convert_to_instrument_type(type),
|
6641
7255
|
'uly': market['baseId'] + '-' + market['quoteId'],
|
6642
7256
|
}
|
@@ -6663,7 +7277,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6663
7277
|
# "msg": ""
|
6664
7278
|
# }
|
6665
7279
|
#
|
6666
|
-
data = self.
|
7280
|
+
data = self.safe_list(response, 'data', [])
|
6667
7281
|
settlements = self.parse_settlements(data, market)
|
6668
7282
|
sorted = self.sort_by(settlements, 'timestamp')
|
6669
7283
|
return self.filter_by_symbol_since_limit(sorted, market['symbol'], since, limit)
|
@@ -6702,7 +7316,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6702
7316
|
for i in range(0, len(settlements)):
|
6703
7317
|
entry = settlements[i]
|
6704
7318
|
timestamp = self.safe_integer(entry, 'ts')
|
6705
|
-
details = self.
|
7319
|
+
details = self.safe_list(entry, 'details', [])
|
6706
7320
|
for j in range(0, len(details)):
|
6707
7321
|
settlement = self.parse_settlement(details[j], market)
|
6708
7322
|
result.append(self.extend(settlement, {
|
@@ -6714,7 +7328,9 @@ class okx(Exchange, ImplicitAPI):
|
|
6714
7328
|
async def fetch_underlying_assets(self, params={}):
|
6715
7329
|
"""
|
6716
7330
|
fetches the market ids of underlying assets for a specific contract market type
|
6717
|
-
|
7331
|
+
|
7332
|
+
https://www.okx.com/docs-v5/en/#public-data-rest-api-get-underlying
|
7333
|
+
|
6718
7334
|
:param dict [params]: exchange specific params
|
6719
7335
|
:param str [params.type]: the contract market type, 'option', 'swap' or 'future', the default is 'option'
|
6720
7336
|
:returns dict[]: a list of `underlying assets <https://docs.ccxt.com/#/?id=underlying-assets-structure>`
|
@@ -6726,7 +7342,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6726
7342
|
marketType = 'option'
|
6727
7343
|
if (marketType != 'option') and (marketType != 'swap') and (marketType != 'future'):
|
6728
7344
|
raise NotSupported(self.id + ' fetchUnderlyingAssets() supports contract markets only')
|
6729
|
-
request = {
|
7345
|
+
request: dict = {
|
6730
7346
|
'instType': self.convert_to_instrument_type(marketType),
|
6731
7347
|
}
|
6732
7348
|
response = await self.publicGetPublicUnderlying(self.extend(request, params))
|
@@ -6742,13 +7358,15 @@ class okx(Exchange, ImplicitAPI):
|
|
6742
7358
|
# "msg": ""
|
6743
7359
|
# }
|
6744
7360
|
#
|
6745
|
-
underlyings = self.
|
7361
|
+
underlyings = self.safe_list(response, 'data', [])
|
6746
7362
|
return underlyings[0]
|
6747
7363
|
|
6748
7364
|
async def fetch_greeks(self, symbol: str, params={}) -> Greeks:
|
6749
7365
|
"""
|
6750
7366
|
fetches an option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract
|
6751
|
-
|
7367
|
+
|
7368
|
+
https://www.okx.com/docs-v5/en/#public-data-rest-api-get-option-market-data
|
7369
|
+
|
6752
7370
|
:param str symbol: unified symbol of the market to fetch greeks for
|
6753
7371
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
6754
7372
|
:returns dict: a `greeks structure <https://docs.ccxt.com/#/?id=greeks-structure>`
|
@@ -6757,7 +7375,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6757
7375
|
market = self.market(symbol)
|
6758
7376
|
marketId = market['id']
|
6759
7377
|
optionParts = marketId.split('-')
|
6760
|
-
request = {
|
7378
|
+
request: dict = {
|
6761
7379
|
'uly': market['info']['uly'],
|
6762
7380
|
'instFamily': market['info']['instFamily'],
|
6763
7381
|
'expTime': self.safe_string(optionParts, 2),
|
@@ -6792,7 +7410,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6792
7410
|
# "msg": ""
|
6793
7411
|
# }
|
6794
7412
|
#
|
6795
|
-
data = self.
|
7413
|
+
data = self.safe_list(response, 'data', [])
|
6796
7414
|
for i in range(0, len(data)):
|
6797
7415
|
entry = data[i]
|
6798
7416
|
entryMarketId = self.safe_string(entry, 'instId')
|
@@ -6800,7 +7418,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6800
7418
|
return self.parse_greeks(entry, market)
|
6801
7419
|
return None
|
6802
7420
|
|
6803
|
-
def parse_greeks(self, greeks, market: Market = None):
|
7421
|
+
def parse_greeks(self, greeks: dict, market: Market = None) -> Greeks:
|
6804
7422
|
#
|
6805
7423
|
# {
|
6806
7424
|
# "askVol": "0",
|
@@ -6852,15 +7470,17 @@ class okx(Exchange, ImplicitAPI):
|
|
6852
7470
|
async def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
|
6853
7471
|
"""
|
6854
7472
|
closes open positions for a market
|
6855
|
-
|
7473
|
+
|
7474
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-close-positions
|
7475
|
+
|
6856
7476
|
:param str symbol: Unified CCXT market symbol
|
6857
7477
|
:param str [side]: 'buy' or 'sell', leave in net mode
|
6858
7478
|
:param dict [params]: extra parameters specific to the okx api endpoint
|
6859
7479
|
:param str [params.clientOrderId]: a unique identifier for the order
|
6860
7480
|
:param str [params.marginMode]: 'cross' or 'isolated', default is 'cross
|
6861
7481
|
:param str [params.code]: *required in the case of closing cross MARGIN position for Single-currency margin* margin currency
|
6862
|
-
|
6863
|
-
|
7482
|
+
|
7483
|
+
EXCHANGE SPECIFIC PARAMETERS
|
6864
7484
|
:param boolean [params.autoCxl]: whether any pending orders for closing out needs to be automatically canceled when close position via a market order. False or True, the default is False
|
6865
7485
|
:param str [params.tag]: order tag a combination of case-sensitive alphanumerics, all numbers, or all letters of up to 16 characters
|
6866
7486
|
:returns dict[]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
|
@@ -6871,7 +7491,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6871
7491
|
code = self.safe_string(params, 'code')
|
6872
7492
|
marginMode = None
|
6873
7493
|
marginMode, params = self.handle_margin_mode_and_params('closePosition', params, 'cross')
|
6874
|
-
request = {
|
7494
|
+
request: dict = {
|
6875
7495
|
'instId': market['id'],
|
6876
7496
|
'mgnMode': marginMode,
|
6877
7497
|
}
|
@@ -6905,11 +7525,478 @@ class okx(Exchange, ImplicitAPI):
|
|
6905
7525
|
# "outTime": "1701877077102579"
|
6906
7526
|
# }
|
6907
7527
|
#
|
6908
|
-
data = self.
|
6909
|
-
order = self.
|
7528
|
+
data = self.safe_list(response, 'data', [])
|
7529
|
+
order = self.safe_dict(data, 0)
|
6910
7530
|
return self.parse_order(order, market)
|
6911
7531
|
|
6912
|
-
def
|
7532
|
+
async def fetch_option(self, symbol: str, params={}) -> Option:
|
7533
|
+
"""
|
7534
|
+
fetches option data that is commonly found in an option chain
|
7535
|
+
|
7536
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-ticker
|
7537
|
+
|
7538
|
+
:param str symbol: unified market symbol
|
7539
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7540
|
+
:returns dict: an `option chain structure <https://docs.ccxt.com/#/?id=option-chain-structure>`
|
7541
|
+
"""
|
7542
|
+
await self.load_markets()
|
7543
|
+
market = self.market(symbol)
|
7544
|
+
request: dict = {
|
7545
|
+
'instId': market['id'],
|
7546
|
+
}
|
7547
|
+
response = await self.publicGetMarketTicker(self.extend(request, params))
|
7548
|
+
#
|
7549
|
+
# {
|
7550
|
+
# "code": "0",
|
7551
|
+
# "msg": "",
|
7552
|
+
# "data": [
|
7553
|
+
# {
|
7554
|
+
# "instType": "OPTION",
|
7555
|
+
# "instId": "BTC-USD-241227-60000-P",
|
7556
|
+
# "last": "",
|
7557
|
+
# "lastSz": "0",
|
7558
|
+
# "askPx": "",
|
7559
|
+
# "askSz": "0",
|
7560
|
+
# "bidPx": "",
|
7561
|
+
# "bidSz": "0",
|
7562
|
+
# "open24h": "",
|
7563
|
+
# "high24h": "",
|
7564
|
+
# "low24h": "",
|
7565
|
+
# "volCcy24h": "0",
|
7566
|
+
# "vol24h": "0",
|
7567
|
+
# "ts": "1711176035035",
|
7568
|
+
# "sodUtc0": "",
|
7569
|
+
# "sodUtc8": ""
|
7570
|
+
# }
|
7571
|
+
# ]
|
7572
|
+
# }
|
7573
|
+
#
|
7574
|
+
result = self.safe_list(response, 'data', [])
|
7575
|
+
chain = self.safe_dict(result, 0, {})
|
7576
|
+
return self.parse_option(chain, None, market)
|
7577
|
+
|
7578
|
+
async def fetch_option_chain(self, code: str, params={}) -> OptionChain:
|
7579
|
+
"""
|
7580
|
+
fetches data for an underlying asset that is commonly found in an option chain
|
7581
|
+
|
7582
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-tickers
|
7583
|
+
|
7584
|
+
:param str code: base currency to fetch an option chain for
|
7585
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7586
|
+
:param str [params.uly]: the underlying asset, can be obtained from fetchUnderlyingAssets()
|
7587
|
+
:returns dict: a list of `option chain structures <https://docs.ccxt.com/#/?id=option-chain-structure>`
|
7588
|
+
"""
|
7589
|
+
await self.load_markets()
|
7590
|
+
currency = self.currency(code)
|
7591
|
+
request: dict = {
|
7592
|
+
'uly': currency['code'] + '-USD',
|
7593
|
+
'instType': 'OPTION',
|
7594
|
+
}
|
7595
|
+
response = await self.publicGetMarketTickers(self.extend(request, params))
|
7596
|
+
#
|
7597
|
+
# {
|
7598
|
+
# "code": "0",
|
7599
|
+
# "msg": "",
|
7600
|
+
# "data": [
|
7601
|
+
# {
|
7602
|
+
# "instType": "OPTION",
|
7603
|
+
# "instId": "BTC-USD-240323-52000-C",
|
7604
|
+
# "last": "",
|
7605
|
+
# "lastSz": "0",
|
7606
|
+
# "askPx": "",
|
7607
|
+
# "askSz": "0",
|
7608
|
+
# "bidPx": "",
|
7609
|
+
# "bidSz": "0",
|
7610
|
+
# "open24h": "",
|
7611
|
+
# "high24h": "",
|
7612
|
+
# "low24h": "",
|
7613
|
+
# "volCcy24h": "0",
|
7614
|
+
# "vol24h": "0",
|
7615
|
+
# "ts": "1711176207008",
|
7616
|
+
# "sodUtc0": "",
|
7617
|
+
# "sodUtc8": ""
|
7618
|
+
# },
|
7619
|
+
# ]
|
7620
|
+
# }
|
7621
|
+
#
|
7622
|
+
result = self.safe_list(response, 'data', [])
|
7623
|
+
return self.parse_option_chain(result, None, 'instId')
|
7624
|
+
|
7625
|
+
def parse_option(self, chain: dict, currency: Currency = None, market: Market = None) -> Option:
|
7626
|
+
#
|
7627
|
+
# {
|
7628
|
+
# "instType": "OPTION",
|
7629
|
+
# "instId": "BTC-USD-241227-60000-P",
|
7630
|
+
# "last": "",
|
7631
|
+
# "lastSz": "0",
|
7632
|
+
# "askPx": "",
|
7633
|
+
# "askSz": "0",
|
7634
|
+
# "bidPx": "",
|
7635
|
+
# "bidSz": "0",
|
7636
|
+
# "open24h": "",
|
7637
|
+
# "high24h": "",
|
7638
|
+
# "low24h": "",
|
7639
|
+
# "volCcy24h": "0",
|
7640
|
+
# "vol24h": "0",
|
7641
|
+
# "ts": "1711176035035",
|
7642
|
+
# "sodUtc0": "",
|
7643
|
+
# "sodUtc8": ""
|
7644
|
+
# }
|
7645
|
+
#
|
7646
|
+
marketId = self.safe_string(chain, 'instId')
|
7647
|
+
market = self.safe_market(marketId, market)
|
7648
|
+
timestamp = self.safe_integer(chain, 'ts')
|
7649
|
+
return {
|
7650
|
+
'info': chain,
|
7651
|
+
'currency': None,
|
7652
|
+
'symbol': market['symbol'],
|
7653
|
+
'timestamp': timestamp,
|
7654
|
+
'datetime': self.iso8601(timestamp),
|
7655
|
+
'impliedVolatility': None,
|
7656
|
+
'openInterest': None,
|
7657
|
+
'bidPrice': self.safe_number(chain, 'bidPx'),
|
7658
|
+
'askPrice': self.safe_number(chain, 'askPx'),
|
7659
|
+
'midPrice': None,
|
7660
|
+
'markPrice': None,
|
7661
|
+
'lastPrice': self.safe_number(chain, 'last'),
|
7662
|
+
'underlyingPrice': None,
|
7663
|
+
'change': None,
|
7664
|
+
'percentage': None,
|
7665
|
+
'baseVolume': self.safe_number(chain, 'volCcy24h'),
|
7666
|
+
'quoteVolume': None,
|
7667
|
+
}
|
7668
|
+
|
7669
|
+
async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
7670
|
+
"""
|
7671
|
+
fetch a quote for converting from one currency to another
|
7672
|
+
|
7673
|
+
https://www.okx.com/docs-v5/en/#funding-account-rest-api-estimate-quote
|
7674
|
+
|
7675
|
+
:param str fromCode: the currency that you want to sell and convert from
|
7676
|
+
:param str toCode: the currency that you want to buy and convert into
|
7677
|
+
:param float [amount]: how much you want to trade in units of the from currency
|
7678
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7679
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
7680
|
+
"""
|
7681
|
+
await self.load_markets()
|
7682
|
+
request: dict = {
|
7683
|
+
'baseCcy': fromCode.upper(),
|
7684
|
+
'quoteCcy': toCode.upper(),
|
7685
|
+
'rfqSzCcy': fromCode.upper(),
|
7686
|
+
'rfqSz': self.number_to_string(amount),
|
7687
|
+
'side': 'sell',
|
7688
|
+
}
|
7689
|
+
response = await self.privatePostAssetConvertEstimateQuote(self.extend(request, params))
|
7690
|
+
#
|
7691
|
+
# {
|
7692
|
+
# "code": "0",
|
7693
|
+
# "data": [
|
7694
|
+
# {
|
7695
|
+
# "baseCcy": "ETH",
|
7696
|
+
# "baseSz": "0.01023052",
|
7697
|
+
# "clQReqId": "",
|
7698
|
+
# "cnvtPx": "2932.40104429",
|
7699
|
+
# "origRfqSz": "30",
|
7700
|
+
# "quoteCcy": "USDT",
|
7701
|
+
# "quoteId": "quoterETH-USDT16461885104612381",
|
7702
|
+
# "quoteSz": "30",
|
7703
|
+
# "quoteTime": "1646188510461",
|
7704
|
+
# "rfqSz": "30",
|
7705
|
+
# "rfqSzCcy": "USDT",
|
7706
|
+
# "side": "buy",
|
7707
|
+
# "ttlMs": "10000"
|
7708
|
+
# }
|
7709
|
+
# ],
|
7710
|
+
# "msg": ""
|
7711
|
+
# }
|
7712
|
+
#
|
7713
|
+
data = self.safe_list(response, 'data', [])
|
7714
|
+
result = self.safe_dict(data, 0, {})
|
7715
|
+
fromCurrencyId = self.safe_string(result, 'baseCcy', fromCode)
|
7716
|
+
fromCurrency = self.currency(fromCurrencyId)
|
7717
|
+
toCurrencyId = self.safe_string(result, 'quoteCcy', toCode)
|
7718
|
+
toCurrency = self.currency(toCurrencyId)
|
7719
|
+
return self.parse_conversion(result, fromCurrency, toCurrency)
|
7720
|
+
|
7721
|
+
async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
7722
|
+
"""
|
7723
|
+
convert from one currency to another
|
7724
|
+
|
7725
|
+
https://www.okx.com/docs-v5/en/#funding-account-rest-api-convert-trade
|
7726
|
+
|
7727
|
+
:param str id: the id of the trade that you want to make
|
7728
|
+
:param str fromCode: the currency that you want to sell and convert from
|
7729
|
+
:param str toCode: the currency that you want to buy and convert into
|
7730
|
+
:param float [amount]: how much you want to trade in units of the from currency
|
7731
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7732
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
7733
|
+
"""
|
7734
|
+
await self.load_markets()
|
7735
|
+
request: dict = {
|
7736
|
+
'quoteId': id,
|
7737
|
+
'baseCcy': fromCode,
|
7738
|
+
'quoteCcy': toCode,
|
7739
|
+
'szCcy': fromCode,
|
7740
|
+
'sz': self.number_to_string(amount),
|
7741
|
+
'side': 'sell',
|
7742
|
+
}
|
7743
|
+
response = await self.privatePostAssetConvertTrade(self.extend(request, params))
|
7744
|
+
#
|
7745
|
+
# {
|
7746
|
+
# "code": "0",
|
7747
|
+
# "data": [
|
7748
|
+
# {
|
7749
|
+
# "baseCcy": "ETH",
|
7750
|
+
# "clTReqId": "",
|
7751
|
+
# "fillBaseSz": "0.01023052",
|
7752
|
+
# "fillPx": "2932.40104429",
|
7753
|
+
# "fillQuoteSz": "30",
|
7754
|
+
# "instId": "ETH-USDT",
|
7755
|
+
# "quoteCcy": "USDT",
|
7756
|
+
# "quoteId": "quoterETH-USDT16461885104612381",
|
7757
|
+
# "side": "buy",
|
7758
|
+
# "state": "fullyFilled",
|
7759
|
+
# "tradeId": "trader16461885203381437",
|
7760
|
+
# "ts": "1646188520338"
|
7761
|
+
# }
|
7762
|
+
# ],
|
7763
|
+
# "msg": ""
|
7764
|
+
# }
|
7765
|
+
#
|
7766
|
+
data = self.safe_list(response, 'data', [])
|
7767
|
+
result = self.safe_dict(data, 0, {})
|
7768
|
+
fromCurrencyId = self.safe_string(result, 'baseCcy', fromCode)
|
7769
|
+
fromCurrency = self.currency(fromCurrencyId)
|
7770
|
+
toCurrencyId = self.safe_string(result, 'quoteCcy', toCode)
|
7771
|
+
toCurrency = self.currency(toCurrencyId)
|
7772
|
+
return self.parse_conversion(result, fromCurrency, toCurrency)
|
7773
|
+
|
7774
|
+
async def fetch_convert_trade(self, id: str, code: Str = None, params={}) -> Conversion:
|
7775
|
+
"""
|
7776
|
+
fetch the data for a conversion trade
|
7777
|
+
|
7778
|
+
https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-history
|
7779
|
+
|
7780
|
+
:param str id: the id of the trade that you want to fetch
|
7781
|
+
:param str [code]: the unified currency code of the conversion trade
|
7782
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7783
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
7784
|
+
"""
|
7785
|
+
await self.load_markets()
|
7786
|
+
request: dict = {
|
7787
|
+
'clTReqId': id,
|
7788
|
+
}
|
7789
|
+
response = await self.privateGetAssetConvertHistory(self.extend(request, params))
|
7790
|
+
#
|
7791
|
+
# {
|
7792
|
+
# "code": "0",
|
7793
|
+
# "data": [
|
7794
|
+
# {
|
7795
|
+
# "clTReqId": "",
|
7796
|
+
# "instId": "ETH-USDT",
|
7797
|
+
# "side": "buy",
|
7798
|
+
# "fillPx": "2932.401044",
|
7799
|
+
# "baseCcy": "ETH",
|
7800
|
+
# "quoteCcy": "USDT",
|
7801
|
+
# "fillBaseSz": "0.01023052",
|
7802
|
+
# "state": "fullyFilled",
|
7803
|
+
# "tradeId": "trader16461885203381437",
|
7804
|
+
# "fillQuoteSz": "30",
|
7805
|
+
# "ts": "1646188520000"
|
7806
|
+
# }
|
7807
|
+
# ],
|
7808
|
+
# "msg": ""
|
7809
|
+
# }
|
7810
|
+
#
|
7811
|
+
data = self.safe_list(response, 'data', [])
|
7812
|
+
result = self.safe_dict(data, 0, {})
|
7813
|
+
fromCurrencyId = self.safe_string(result, 'baseCcy')
|
7814
|
+
toCurrencyId = self.safe_string(result, 'quoteCcy')
|
7815
|
+
fromCurrency = None
|
7816
|
+
toCurrency = None
|
7817
|
+
if fromCurrencyId is not None:
|
7818
|
+
fromCurrency = self.currency(fromCurrencyId)
|
7819
|
+
if toCurrencyId is not None:
|
7820
|
+
toCurrency = self.currency(toCurrencyId)
|
7821
|
+
return self.parse_conversion(result, fromCurrency, toCurrency)
|
7822
|
+
|
7823
|
+
async def fetch_convert_trade_history(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Conversion]:
|
7824
|
+
"""
|
7825
|
+
fetch the users history of conversion trades
|
7826
|
+
|
7827
|
+
https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-history
|
7828
|
+
|
7829
|
+
:param str [code]: the unified currency code
|
7830
|
+
:param int [since]: the earliest time in ms to fetch conversions for
|
7831
|
+
:param int [limit]: the maximum number of conversion structures to retrieve
|
7832
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7833
|
+
:param int [params.until]: timestamp in ms of the latest conversion to fetch
|
7834
|
+
:returns dict[]: a list of `conversion structures <https://docs.ccxt.com/#/?id=conversion-structure>`
|
7835
|
+
"""
|
7836
|
+
await self.load_markets()
|
7837
|
+
request: dict = {}
|
7838
|
+
request, params = self.handle_until_option('after', request, params)
|
7839
|
+
if since is not None:
|
7840
|
+
request['before'] = since
|
7841
|
+
if limit is not None:
|
7842
|
+
request['limit'] = limit
|
7843
|
+
response = await self.privateGetAssetConvertHistory(self.extend(request, params))
|
7844
|
+
#
|
7845
|
+
# {
|
7846
|
+
# "code": "0",
|
7847
|
+
# "data": [
|
7848
|
+
# {
|
7849
|
+
# "clTReqId": "",
|
7850
|
+
# "instId": "ETH-USDT",
|
7851
|
+
# "side": "buy",
|
7852
|
+
# "fillPx": "2932.401044",
|
7853
|
+
# "baseCcy": "ETH",
|
7854
|
+
# "quoteCcy": "USDT",
|
7855
|
+
# "fillBaseSz": "0.01023052",
|
7856
|
+
# "state": "fullyFilled",
|
7857
|
+
# "tradeId": "trader16461885203381437",
|
7858
|
+
# "fillQuoteSz": "30",
|
7859
|
+
# "ts": "1646188520000"
|
7860
|
+
# }
|
7861
|
+
# ],
|
7862
|
+
# "msg": ""
|
7863
|
+
# }
|
7864
|
+
#
|
7865
|
+
rows = self.safe_list(response, 'data', [])
|
7866
|
+
return self.parse_conversions(rows, code, 'baseCcy', 'quoteCcy', since, limit)
|
7867
|
+
|
7868
|
+
def parse_conversion(self, conversion: dict, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
|
7869
|
+
#
|
7870
|
+
# fetchConvertQuote
|
7871
|
+
#
|
7872
|
+
# {
|
7873
|
+
# "baseCcy": "ETH",
|
7874
|
+
# "baseSz": "0.01023052",
|
7875
|
+
# "clQReqId": "",
|
7876
|
+
# "cnvtPx": "2932.40104429",
|
7877
|
+
# "origRfqSz": "30",
|
7878
|
+
# "quoteCcy": "USDT",
|
7879
|
+
# "quoteId": "quoterETH-USDT16461885104612381",
|
7880
|
+
# "quoteSz": "30",
|
7881
|
+
# "quoteTime": "1646188510461",
|
7882
|
+
# "rfqSz": "30",
|
7883
|
+
# "rfqSzCcy": "USDT",
|
7884
|
+
# "side": "buy",
|
7885
|
+
# "ttlMs": "10000"
|
7886
|
+
# }
|
7887
|
+
#
|
7888
|
+
# createConvertTrade
|
7889
|
+
#
|
7890
|
+
# {
|
7891
|
+
# "baseCcy": "ETH",
|
7892
|
+
# "clTReqId": "",
|
7893
|
+
# "fillBaseSz": "0.01023052",
|
7894
|
+
# "fillPx": "2932.40104429",
|
7895
|
+
# "fillQuoteSz": "30",
|
7896
|
+
# "instId": "ETH-USDT",
|
7897
|
+
# "quoteCcy": "USDT",
|
7898
|
+
# "quoteId": "quoterETH-USDT16461885104612381",
|
7899
|
+
# "side": "buy",
|
7900
|
+
# "state": "fullyFilled",
|
7901
|
+
# "tradeId": "trader16461885203381437",
|
7902
|
+
# "ts": "1646188520338"
|
7903
|
+
# }
|
7904
|
+
#
|
7905
|
+
# fetchConvertTrade, fetchConvertTradeHistory
|
7906
|
+
#
|
7907
|
+
# {
|
7908
|
+
# "clTReqId": "",
|
7909
|
+
# "instId": "ETH-USDT",
|
7910
|
+
# "side": "buy",
|
7911
|
+
# "fillPx": "2932.401044",
|
7912
|
+
# "baseCcy": "ETH",
|
7913
|
+
# "quoteCcy": "USDT",
|
7914
|
+
# "fillBaseSz": "0.01023052",
|
7915
|
+
# "state": "fullyFilled",
|
7916
|
+
# "tradeId": "trader16461885203381437",
|
7917
|
+
# "fillQuoteSz": "30",
|
7918
|
+
# "ts": "1646188520000"
|
7919
|
+
# }
|
7920
|
+
#
|
7921
|
+
timestamp = self.safe_integer_2(conversion, 'quoteTime', 'ts')
|
7922
|
+
fromCoin = self.safe_string(conversion, 'baseCcy')
|
7923
|
+
fromCode = self.safe_currency_code(fromCoin, fromCurrency)
|
7924
|
+
to = self.safe_string(conversion, 'quoteCcy')
|
7925
|
+
toCode = self.safe_currency_code(to, toCurrency)
|
7926
|
+
return {
|
7927
|
+
'info': conversion,
|
7928
|
+
'timestamp': timestamp,
|
7929
|
+
'datetime': self.iso8601(timestamp),
|
7930
|
+
'id': self.safe_string_n(conversion, ['clQReqId', 'tradeId', 'quoteId']),
|
7931
|
+
'fromCurrency': fromCode,
|
7932
|
+
'fromAmount': self.safe_number_2(conversion, 'baseSz', 'fillBaseSz'),
|
7933
|
+
'toCurrency': toCode,
|
7934
|
+
'toAmount': self.safe_number_2(conversion, 'quoteSz', 'fillQuoteSz'),
|
7935
|
+
'price': self.safe_number_2(conversion, 'cnvtPx', 'fillPx'),
|
7936
|
+
'fee': None,
|
7937
|
+
}
|
7938
|
+
|
7939
|
+
async def fetch_convert_currencies(self, params={}) -> Currencies:
|
7940
|
+
"""
|
7941
|
+
fetches all available currencies that can be converted
|
7942
|
+
|
7943
|
+
https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-currencies
|
7944
|
+
|
7945
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7946
|
+
:returns dict: an associative dictionary of currencies
|
7947
|
+
"""
|
7948
|
+
await self.load_markets()
|
7949
|
+
response = await self.privateGetAssetConvertCurrencies(params)
|
7950
|
+
#
|
7951
|
+
# {
|
7952
|
+
# "code": "0",
|
7953
|
+
# "data": [
|
7954
|
+
# {
|
7955
|
+
# "ccy": "BTC",
|
7956
|
+
# "max": "",
|
7957
|
+
# "min": ""
|
7958
|
+
# },
|
7959
|
+
# ],
|
7960
|
+
# "msg": ""
|
7961
|
+
# }
|
7962
|
+
#
|
7963
|
+
result: dict = {}
|
7964
|
+
data = self.safe_list(response, 'data', [])
|
7965
|
+
for i in range(0, len(data)):
|
7966
|
+
entry = data[i]
|
7967
|
+
id = self.safe_string(entry, 'ccy')
|
7968
|
+
code = self.safe_currency_code(id)
|
7969
|
+
result[code] = {
|
7970
|
+
'info': entry,
|
7971
|
+
'id': id,
|
7972
|
+
'code': code,
|
7973
|
+
'networks': None,
|
7974
|
+
'type': None,
|
7975
|
+
'name': None,
|
7976
|
+
'active': None,
|
7977
|
+
'deposit': None,
|
7978
|
+
'withdraw': None,
|
7979
|
+
'fee': None,
|
7980
|
+
'precision': None,
|
7981
|
+
'limits': {
|
7982
|
+
'amount': {
|
7983
|
+
'min': self.safe_number(entry, 'min'),
|
7984
|
+
'max': self.safe_number(entry, 'max'),
|
7985
|
+
},
|
7986
|
+
'withdraw': {
|
7987
|
+
'min': None,
|
7988
|
+
'max': None,
|
7989
|
+
},
|
7990
|
+
'deposit': {
|
7991
|
+
'min': None,
|
7992
|
+
'max': None,
|
7993
|
+
},
|
7994
|
+
},
|
7995
|
+
'created': None,
|
7996
|
+
}
|
7997
|
+
return result
|
7998
|
+
|
7999
|
+
def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
6913
8000
|
if not response:
|
6914
8001
|
return None # fallback to default error handler
|
6915
8002
|
#
|
@@ -6935,7 +8022,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6935
8022
|
code = self.safe_string(response, 'code')
|
6936
8023
|
if (code != '0') and (code != '2'): # 2 means that bulk operation partially succeeded
|
6937
8024
|
feedback = self.id + ' ' + body
|
6938
|
-
data = self.
|
8025
|
+
data = self.safe_list(response, 'data', [])
|
6939
8026
|
for i in range(0, len(data)):
|
6940
8027
|
error = data[i]
|
6941
8028
|
errorCode = self.safe_string(error, 'sCode')
|
@@ -6945,3 +8032,238 @@ class okx(Exchange, ImplicitAPI):
|
|
6945
8032
|
self.throw_exactly_matched_exception(self.exceptions['exact'], code, feedback)
|
6946
8033
|
raise ExchangeError(feedback) # unknown message
|
6947
8034
|
return None
|
8035
|
+
|
8036
|
+
async def fetch_margin_adjustment_history(self, symbol: Str = None, type: Str = None, since: Num = None, limit: Num = None, params={}) -> List[MarginModification]:
|
8037
|
+
"""
|
8038
|
+
fetches the history of margin added or reduced from contract isolated positions
|
8039
|
+
|
8040
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-7-days
|
8041
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months
|
8042
|
+
|
8043
|
+
:param str [symbol]: not used by okx fetchMarginAdjustmentHistory
|
8044
|
+
:param str [type]: "add" or "reduce"
|
8045
|
+
:param int [since]: the earliest time in ms to fetch margin adjustment history for
|
8046
|
+
:param int [limit]: the maximum number of entries to retrieve
|
8047
|
+
:param dict params: extra parameters specific to the exchange api endpoint
|
8048
|
+
:param boolean [params.auto]: True if fetching auto margin increases
|
8049
|
+
:returns dict[]: a list of `margin structures <https://docs.ccxt.com/#/?id=margin-loan-structure>`
|
8050
|
+
"""
|
8051
|
+
await self.load_markets()
|
8052
|
+
auto = self.safe_bool(params, 'auto')
|
8053
|
+
if type is None:
|
8054
|
+
raise ArgumentsRequired(self.id + ' fetchMarginAdjustmentHistory() requires a type argument')
|
8055
|
+
isAdd = type == 'add'
|
8056
|
+
subType = '160' if isAdd else '161'
|
8057
|
+
if auto:
|
8058
|
+
if isAdd:
|
8059
|
+
subType = '162'
|
8060
|
+
else:
|
8061
|
+
raise BadRequest(self.id + ' cannot fetch margin adjustments for type ' + type)
|
8062
|
+
request: dict = {
|
8063
|
+
'subType': subType,
|
8064
|
+
'mgnMode': 'isolated',
|
8065
|
+
}
|
8066
|
+
until = self.safe_integer(params, 'until')
|
8067
|
+
params = self.omit(params, 'until')
|
8068
|
+
if since is not None:
|
8069
|
+
request['startTime'] = since
|
8070
|
+
if limit is not None:
|
8071
|
+
request['limit'] = limit
|
8072
|
+
if until is not None:
|
8073
|
+
request['endTime'] = until
|
8074
|
+
response = None
|
8075
|
+
now = self.milliseconds()
|
8076
|
+
oneWeekAgo = now - 604800000
|
8077
|
+
threeMonthsAgo = now - 7776000000
|
8078
|
+
if (since is None) or (since > oneWeekAgo):
|
8079
|
+
response = await self.privateGetAccountBills(self.extend(request, params))
|
8080
|
+
elif since > threeMonthsAgo:
|
8081
|
+
response = await self.privateGetAccountBillsArchive(self.extend(request, params))
|
8082
|
+
else:
|
8083
|
+
raise BadRequest(self.id + ' fetchMarginAdjustmentHistory() cannot fetch margin adjustments older than 3 months')
|
8084
|
+
#
|
8085
|
+
# {
|
8086
|
+
# code: '0',
|
8087
|
+
# data: [
|
8088
|
+
# {
|
8089
|
+
# bal: '67621.4325135010619812',
|
8090
|
+
# balChg: '-10.0000000000000000',
|
8091
|
+
# billId: '691293628710342659',
|
8092
|
+
# ccy: 'USDT',
|
8093
|
+
# clOrdId: '',
|
8094
|
+
# execType: '',
|
8095
|
+
# fee: '0',
|
8096
|
+
# fillFwdPx: '',
|
8097
|
+
# fillIdxPx: '',
|
8098
|
+
# fillMarkPx: '',
|
8099
|
+
# fillMarkVol: '',
|
8100
|
+
# fillPxUsd: '',
|
8101
|
+
# fillPxVol: '',
|
8102
|
+
# fillTime: '1711089244850',
|
8103
|
+
# from: '',
|
8104
|
+
# instId: 'XRP-USDT-SWAP',
|
8105
|
+
# instType: 'SWAP',
|
8106
|
+
# interest: '0',
|
8107
|
+
# mgnMode: 'isolated',
|
8108
|
+
# notes: '',
|
8109
|
+
# ordId: '',
|
8110
|
+
# pnl: '0',
|
8111
|
+
# posBal: '73.12',
|
8112
|
+
# posBalChg: '10.00',
|
8113
|
+
# px: '',
|
8114
|
+
# subType: '160',
|
8115
|
+
# sz: '10',
|
8116
|
+
# tag: '',
|
8117
|
+
# to: '',
|
8118
|
+
# tradeId: '0',
|
8119
|
+
# ts: '1711089244699',
|
8120
|
+
# type: '6'
|
8121
|
+
# }
|
8122
|
+
# ],
|
8123
|
+
# msg: ''
|
8124
|
+
# }
|
8125
|
+
#
|
8126
|
+
data = self.safe_list(response, 'data')
|
8127
|
+
modifications = self.parse_margin_modifications(data)
|
8128
|
+
return self.filter_by_symbol_since_limit(modifications, symbol, since, limit)
|
8129
|
+
|
8130
|
+
async def fetch_positions_history(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
|
8131
|
+
"""
|
8132
|
+
fetches historical positions
|
8133
|
+
|
8134
|
+
https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-positions-history
|
8135
|
+
|
8136
|
+
:param str [symbols]: unified market symbols
|
8137
|
+
:param int [since]: timestamp in ms of the earliest position to fetch
|
8138
|
+
:param int [limit]: the maximum amount of records to fetch, default=100, max=100
|
8139
|
+
:param dict params: extra parameters specific to the exchange api endpoint
|
8140
|
+
:param str [params.marginMode]: "cross" or "isolated"
|
8141
|
+
|
8142
|
+
EXCHANGE SPECIFIC PARAMETERS
|
8143
|
+
:param str [params.instType]: margin, swap, futures or option
|
8144
|
+
:param str [params.type]: the type of latest close position 1: close position partially, 2:close all, 3:liquidation, 4:partial liquidation; 5:adl, is it is the latest type if there are several types for the same position
|
8145
|
+
:param str [params.posId]: position id, there is attribute expiration, the posid will be expired if it is more than 30 days after the last full close position, then position will use new posid
|
8146
|
+
:param str [params.before]: timestamp in ms of the earliest position to fetch based on the last update time of the position
|
8147
|
+
:param str [params.after]: timestamp in ms of the latest position to fetch based on the last update time of the position
|
8148
|
+
:returns dict[]: a list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
|
8149
|
+
"""
|
8150
|
+
await self.load_markets()
|
8151
|
+
marginMode = self.safe_string(params, 'marginMode')
|
8152
|
+
instType = self.safe_string_upper(params, 'instType')
|
8153
|
+
params = self.omit(params, ['until', 'marginMode', 'instType'])
|
8154
|
+
if limit is None:
|
8155
|
+
limit = 100
|
8156
|
+
request: dict = {
|
8157
|
+
'limit': limit,
|
8158
|
+
}
|
8159
|
+
if symbols is not None:
|
8160
|
+
symbolsLength = len(symbols)
|
8161
|
+
if symbolsLength == 1:
|
8162
|
+
market = self.market(symbols[0])
|
8163
|
+
request['instId'] = market['id']
|
8164
|
+
if marginMode is not None:
|
8165
|
+
request['mgnMode'] = marginMode
|
8166
|
+
if instType is not None:
|
8167
|
+
request['instType'] = instType
|
8168
|
+
response = await self.privateGetAccountPositionsHistory(self.extend(request, params))
|
8169
|
+
#
|
8170
|
+
# {
|
8171
|
+
# code: '0',
|
8172
|
+
# data: [
|
8173
|
+
# {
|
8174
|
+
# cTime: '1708735940395',
|
8175
|
+
# ccy: 'USDT',
|
8176
|
+
# closeAvgPx: '0.6330444444444444',
|
8177
|
+
# closeTotalPos: '27',
|
8178
|
+
# direction: 'long',
|
8179
|
+
# fee: '-1.69566',
|
8180
|
+
# fundingFee: '-11.870404179341788',
|
8181
|
+
# instId: 'XRP-USDT-SWAP',
|
8182
|
+
# instType: 'SWAP',
|
8183
|
+
# lever: '3.0',
|
8184
|
+
# liqPenalty: '0',
|
8185
|
+
# mgnMode: 'cross',
|
8186
|
+
# openAvgPx: '0.623',
|
8187
|
+
# openMaxPos: '15',
|
8188
|
+
# pnl: '27.11999999999988',
|
8189
|
+
# pnlRatio: '0.0241732402722634',
|
8190
|
+
# posId: '681423155054862336',
|
8191
|
+
# realizedPnl: '13.553935820658092',
|
8192
|
+
# triggerPx: '',
|
8193
|
+
# type: '2',
|
8194
|
+
# uTime: '1711088748170',
|
8195
|
+
# uly: 'XRP-USDT'
|
8196
|
+
# },
|
8197
|
+
# ...
|
8198
|
+
# ],
|
8199
|
+
# msg: ''
|
8200
|
+
# }
|
8201
|
+
#
|
8202
|
+
data = self.safe_list(response, 'data')
|
8203
|
+
positions = self.parse_positions(data, symbols, params)
|
8204
|
+
return self.filter_by_since_limit(positions, since, limit)
|
8205
|
+
|
8206
|
+
async def fetch_long_short_ratio_history(self, symbol: Str = None, timeframe: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LongShortRatio]:
|
8207
|
+
"""
|
8208
|
+
fetches the long short ratio history for a unified market symbol
|
8209
|
+
|
8210
|
+
https://www.okx.com/docs-v5/en/#trading-statistics-rest-api-get-contract-long-short-ratio
|
8211
|
+
|
8212
|
+
:param str symbol: unified symbol of the market to fetch the long short ratio for
|
8213
|
+
:param str [timeframe]: the period for the ratio
|
8214
|
+
:param int [since]: the earliest time in ms to fetch ratios for
|
8215
|
+
:param int [limit]: the maximum number of long short ratio structures to retrieve
|
8216
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
8217
|
+
:param int [params.until]: timestamp in ms of the latest ratio to fetch
|
8218
|
+
:returns dict[]: an array of `long short ratio structures <https://docs.ccxt.com/#/?id=long-short-ratio-structure>`
|
8219
|
+
"""
|
8220
|
+
await self.load_markets()
|
8221
|
+
market = self.market(symbol)
|
8222
|
+
request: dict = {
|
8223
|
+
'instId': market['id'],
|
8224
|
+
}
|
8225
|
+
until = self.safe_string_2(params, 'until', 'end')
|
8226
|
+
params = self.omit(params, 'until')
|
8227
|
+
if until is not None:
|
8228
|
+
request['end'] = until
|
8229
|
+
if timeframe is not None:
|
8230
|
+
request['period'] = timeframe
|
8231
|
+
if since is not None:
|
8232
|
+
request['begin'] = since
|
8233
|
+
if limit is not None:
|
8234
|
+
request['limit'] = limit
|
8235
|
+
response = await self.publicGetRubikStatContractsLongShortAccountRatioContract(self.extend(request, params))
|
8236
|
+
#
|
8237
|
+
# {
|
8238
|
+
# "code": "0",
|
8239
|
+
# "data": [
|
8240
|
+
# ["1729323600000", "0.9398602814619824"],
|
8241
|
+
# ["1729323300000", "0.9398602814619824"],
|
8242
|
+
# ["1729323000000", "0.9398602814619824"],
|
8243
|
+
# ],
|
8244
|
+
# "msg": ""
|
8245
|
+
# }
|
8246
|
+
#
|
8247
|
+
data = self.safe_list(response, 'data', [])
|
8248
|
+
result = []
|
8249
|
+
for i in range(0, len(data)):
|
8250
|
+
entry = data[i]
|
8251
|
+
result.append({
|
8252
|
+
'timestamp': self.safe_string(entry, 0),
|
8253
|
+
'longShortRatio': self.safe_string(entry, 1),
|
8254
|
+
})
|
8255
|
+
return self.parse_long_short_ratio_history(result, market)
|
8256
|
+
|
8257
|
+
def parse_long_short_ratio(self, info: dict, market: Market = None) -> LongShortRatio:
|
8258
|
+
timestamp = self.safe_integer(info, 'timestamp')
|
8259
|
+
symbol = None
|
8260
|
+
if market is not None:
|
8261
|
+
symbol = market['symbol']
|
8262
|
+
return {
|
8263
|
+
'info': info,
|
8264
|
+
'symbol': symbol,
|
8265
|
+
'timestamp': timestamp,
|
8266
|
+
'datetime': self.iso8601(timestamp),
|
8267
|
+
'timeframe': None,
|
8268
|
+
'longShortRatio': self.safe_number(info, 'longShortRatio'),
|
8269
|
+
}
|