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