ccxt-ir 4.3.46.0.3__py2.py3-none-any.whl → 4.5.1__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 +39 -35
- ccxt/abantether.py +8 -8
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/apex.py +31 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +106 -48
- ccxt/abstract/binancecoinm.py +106 -48
- ccxt/abstract/binanceus.py +141 -83
- ccxt/abstract/binanceusdm.py +106 -48
- ccxt/abstract/bingx.py +50 -1
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +67 -0
- ccxt/abstract/bitmart.py +19 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitrue.py +68 -68
- ccxt/abstract/bitstamp.py +1 -0
- ccxt/abstract/blofin.py +30 -0
- ccxt/abstract/btcbox.py +2 -0
- ccxt/abstract/bybit.py +28 -13
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbaseexchange.py +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/cryptocom.py +16 -0
- ccxt/abstract/cryptomus.py +20 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/derive.py +117 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/foxbit.py +26 -0
- ccxt/abstract/gate.py +19 -0
- ccxt/abstract/gateio.py +19 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hibachi.py +26 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +1 -0
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +10 -0
- ccxt/abstract/kucoinfutures.py +18 -0
- ccxt/abstract/lbank.py +2 -1
- ccxt/abstract/luno.py +1 -0
- ccxt/abstract/mexc.py +2 -0
- ccxt/abstract/modetrade.py +119 -0
- ccxt/abstract/myokx.py +349 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +25 -0
- ccxt/abstract/okxus.py +349 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/paradex.py +23 -0
- ccxt/abstract/phemex.py +2 -0
- ccxt/abstract/poloniex.py +36 -0
- ccxt/abstract/tradeogre.py +3 -1
- ccxt/abstract/upbit.py +51 -34
- ccxt/abstract/whitebit.py +16 -0
- ccxt/abstract/woo.py +64 -6
- ccxt/abstract/xt.py +10 -5
- ccxt/afratether.py +8 -8
- ccxt/alpaca.py +828 -51
- ccxt/apex.py +1875 -0
- ccxt/arzinja.py +7 -7
- ccxt/arzplus.py +9 -9
- ccxt/ascendex.py +501 -306
- ccxt/async_support/__init__.py +39 -35
- ccxt/async_support/abantether.py +8 -8
- ccxt/async_support/afratether.py +10 -10
- ccxt/async_support/alpaca.py +828 -51
- ccxt/async_support/apex.py +1875 -0
- ccxt/async_support/arzinja.py +10 -10
- ccxt/async_support/arzplus.py +12 -12
- ccxt/async_support/ascendex.py +502 -306
- ccxt/async_support/base/exchange.py +303 -89
- ccxt/async_support/base/ws/cache.py +9 -3
- ccxt/async_support/base/ws/client.py +173 -38
- ccxt/async_support/base/ws/future.py +25 -37
- ccxt/async_support/bequant.py +5 -3
- ccxt/async_support/bigone.py +279 -144
- ccxt/async_support/binance.py +2347 -1158
- ccxt/async_support/binancecoinm.py +9 -3
- ccxt/async_support/binanceus.py +17 -3
- ccxt/async_support/binanceusdm.py +9 -4
- ccxt/async_support/bingx.py +2962 -920
- ccxt/async_support/bit2c.py +147 -27
- ccxt/async_support/bitbank.py +151 -23
- ccxt/async_support/bitbns.py +104 -30
- ccxt/async_support/bitfinex.py +3291 -1113
- ccxt/async_support/bitflyer.py +202 -27
- ccxt/async_support/bitget.py +3683 -1538
- ccxt/async_support/bithumb.py +195 -38
- ccxt/async_support/bitimen.py +12 -12
- ccxt/async_support/bitir.py +38 -38
- ccxt/async_support/bitmart.py +1288 -350
- ccxt/async_support/bitmex.py +260 -75
- ccxt/async_support/bitopro.py +262 -62
- ccxt/async_support/bitpin.py +17 -16
- ccxt/async_support/bitrue.py +459 -290
- ccxt/async_support/bitso.py +199 -54
- ccxt/async_support/bitstamp.py +230 -96
- ccxt/async_support/bitteam.py +167 -25
- ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
- ccxt/async_support/bitvavo.py +213 -49
- ccxt/async_support/blockchaincom.py +160 -46
- ccxt/async_support/blofin.py +502 -120
- ccxt/async_support/btcalpha.py +169 -31
- ccxt/async_support/btcbox.py +292 -23
- ccxt/async_support/btcmarkets.py +211 -58
- ccxt/async_support/btcturk.py +161 -38
- ccxt/async_support/bybit.py +1775 -1030
- ccxt/async_support/cex.py +1440 -1303
- ccxt/async_support/coinbase.py +724 -212
- ccxt/async_support/coinbaseadvanced.py +2 -1
- ccxt/async_support/coinbaseexchange.py +388 -89
- ccxt/async_support/coinbaseinternational.py +412 -57
- ccxt/async_support/coincatch.py +177 -78
- ccxt/async_support/coincheck.py +135 -19
- ccxt/async_support/coinex.py +606 -232
- ccxt/async_support/coinmate.py +189 -63
- ccxt/async_support/coinmetro.py +195 -54
- ccxt/async_support/coinone.py +158 -51
- ccxt/async_support/coinsph.py +336 -61
- ccxt/async_support/coinspot.py +151 -52
- ccxt/async_support/cryptocom.py +661 -111
- ccxt/async_support/cryptomus.py +1137 -0
- ccxt/async_support/defx.py +2071 -0
- ccxt/async_support/delta.py +299 -99
- ccxt/async_support/deribit.py +348 -126
- ccxt/async_support/derive.py +2572 -0
- ccxt/async_support/digifinex.py +430 -214
- ccxt/async_support/ellipx.py +2029 -0
- ccxt/async_support/eterex.py +10 -10
- ccxt/async_support/excoino.py +31 -31
- ccxt/async_support/exir.py +14 -14
- ccxt/async_support/exmo.py +344 -131
- ccxt/async_support/exnovin.py +10 -10
- ccxt/async_support/farhadexchange.py +12 -12
- ccxt/async_support/fmfwio.py +2 -1
- ccxt/async_support/foxbit.py +1935 -0
- ccxt/async_support/gate.py +1351 -529
- ccxt/async_support/gateio.py +2 -1
- ccxt/async_support/gemini.py +144 -39
- ccxt/async_support/hashkey.py +152 -109
- ccxt/async_support/hibachi.py +2080 -0
- ccxt/async_support/hitbtc.py +395 -167
- ccxt/async_support/hitobit.py +12 -12
- ccxt/async_support/hollaex.py +307 -119
- ccxt/async_support/htx.py +851 -383
- ccxt/async_support/huobi.py +2 -1
- ccxt/async_support/hyperliquid.py +1848 -536
- ccxt/async_support/independentreserve.py +288 -15
- ccxt/async_support/indodax.py +190 -33
- ccxt/async_support/jibitex.py +12 -12
- ccxt/async_support/kraken.py +795 -351
- ccxt/async_support/krakenfutures.py +214 -62
- ccxt/async_support/kucoin.py +715 -396
- ccxt/async_support/kucoinfutures.py +652 -89
- ccxt/async_support/latoken.py +217 -113
- ccxt/async_support/lbank.py +425 -97
- ccxt/async_support/luno.py +382 -35
- ccxt/async_support/mercado.py +113 -6
- ccxt/async_support/mexc.py +874 -437
- ccxt/async_support/modetrade.py +2818 -0
- ccxt/async_support/myokx.py +54 -0
- ccxt/async_support/ndax.py +221 -64
- ccxt/async_support/nobitex.py +32 -38
- ccxt/async_support/novadax.py +190 -34
- ccxt/async_support/oceanex.py +217 -28
- ccxt/async_support/okcoin.py +253 -145
- ccxt/async_support/okexchange.py +11 -11
- ccxt/async_support/okx.py +1088 -351
- ccxt/async_support/okxus.py +54 -0
- ccxt/async_support/ompfinex.py +32 -27
- ccxt/async_support/onetrading.py +213 -392
- ccxt/async_support/oxfun.py +245 -166
- ccxt/async_support/p2b.py +151 -29
- ccxt/async_support/paradex.py +562 -49
- ccxt/async_support/paymium.py +82 -19
- ccxt/async_support/phemex.py +713 -172
- ccxt/async_support/poloniex.py +1602 -283
- ccxt/async_support/probit.py +224 -95
- ccxt/async_support/ramzinex.py +34 -30
- ccxt/async_support/sarmayex.py +9 -9
- ccxt/async_support/sarrafex.py +13 -13
- ccxt/async_support/tabdeal.py +15 -14
- ccxt/async_support/tetherland.py +9 -9
- ccxt/async_support/timex.py +210 -51
- ccxt/async_support/tokocrypto.py +167 -47
- ccxt/async_support/tradeogre.py +266 -31
- ccxt/async_support/twox.py +9 -9
- ccxt/async_support/ubitex.py +12 -12
- ccxt/async_support/upbit.py +568 -165
- ccxt/async_support/vertex.py +160 -32
- ccxt/async_support/wallex.py +12 -12
- ccxt/async_support/wavesexchange.py +165 -30
- ccxt/async_support/whitebit.py +975 -127
- ccxt/async_support/woo.py +1918 -1016
- ccxt/async_support/woofipro.py +433 -141
- ccxt/async_support/xt.py +649 -193
- ccxt/async_support/yobit.py +195 -70
- ccxt/async_support/zaif.py +91 -15
- ccxt/async_support/zonda.py +151 -36
- ccxt/base/decimal_to_precision.py +14 -10
- ccxt/base/errors.py +49 -18
- ccxt/base/exchange.py +1556 -450
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +114 -6
- ccxt/bequant.py +5 -3
- ccxt/bigone.py +279 -144
- ccxt/binance.py +2347 -1158
- ccxt/binancecoinm.py +9 -3
- ccxt/binanceus.py +17 -3
- ccxt/binanceusdm.py +9 -4
- ccxt/bingx.py +2962 -920
- ccxt/bit2c.py +147 -27
- ccxt/bitbank.py +151 -23
- ccxt/bitbns.py +104 -30
- ccxt/bitfinex.py +3290 -1113
- ccxt/bitflyer.py +202 -27
- ccxt/bitget.py +3683 -1538
- ccxt/bithumb.py +194 -38
- ccxt/bitimen.py +9 -9
- ccxt/bitir.py +35 -35
- ccxt/bitmart.py +1288 -350
- ccxt/bitmex.py +260 -75
- ccxt/bitopro.py +262 -62
- ccxt/bitpin.py +15 -14
- ccxt/bitrue.py +459 -290
- ccxt/bitso.py +199 -54
- ccxt/bitstamp.py +230 -96
- ccxt/bitteam.py +167 -25
- ccxt/{huobijp.py → bittrade.py} +158 -30
- ccxt/bitvavo.py +213 -49
- ccxt/blockchaincom.py +160 -46
- ccxt/blofin.py +502 -120
- ccxt/btcalpha.py +169 -31
- ccxt/btcbox.py +291 -23
- ccxt/btcmarkets.py +211 -58
- ccxt/btcturk.py +161 -38
- ccxt/bybit.py +1775 -1030
- ccxt/cex.py +1439 -1303
- ccxt/coinbase.py +724 -212
- ccxt/coinbaseadvanced.py +2 -1
- ccxt/coinbaseexchange.py +388 -89
- ccxt/coinbaseinternational.py +412 -57
- ccxt/coincatch.py +177 -78
- ccxt/coincheck.py +135 -19
- ccxt/coinex.py +606 -232
- ccxt/coinmate.py +189 -63
- ccxt/coinmetro.py +194 -54
- ccxt/coinone.py +158 -51
- ccxt/coinsph.py +336 -61
- ccxt/coinspot.py +151 -52
- ccxt/cryptocom.py +661 -111
- ccxt/cryptomus.py +1137 -0
- ccxt/defx.py +2070 -0
- ccxt/delta.py +299 -99
- ccxt/deribit.py +348 -126
- ccxt/derive.py +2571 -0
- ccxt/digifinex.py +430 -214
- ccxt/ellipx.py +2029 -0
- ccxt/eterex.py +7 -7
- ccxt/excoino.py +29 -29
- ccxt/exir.py +11 -11
- ccxt/exmo.py +343 -131
- ccxt/exnovin.py +8 -8
- ccxt/farhadexchange.py +10 -10
- ccxt/fmfwio.py +2 -1
- ccxt/foxbit.py +1935 -0
- ccxt/gate.py +1351 -529
- ccxt/gateio.py +2 -1
- ccxt/gemini.py +144 -39
- ccxt/hashkey.py +152 -109
- ccxt/hibachi.py +2079 -0
- ccxt/hitbtc.py +395 -167
- ccxt/hitobit.py +9 -9
- ccxt/hollaex.py +307 -119
- ccxt/htx.py +851 -383
- ccxt/huobi.py +2 -1
- ccxt/hyperliquid.py +1848 -536
- ccxt/independentreserve.py +287 -15
- ccxt/indodax.py +190 -33
- ccxt/jibitex.py +9 -9
- ccxt/kraken.py +794 -351
- ccxt/krakenfutures.py +214 -62
- ccxt/kucoin.py +715 -396
- ccxt/kucoinfutures.py +652 -89
- ccxt/latoken.py +217 -113
- ccxt/lbank.py +425 -97
- ccxt/luno.py +382 -35
- ccxt/mercado.py +113 -6
- ccxt/mexc.py +873 -437
- ccxt/modetrade.py +2818 -0
- ccxt/myokx.py +54 -0
- ccxt/ndax.py +221 -64
- ccxt/nobitex.py +30 -36
- ccxt/novadax.py +190 -34
- ccxt/oceanex.py +217 -28
- ccxt/okcoin.py +253 -145
- ccxt/okexchange.py +9 -9
- ccxt/okx.py +1088 -351
- ccxt/okxus.py +54 -0
- ccxt/ompfinex.py +29 -24
- ccxt/onetrading.py +213 -392
- ccxt/oxfun.py +245 -166
- ccxt/p2b.py +151 -29
- ccxt/paradex.py +562 -49
- ccxt/paymium.py +82 -19
- ccxt/phemex.py +712 -172
- ccxt/poloniex.py +1601 -283
- ccxt/pro/__init__.py +76 -17
- ccxt/pro/alpaca.py +21 -6
- ccxt/pro/apex.py +984 -0
- ccxt/pro/ascendex.py +58 -10
- ccxt/pro/bequant.py +6 -1
- ccxt/pro/binance.py +728 -156
- ccxt/pro/binancecoinm.py +6 -2
- ccxt/pro/binanceus.py +8 -4
- ccxt/pro/binanceusdm.py +7 -2
- ccxt/pro/bingx.py +333 -142
- ccxt/pro/bitfinex.py +727 -262
- ccxt/pro/bitget.py +570 -79
- ccxt/pro/bithumb.py +20 -6
- ccxt/pro/bitmart.py +216 -87
- ccxt/pro/bitmex.py +47 -9
- ccxt/pro/bitopro.py +26 -14
- ccxt/pro/bitrue.py +22 -22
- ccxt/pro/bitstamp.py +54 -21
- ccxt/pro/{huobijp.py → bittrade.py} +7 -6
- ccxt/pro/bitvavo.py +191 -67
- ccxt/pro/blockchaincom.py +21 -8
- ccxt/pro/blofin.py +9 -1
- ccxt/pro/bybit.py +632 -245
- ccxt/pro/cex.py +59 -24
- ccxt/pro/coinbase.py +102 -73
- ccxt/pro/coinbaseadvanced.py +2 -1
- ccxt/pro/coinbaseexchange.py +8 -8
- ccxt/pro/coinbaseinternational.py +181 -25
- ccxt/pro/coincatch.py +6 -7
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +967 -665
- ccxt/pro/coinone.py +16 -9
- ccxt/pro/cryptocom.py +448 -45
- ccxt/pro/defx.py +831 -0
- ccxt/pro/deribit.py +150 -14
- ccxt/pro/derive.py +704 -0
- ccxt/pro/exmo.py +239 -6
- ccxt/pro/gate.py +623 -65
- ccxt/pro/gateio.py +2 -1
- ccxt/pro/gemini.py +27 -11
- ccxt/pro/hashkey.py +2 -2
- ccxt/pro/hitbtc.py +196 -91
- ccxt/pro/hollaex.py +23 -7
- ccxt/pro/htx.py +51 -14
- ccxt/pro/huobi.py +2 -1
- ccxt/pro/hyperliquid.py +591 -27
- ccxt/pro/independentreserve.py +9 -6
- ccxt/pro/kraken.py +640 -320
- ccxt/pro/krakenfutures.py +62 -35
- ccxt/pro/kucoin.py +267 -46
- ccxt/pro/kucoinfutures.py +165 -21
- ccxt/pro/lbank.py +102 -21
- ccxt/pro/luno.py +12 -8
- ccxt/pro/mexc.py +877 -111
- ccxt/pro/modetrade.py +1271 -0
- ccxt/pro/myokx.py +38 -0
- ccxt/pro/ndax.py +15 -2
- ccxt/pro/okcoin.py +23 -4
- ccxt/pro/okx.py +573 -98
- ccxt/pro/okxus.py +38 -0
- ccxt/pro/onetrading.py +30 -13
- ccxt/pro/oxfun.py +131 -27
- ccxt/pro/p2b.py +88 -22
- ccxt/pro/paradex.py +3 -3
- ccxt/pro/phemex.py +75 -21
- ccxt/pro/poloniex.py +124 -41
- ccxt/pro/probit.py +87 -80
- ccxt/pro/tradeogre.py +272 -0
- ccxt/pro/upbit.py +152 -12
- ccxt/pro/vertex.py +8 -3
- ccxt/pro/whitebit.py +58 -5
- ccxt/pro/woo.py +228 -37
- ccxt/pro/woofipro.py +106 -18
- ccxt/pro/xt.py +111 -5
- ccxt/probit.py +224 -95
- ccxt/protobuf/__init__.py +0 -0
- ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
- ccxt/protobuf/mexc/__init__.py +0 -0
- ccxt/ramzinex.py +32 -28
- ccxt/sarmayex.py +7 -7
- ccxt/sarrafex.py +10 -10
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/tabdeal.py +13 -12
- ccxt/test/tests_async.py +261 -57
- ccxt/test/tests_helpers.py +1 -3
- ccxt/test/tests_init.py +4 -3
- ccxt/test/tests_sync.py +261 -57
- ccxt/tetherland.py +7 -7
- ccxt/timex.py +210 -51
- ccxt/tokocrypto.py +167 -47
- ccxt/tradeogre.py +266 -31
- ccxt/twox.py +7 -7
- ccxt/ubitex.py +9 -9
- ccxt/upbit.py +568 -165
- ccxt/vertex.py +160 -32
- ccxt/wallex.py +9 -9
- ccxt/wavesexchange.py +165 -30
- ccxt/whitebit.py +975 -127
- ccxt/woo.py +1917 -1016
- ccxt/woofipro.py +432 -141
- ccxt/xt.py +649 -193
- ccxt/yobit.py +194 -70
- ccxt/zaif.py +91 -15
- ccxt/zonda.py +151 -36
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/METADATA +225 -73
- ccxt_ir-4.5.1.dist-info/RECORD +743 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/WHEEL +1 -1
- ccxt/__test__.py +0 -7
- ccxt/abstract/ace.py +0 -15
- ccxt/abstract/bitbay.py +0 -53
- ccxt/abstract/bitcoincom.py +0 -115
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/bitpanda.py +0 -35
- ccxt/abstract/bl3p.py +0 -19
- ccxt/abstract/coinlist.py +0 -54
- ccxt/abstract/currencycom.py +0 -68
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/abstract/idex.py +0 -26
- ccxt/abstract/kuna.py +0 -182
- ccxt/abstract/lykke.py +0 -29
- ccxt/abstract/poloniexfutures.py +0 -48
- ccxt/abstract/wazirx.py +0 -30
- ccxt/ace.py +0 -1012
- ccxt/async_support/ace.py +0 -1012
- ccxt/async_support/base/ws/aiohttp_client.py +0 -125
- ccxt/async_support/base/ws/fast_client.py +0 -96
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitcoincom.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3552
- ccxt/async_support/bitpanda.py +0 -16
- ccxt/async_support/bl3p.py +0 -485
- ccxt/async_support/coinlist.py +0 -2243
- ccxt/async_support/currencycom.py +0 -1950
- ccxt/async_support/hitbtc3.py +0 -16
- ccxt/async_support/idex.py +0 -1766
- ccxt/async_support/kuna.py +0 -1841
- ccxt/async_support/lykke.py +0 -1270
- ccxt/async_support/poloniexfutures.py +0 -1717
- ccxt/async_support/wazirx.py +0 -1224
- ccxt/bitbay.py +0 -17
- ccxt/bitcoincom.py +0 -17
- ccxt/bitfinex2.py +0 -3552
- ccxt/bitpanda.py +0 -16
- ccxt/bl3p.py +0 -485
- ccxt/coinlist.py +0 -2243
- ccxt/currencycom.py +0 -1950
- ccxt/hitbtc3.py +0 -16
- ccxt/idex.py +0 -1766
- ccxt/kuna.py +0 -1841
- ccxt/lykke.py +0 -1270
- ccxt/poloniexfutures.py +0 -1717
- ccxt/pro/bitcoincom.py +0 -34
- ccxt/pro/bitfinex2.py +0 -1083
- ccxt/pro/bitpanda.py +0 -15
- ccxt/pro/currencycom.py +0 -536
- ccxt/pro/idex.py +0 -672
- ccxt/pro/poloniexfutures.py +0 -990
- ccxt/pro/wazirx.py +0 -749
- ccxt/test/base/__init__.py +0 -29
- 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 -109
- 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 -31
- 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_liquidation.py +0 -50
- 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 -193
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -33
- 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 -69
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -353
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -92
- 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/test/test_async.py +0 -1649
- ccxt/test/test_sync.py +0 -1648
- ccxt/wazirx.py +0 -1224
- ccxt_ir-4.3.46.0.3.dist-info/RECORD +0 -773
- /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info/licenses}/LICENSE.txt +0 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/top_level.txt +0 -0
ccxt/pro/okx.py
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import ccxt.async_support
|
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
|
|
8
8
|
import hashlib
|
|
9
|
-
from ccxt.base.types import Balances, Int, Liquidation, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade
|
|
9
|
+
from ccxt.base.types import Any, Balances, Bool, Int, Liquidation, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade
|
|
10
10
|
from ccxt.async_support.base.ws.client import Client
|
|
11
11
|
from typing import List
|
|
12
12
|
from ccxt.base.errors import ExchangeError
|
|
@@ -14,16 +14,20 @@ from ccxt.base.errors import AuthenticationError
|
|
|
14
14
|
from ccxt.base.errors import ArgumentsRequired
|
|
15
15
|
from ccxt.base.errors import BadRequest
|
|
16
16
|
from ccxt.base.errors import InvalidNonce
|
|
17
|
+
from ccxt.base.errors import ChecksumError
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class okx(ccxt.async_support.okx):
|
|
20
21
|
|
|
21
|
-
def describe(self):
|
|
22
|
+
def describe(self) -> Any:
|
|
22
23
|
return self.deep_extend(super(okx, self).describe(), {
|
|
23
24
|
'has': {
|
|
24
25
|
'ws': True,
|
|
25
26
|
'watchTicker': True,
|
|
27
|
+
'watchMarkPrice': True,
|
|
28
|
+
'watchMarkPrices': True,
|
|
26
29
|
'watchTickers': True,
|
|
30
|
+
'watchBidsAsks': True,
|
|
27
31
|
'watchOrderBook': True,
|
|
28
32
|
'watchTrades': True,
|
|
29
33
|
'watchTradesForSymbols': True,
|
|
@@ -56,6 +60,7 @@ class okx(ccxt.async_support.okx):
|
|
|
56
60
|
},
|
|
57
61
|
'options': {
|
|
58
62
|
'watchOrderBook': {
|
|
63
|
+
'checksum': True,
|
|
59
64
|
#
|
|
60
65
|
# bbo-tbt
|
|
61
66
|
# 1. Newly added channel that sends tick-by-tick Level 1 data
|
|
@@ -103,13 +108,12 @@ class okx(ccxt.async_support.okx):
|
|
|
103
108
|
'ws': {
|
|
104
109
|
# 'inflate': True,
|
|
105
110
|
},
|
|
106
|
-
'checksum': True,
|
|
107
111
|
},
|
|
108
112
|
'streaming': {
|
|
109
113
|
# okex does not support built-in ws protocol-level ping-pong
|
|
110
114
|
# instead it requires a custom text-based ping-pong
|
|
111
115
|
'ping': self.ping,
|
|
112
|
-
'keepAlive':
|
|
116
|
+
'keepAlive': 18000,
|
|
113
117
|
},
|
|
114
118
|
})
|
|
115
119
|
|
|
@@ -132,9 +136,8 @@ class okx(ccxt.async_support.okx):
|
|
|
132
136
|
symbols = self.symbols
|
|
133
137
|
symbols = self.market_symbols(symbols)
|
|
134
138
|
url = self.get_url(channel, access)
|
|
135
|
-
|
|
139
|
+
messageHashes = []
|
|
136
140
|
args = []
|
|
137
|
-
messageHash += '::' + ','.join(symbols)
|
|
138
141
|
for i in range(0, len(symbols)):
|
|
139
142
|
marketId = self.market_id(symbols[i])
|
|
140
143
|
arg: dict = {
|
|
@@ -142,11 +145,12 @@ class okx(ccxt.async_support.okx):
|
|
|
142
145
|
'instId': marketId,
|
|
143
146
|
}
|
|
144
147
|
args.append(self.extend(arg, params))
|
|
148
|
+
messageHashes.append(channel + '::' + symbols[i])
|
|
145
149
|
request: dict = {
|
|
146
150
|
'op': 'subscribe',
|
|
147
151
|
'args': args,
|
|
148
152
|
}
|
|
149
|
-
return await self.
|
|
153
|
+
return await self.watch_multiple(url, messageHashes, request, messageHashes)
|
|
150
154
|
|
|
151
155
|
async def subscribe(self, access, messageHash, channel, symbol, params={}):
|
|
152
156
|
await self.load_markets()
|
|
@@ -180,7 +184,7 @@ class okx(ccxt.async_support.okx):
|
|
|
180
184
|
async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
181
185
|
"""
|
|
182
186
|
get the list of most recent trades for a particular symbol
|
|
183
|
-
:param str
|
|
187
|
+
:param str symbols:
|
|
184
188
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
|
185
189
|
:param int [limit]: the maximum amount of trades to fetch
|
|
186
190
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -215,6 +219,43 @@ class okx(ccxt.async_support.okx):
|
|
|
215
219
|
limit = trades.getLimit(tradeSymbol, limit)
|
|
216
220
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
|
217
221
|
|
|
222
|
+
async def un_watch_trades_for_symbols(self, symbols: List[str], params={}) -> Any:
|
|
223
|
+
"""
|
|
224
|
+
unWatches from the stream channel
|
|
225
|
+
:param str[] symbols:
|
|
226
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
227
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
|
228
|
+
"""
|
|
229
|
+
await self.load_markets()
|
|
230
|
+
symbols = self.market_symbols(symbols, None, False)
|
|
231
|
+
channel = 'trades'
|
|
232
|
+
topics = []
|
|
233
|
+
messageHashes = []
|
|
234
|
+
for i in range(0, len(symbols)):
|
|
235
|
+
symbol = symbols[i]
|
|
236
|
+
messageHashes.append('unsubscribe:trades:' + symbol)
|
|
237
|
+
marketId = self.market_id(symbol)
|
|
238
|
+
topic: dict = {
|
|
239
|
+
'channel': channel,
|
|
240
|
+
'instId': marketId,
|
|
241
|
+
}
|
|
242
|
+
topics.append(topic)
|
|
243
|
+
request: dict = {
|
|
244
|
+
'op': 'unsubscribe',
|
|
245
|
+
'args': topics,
|
|
246
|
+
}
|
|
247
|
+
url = self.get_url(channel, 'public')
|
|
248
|
+
return await self.watch_multiple(url, messageHashes, request, messageHashes)
|
|
249
|
+
|
|
250
|
+
async def un_watch_trades(self, symbol: str, params={}) -> Any:
|
|
251
|
+
"""
|
|
252
|
+
unWatches from the stream channel
|
|
253
|
+
:param str symbol: unified symbol of the market to fetch trades for
|
|
254
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
255
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
|
256
|
+
"""
|
|
257
|
+
return await self.un_watch_trades_for_symbols([symbol], params)
|
|
258
|
+
|
|
218
259
|
def handle_trades(self, client: Client, message):
|
|
219
260
|
#
|
|
220
261
|
# {
|
|
@@ -250,7 +291,9 @@ class okx(ccxt.async_support.okx):
|
|
|
250
291
|
async def watch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
|
251
292
|
"""
|
|
252
293
|
watch the current funding rate
|
|
253
|
-
|
|
294
|
+
|
|
295
|
+
https://www.okx.com/docs-v5/en/#public-data-websocket-funding-rate-channel
|
|
296
|
+
|
|
254
297
|
:param str symbol: unified market symbol
|
|
255
298
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
256
299
|
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
|
@@ -262,7 +305,9 @@ class okx(ccxt.async_support.okx):
|
|
|
262
305
|
async def watch_funding_rates(self, symbols: List[str], params={}) -> FundingRates:
|
|
263
306
|
"""
|
|
264
307
|
watch the funding rate for multiple markets
|
|
265
|
-
|
|
308
|
+
|
|
309
|
+
https://www.okx.com/docs-v5/en/#public-data-websocket-funding-rate-channel
|
|
310
|
+
|
|
266
311
|
:param str[] symbols: list of unified market symbols
|
|
267
312
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
268
313
|
:returns dict: a dictionary of `funding rates structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexe by market symbols
|
|
@@ -324,7 +369,9 @@ class okx(ccxt.async_support.okx):
|
|
|
324
369
|
|
|
325
370
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
|
326
371
|
"""
|
|
327
|
-
|
|
372
|
+
|
|
373
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-tickers-channel
|
|
374
|
+
|
|
328
375
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
329
376
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
|
330
377
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -334,20 +381,37 @@ class okx(ccxt.async_support.okx):
|
|
|
334
381
|
channel = None
|
|
335
382
|
channel, params = self.handle_option_and_params(params, 'watchTicker', 'channel', 'tickers')
|
|
336
383
|
params['channel'] = channel
|
|
384
|
+
market = self.market(symbol)
|
|
385
|
+
symbol = market['symbol']
|
|
337
386
|
ticker = await self.watch_tickers([symbol], params)
|
|
338
387
|
return self.safe_value(ticker, symbol)
|
|
339
388
|
|
|
389
|
+
async def un_watch_ticker(self, symbol: str, params={}) -> Any:
|
|
390
|
+
"""
|
|
391
|
+
|
|
392
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-tickers-channel
|
|
393
|
+
|
|
394
|
+
unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
395
|
+
:param str symbol: unified symbol of the market to fetch the ticker for
|
|
396
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
397
|
+
:param str [params.channel]: the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
|
|
398
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
399
|
+
"""
|
|
400
|
+
return await self.un_watch_tickers([symbol], params)
|
|
401
|
+
|
|
340
402
|
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
|
341
403
|
"""
|
|
342
|
-
|
|
404
|
+
|
|
405
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-tickers-channel
|
|
406
|
+
|
|
343
407
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
344
408
|
:param str[] [symbols]: unified symbol of the market to fetch the ticker for
|
|
345
409
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
346
410
|
:param str [params.channel]: the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
|
|
347
411
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
348
412
|
"""
|
|
349
|
-
|
|
350
|
-
|
|
413
|
+
await self.load_markets()
|
|
414
|
+
symbols = self.market_symbols(symbols, None, False)
|
|
351
415
|
channel = None
|
|
352
416
|
channel, params = self.handle_option_and_params(params, 'watchTickers', 'channel', 'tickers')
|
|
353
417
|
newTickers = await self.subscribe_multiple('public', channel, symbols, params)
|
|
@@ -355,6 +419,78 @@ class okx(ccxt.async_support.okx):
|
|
|
355
419
|
return newTickers
|
|
356
420
|
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
|
357
421
|
|
|
422
|
+
async def watch_mark_price(self, symbol: str, params={}) -> Ticker:
|
|
423
|
+
"""
|
|
424
|
+
|
|
425
|
+
https://www.okx.com/docs-v5/en/#public-data-websocket-mark-price-channel
|
|
426
|
+
|
|
427
|
+
watches a mark price
|
|
428
|
+
:param str symbol: unified symbol of the market to fetch the ticker for
|
|
429
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
430
|
+
:param str [params.channel]: the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
|
|
431
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
432
|
+
"""
|
|
433
|
+
channel = None
|
|
434
|
+
channel, params = self.handle_option_and_params(params, 'watchMarkPrice', 'channel', 'mark-price')
|
|
435
|
+
params['channel'] = channel
|
|
436
|
+
market = self.market(symbol)
|
|
437
|
+
symbol = market['symbol']
|
|
438
|
+
ticker = await self.watch_mark_prices([symbol], params)
|
|
439
|
+
return ticker[symbol]
|
|
440
|
+
|
|
441
|
+
async def watch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
|
|
442
|
+
"""
|
|
443
|
+
|
|
444
|
+
https://www.okx.com/docs-v5/en/#public-data-websocket-mark-price-channel
|
|
445
|
+
|
|
446
|
+
watches mark prices
|
|
447
|
+
:param str[] [symbols]: unified symbol of the market to fetch the ticker for
|
|
448
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
449
|
+
:param str [params.channel]: the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
|
|
450
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
451
|
+
"""
|
|
452
|
+
await self.load_markets()
|
|
453
|
+
symbols = self.market_symbols(symbols, None, False)
|
|
454
|
+
channel = None
|
|
455
|
+
channel, params = self.handle_option_and_params(params, 'watchMarkPrices', 'channel', 'mark-price')
|
|
456
|
+
newTickers = await self.subscribe_multiple('public', channel, symbols, params)
|
|
457
|
+
if self.newUpdates:
|
|
458
|
+
return newTickers
|
|
459
|
+
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
|
460
|
+
|
|
461
|
+
async def un_watch_tickers(self, symbols: Strings = None, params={}) -> Any:
|
|
462
|
+
"""
|
|
463
|
+
|
|
464
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-tickers-channel
|
|
465
|
+
|
|
466
|
+
unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
467
|
+
:param str[] [symbols]: unified symbol of the market to fetch the ticker for
|
|
468
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
469
|
+
:param str [params.channel]: the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
|
|
470
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
471
|
+
"""
|
|
472
|
+
await self.load_markets()
|
|
473
|
+
symbols = self.market_symbols(symbols, None, False)
|
|
474
|
+
channel = None
|
|
475
|
+
channel, params = self.handle_option_and_params(params, 'watchTickers', 'channel', 'tickers')
|
|
476
|
+
topics = []
|
|
477
|
+
messageHashes = []
|
|
478
|
+
for i in range(0, len(symbols)):
|
|
479
|
+
symbol = symbols[i]
|
|
480
|
+
messageHashes.append('unsubscribe:ticker:' + symbol)
|
|
481
|
+
marketId = self.market_id(symbol)
|
|
482
|
+
topic: dict = {
|
|
483
|
+
'channel': channel,
|
|
484
|
+
'instId': marketId,
|
|
485
|
+
}
|
|
486
|
+
topics.append(topic)
|
|
487
|
+
request: dict = {
|
|
488
|
+
'op': 'unsubscribe',
|
|
489
|
+
'args': topics,
|
|
490
|
+
}
|
|
491
|
+
url = self.get_url(channel, 'public')
|
|
492
|
+
return await self.watch_multiple(url, messageHashes, request, messageHashes)
|
|
493
|
+
|
|
358
494
|
def handle_ticker(self, client: Client, message):
|
|
359
495
|
#
|
|
360
496
|
# {
|
|
@@ -381,33 +517,114 @@ class okx(ccxt.async_support.okx):
|
|
|
381
517
|
# ]
|
|
382
518
|
# }
|
|
383
519
|
#
|
|
520
|
+
self.handle_bid_ask(client, message)
|
|
384
521
|
arg = self.safe_value(message, 'arg', {})
|
|
522
|
+
marketId = self.safe_string(arg, 'instId')
|
|
523
|
+
market = self.safe_market(marketId, None, '-')
|
|
524
|
+
symbol = market['symbol']
|
|
385
525
|
channel = self.safe_string(arg, 'channel')
|
|
386
526
|
data = self.safe_value(message, 'data', [])
|
|
387
|
-
newTickers =
|
|
527
|
+
newTickers: dict = {}
|
|
388
528
|
for i in range(0, len(data)):
|
|
389
529
|
ticker = self.parse_ticker(data[i])
|
|
390
|
-
symbol = ticker['symbol']
|
|
391
530
|
self.tickers[symbol] = ticker
|
|
392
|
-
newTickers
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
messageHash = messageHashes[i]
|
|
396
|
-
parts = messageHash.split('::')
|
|
397
|
-
symbolsString = parts[1]
|
|
398
|
-
symbols = symbolsString.split(',')
|
|
399
|
-
tickers = self.filter_by_array(newTickers, 'symbol', symbols)
|
|
400
|
-
tickersSymbols = list(tickers.keys())
|
|
401
|
-
numTickers = len(tickersSymbols)
|
|
402
|
-
if numTickers > 0:
|
|
403
|
-
client.resolve(tickers, messageHash)
|
|
404
|
-
return message
|
|
531
|
+
newTickers[symbol] = ticker
|
|
532
|
+
messageHash = channel + '::' + symbol
|
|
533
|
+
client.resolve(newTickers, messageHash)
|
|
405
534
|
|
|
406
|
-
async def
|
|
535
|
+
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
|
536
|
+
"""
|
|
537
|
+
|
|
538
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-tickers-channel
|
|
539
|
+
|
|
540
|
+
watches best bid & ask for symbols
|
|
541
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
542
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
543
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
544
|
+
"""
|
|
545
|
+
await self.load_markets()
|
|
546
|
+
symbols = self.market_symbols(symbols, None, False)
|
|
547
|
+
channel = None
|
|
548
|
+
channel, params = self.handle_option_and_params(params, 'watchBidsAsks', 'channel', 'tickers')
|
|
549
|
+
url = self.get_url(channel, 'public')
|
|
550
|
+
messageHashes = []
|
|
551
|
+
args = []
|
|
552
|
+
for i in range(0, len(symbols)):
|
|
553
|
+
marketId = self.market_id(symbols[i])
|
|
554
|
+
arg: dict = {
|
|
555
|
+
'channel': channel,
|
|
556
|
+
'instId': marketId,
|
|
557
|
+
}
|
|
558
|
+
args.append(self.extend(arg, params))
|
|
559
|
+
messageHashes.append('bidask::' + symbols[i])
|
|
560
|
+
request: dict = {
|
|
561
|
+
'op': 'subscribe',
|
|
562
|
+
'args': args,
|
|
563
|
+
}
|
|
564
|
+
newTickers = await self.watch_multiple(url, messageHashes, request, messageHashes)
|
|
565
|
+
if self.newUpdates:
|
|
566
|
+
tickers: dict = {}
|
|
567
|
+
tickers[newTickers['symbol']] = newTickers
|
|
568
|
+
return tickers
|
|
569
|
+
return self.filter_by_array(self.bidsasks, 'symbol', symbols)
|
|
570
|
+
|
|
571
|
+
def handle_bid_ask(self, client: Client, message):
|
|
572
|
+
#
|
|
573
|
+
# {
|
|
574
|
+
# "arg": {channel: "tickers", instId: "BTC-USDT"},
|
|
575
|
+
# "data": [
|
|
576
|
+
# {
|
|
577
|
+
# "instType": "SPOT",
|
|
578
|
+
# "instId": "BTC-USDT",
|
|
579
|
+
# "last": "31500.1",
|
|
580
|
+
# "lastSz": "0.00001754",
|
|
581
|
+
# "askPx": "31500.1",
|
|
582
|
+
# "askSz": "0.00998144",
|
|
583
|
+
# "bidPx": "31500",
|
|
584
|
+
# "bidSz": "3.05652439",
|
|
585
|
+
# "open24h": "31697",
|
|
586
|
+
# "high24h": "32248",
|
|
587
|
+
# "low24h": "31165.6",
|
|
588
|
+
# "sodUtc0": "31385.5",
|
|
589
|
+
# "sodUtc8": "32134.9",
|
|
590
|
+
# "volCcy24h": "503403597.38138519",
|
|
591
|
+
# "vol24h": "15937.10781721",
|
|
592
|
+
# "ts": "1626526618762"
|
|
593
|
+
# }
|
|
594
|
+
# ]
|
|
595
|
+
# }
|
|
596
|
+
#
|
|
597
|
+
data = self.safe_list(message, 'data', [])
|
|
598
|
+
ticker = self.safe_dict(data, 0, {})
|
|
599
|
+
parsedTicker = self.parse_ws_bid_ask(ticker)
|
|
600
|
+
symbol = parsedTicker['symbol']
|
|
601
|
+
self.bidsasks[symbol] = parsedTicker
|
|
602
|
+
messageHash = 'bidask::' + symbol
|
|
603
|
+
client.resolve(parsedTicker, messageHash)
|
|
604
|
+
|
|
605
|
+
def parse_ws_bid_ask(self, ticker, market=None):
|
|
606
|
+
marketId = self.safe_string(ticker, 'instId')
|
|
607
|
+
market = self.safe_market(marketId, market)
|
|
608
|
+
symbol = self.safe_string(market, 'symbol')
|
|
609
|
+
timestamp = self.safe_integer(ticker, 'ts')
|
|
610
|
+
return self.safe_ticker({
|
|
611
|
+
'symbol': symbol,
|
|
612
|
+
'timestamp': timestamp,
|
|
613
|
+
'datetime': self.iso8601(timestamp),
|
|
614
|
+
'ask': self.safe_string(ticker, 'askPx'),
|
|
615
|
+
'askVolume': self.safe_string(ticker, 'askSz'),
|
|
616
|
+
'bid': self.safe_string(ticker, 'bidPx'),
|
|
617
|
+
'bidVolume': self.safe_string(ticker, 'bidSz'),
|
|
618
|
+
'info': ticker,
|
|
619
|
+
}, market)
|
|
620
|
+
|
|
621
|
+
async def watch_liquidations_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
|
407
622
|
"""
|
|
408
623
|
watch the public liquidations of a trading pair
|
|
409
|
-
|
|
410
|
-
|
|
624
|
+
|
|
625
|
+
https://www.okx.com/docs-v5/en/#public-data-websocket-liquidation-orders-channel
|
|
626
|
+
|
|
627
|
+
:param str symbols:
|
|
411
628
|
:param int [since]: the earliest time in ms to fetch liquidations for
|
|
412
629
|
:param int [limit]: the maximum number of liquidation structures to retrieve
|
|
413
630
|
:param dict [params]: exchange specific parameters for the okx api endpoint
|
|
@@ -416,8 +633,13 @@ class okx(ccxt.async_support.okx):
|
|
|
416
633
|
await self.load_markets()
|
|
417
634
|
symbols = self.market_symbols(symbols, None, True, True)
|
|
418
635
|
messageHash = 'liquidations'
|
|
636
|
+
messageHashes = []
|
|
419
637
|
if symbols is not None:
|
|
420
|
-
|
|
638
|
+
for i in range(0, len(symbols)):
|
|
639
|
+
symbol = symbols[i]
|
|
640
|
+
messageHashes.append(messageHash + '::' + symbol)
|
|
641
|
+
else:
|
|
642
|
+
messageHashes.append(messageHash)
|
|
421
643
|
market = self.get_market_from_symbols(symbols)
|
|
422
644
|
type = None
|
|
423
645
|
type, params = self.handle_market_type_and_params('watchliquidationsForSymbols', market, params)
|
|
@@ -428,9 +650,16 @@ class okx(ccxt.async_support.okx):
|
|
|
428
650
|
type = 'futures'
|
|
429
651
|
uppercaseType = type.upper()
|
|
430
652
|
request = {
|
|
431
|
-
'
|
|
653
|
+
'op': 'subscribe',
|
|
654
|
+
'args': [
|
|
655
|
+
{
|
|
656
|
+
'channel': channel,
|
|
657
|
+
'instType': uppercaseType,
|
|
658
|
+
},
|
|
659
|
+
],
|
|
432
660
|
}
|
|
433
|
-
|
|
661
|
+
url = self.get_url(channel, 'public')
|
|
662
|
+
newLiquidations = await self.watch_multiple(url, messageHashes, request, messageHashes)
|
|
434
663
|
if self.newUpdates:
|
|
435
664
|
return newLiquidations
|
|
436
665
|
return self.filter_by_symbols_since_limit(self.liquidations, symbols, since, limit, True)
|
|
@@ -477,26 +706,42 @@ class okx(ccxt.async_support.okx):
|
|
|
477
706
|
client.resolve([liquidation], 'liquidations')
|
|
478
707
|
client.resolve([liquidation], 'liquidations::' + symbol)
|
|
479
708
|
|
|
480
|
-
async def watch_my_liquidations_for_symbols(self, symbols: List[str]
|
|
709
|
+
async def watch_my_liquidations_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
|
481
710
|
"""
|
|
482
711
|
watch the private liquidations of a trading pair
|
|
483
|
-
|
|
484
|
-
|
|
712
|
+
|
|
713
|
+
https://www.okx.com/docs-v5/en/#trading-account-websocket-balance-and-position-channel
|
|
714
|
+
|
|
715
|
+
:param str[] symbols:
|
|
485
716
|
:param int [since]: the earliest time in ms to fetch liquidations for
|
|
486
717
|
:param int [limit]: the maximum number of liquidation structures to retrieve
|
|
487
718
|
:param dict [params]: exchange specific parameters for the okx api endpoint
|
|
488
719
|
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
|
489
720
|
"""
|
|
490
721
|
await self.load_markets()
|
|
491
|
-
|
|
722
|
+
isTrigger = self.safe_value_2(params, 'stop', 'trigger', False)
|
|
492
723
|
params = self.omit(params, ['stop', 'trigger'])
|
|
493
|
-
await self.authenticate({'access': 'business' if
|
|
724
|
+
await self.authenticate({'access': 'business' if isTrigger else 'private'})
|
|
494
725
|
symbols = self.market_symbols(symbols, None, True, True)
|
|
495
726
|
messageHash = 'myLiquidations'
|
|
727
|
+
messageHashes = []
|
|
496
728
|
if symbols is not None:
|
|
497
|
-
|
|
729
|
+
for i in range(0, len(symbols)):
|
|
730
|
+
symbol = symbols[i]
|
|
731
|
+
messageHashes.append(messageHash + '::' + symbol)
|
|
732
|
+
else:
|
|
733
|
+
messageHashes.append(messageHash)
|
|
498
734
|
channel = 'balance_and_position'
|
|
499
|
-
|
|
735
|
+
request: dict = {
|
|
736
|
+
'op': 'subscribe',
|
|
737
|
+
'args': [
|
|
738
|
+
{
|
|
739
|
+
'channel': channel,
|
|
740
|
+
},
|
|
741
|
+
],
|
|
742
|
+
}
|
|
743
|
+
url = self.get_url(channel, 'private')
|
|
744
|
+
newLiquidations = await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), messageHashes)
|
|
500
745
|
if self.newUpdates:
|
|
501
746
|
return newLiquidations
|
|
502
747
|
return self.filter_by_symbols_since_limit(self.liquidations, symbols, since, limit, True)
|
|
@@ -631,6 +876,7 @@ class okx(ccxt.async_support.okx):
|
|
|
631
876
|
'contracts': self.safe_number(liquidationDetails, 'sz'),
|
|
632
877
|
'contractSize': self.safe_number(market, 'contractSize'),
|
|
633
878
|
'price': self.safe_number(liquidationDetails, 'bkPx'),
|
|
879
|
+
'side': self.safe_string(liquidationDetails, 'side'),
|
|
634
880
|
'baseValue': None,
|
|
635
881
|
'quoteValue': None,
|
|
636
882
|
'timestamp': timestamp,
|
|
@@ -656,6 +902,17 @@ class okx(ccxt.async_support.okx):
|
|
|
656
902
|
limit = ohlcv.getLimit(symbol, limit)
|
|
657
903
|
return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
|
|
658
904
|
|
|
905
|
+
async def un_watch_ohlcv(self, symbol: str, timeframe='1m', params={}) -> Any:
|
|
906
|
+
"""
|
|
907
|
+
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
908
|
+
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
|
909
|
+
:param str timeframe: the length of time each candle represents
|
|
910
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
911
|
+
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
|
912
|
+
"""
|
|
913
|
+
await self.load_markets()
|
|
914
|
+
return await self.un_watch_ohlcv_for_symbols([[symbol, timeframe]], params)
|
|
915
|
+
|
|
659
916
|
async def watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], since: Int = None, limit: Int = None, params={}):
|
|
660
917
|
"""
|
|
661
918
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
@@ -695,6 +952,39 @@ class okx(ccxt.async_support.okx):
|
|
|
695
952
|
filtered = self.filter_by_since_limit(candles, since, limit, 0, True)
|
|
696
953
|
return self.create_ohlcv_object(symbol, timeframe, filtered)
|
|
697
954
|
|
|
955
|
+
async def un_watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], params={}) -> Any:
|
|
956
|
+
"""
|
|
957
|
+
unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
958
|
+
:param str[][] symbolsAndTimeframes: array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
|
959
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
960
|
+
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
|
961
|
+
"""
|
|
962
|
+
symbolsLength = len(symbolsAndTimeframes)
|
|
963
|
+
if symbolsLength == 0 or not isinstance(symbolsAndTimeframes[0], list):
|
|
964
|
+
raise ArgumentsRequired(self.id + " watchOHLCVForSymbols() requires a an array of symbols and timeframes, like [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]")
|
|
965
|
+
await self.load_markets()
|
|
966
|
+
topics = []
|
|
967
|
+
messageHashes = []
|
|
968
|
+
for i in range(0, len(symbolsAndTimeframes)):
|
|
969
|
+
symbolAndTimeframe = symbolsAndTimeframes[i]
|
|
970
|
+
sym = symbolAndTimeframe[0]
|
|
971
|
+
tf = symbolAndTimeframe[1]
|
|
972
|
+
marketId = self.market_id(sym)
|
|
973
|
+
interval = self.safe_string(self.timeframes, tf, tf)
|
|
974
|
+
channel = 'candle' + interval
|
|
975
|
+
topic: dict = {
|
|
976
|
+
'channel': channel,
|
|
977
|
+
'instId': marketId,
|
|
978
|
+
}
|
|
979
|
+
topics.append(topic)
|
|
980
|
+
messageHashes.append('unsubscribe:multi:' + channel + ':' + sym)
|
|
981
|
+
request: dict = {
|
|
982
|
+
'op': 'unsubscribe',
|
|
983
|
+
'args': topics,
|
|
984
|
+
}
|
|
985
|
+
url = self.get_url('candle', 'public')
|
|
986
|
+
return await self.watch_multiple(url, messageHashes, request, messageHashes)
|
|
987
|
+
|
|
698
988
|
def handle_ohlcv(self, client: Client, message):
|
|
699
989
|
#
|
|
700
990
|
# {
|
|
@@ -740,7 +1030,9 @@ class okx(ccxt.async_support.okx):
|
|
|
740
1030
|
|
|
741
1031
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
|
742
1032
|
"""
|
|
743
|
-
|
|
1033
|
+
|
|
1034
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-order-book-channel
|
|
1035
|
+
|
|
744
1036
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
745
1037
|
:param str symbol: unified symbol of the market to fetch the order book for
|
|
746
1038
|
:param int [limit]: the maximum amount of order book entries to return
|
|
@@ -775,7 +1067,9 @@ class okx(ccxt.async_support.okx):
|
|
|
775
1067
|
|
|
776
1068
|
async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
|
|
777
1069
|
"""
|
|
778
|
-
|
|
1070
|
+
|
|
1071
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-order-book-channel
|
|
1072
|
+
|
|
779
1073
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
780
1074
|
:param str[] symbols: unified array of symbols
|
|
781
1075
|
:param int [limit]: 1,5, 400, 50(l2-tbt, vip4+) or 40000(vip5+) the maximum amount of order book entries to return
|
|
@@ -819,6 +1113,66 @@ class okx(ccxt.async_support.okx):
|
|
|
819
1113
|
orderbook = await self.watch_multiple(url, messageHashes, request, messageHashes)
|
|
820
1114
|
return orderbook.limit()
|
|
821
1115
|
|
|
1116
|
+
async def un_watch_order_book_for_symbols(self, symbols: List[str], params={}) -> Any:
|
|
1117
|
+
"""
|
|
1118
|
+
|
|
1119
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-order-book-channel
|
|
1120
|
+
|
|
1121
|
+
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
1122
|
+
:param str[] symbols: unified array of symbols
|
|
1123
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1124
|
+
:param int [params.limit]: the maximum amount of order book entries to return
|
|
1125
|
+
:param str [params.depth]: okx order book depth, can be books, books5, books-l2-tbt, books50-l2-tbt, bbo-tbt
|
|
1126
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
|
1127
|
+
"""
|
|
1128
|
+
await self.load_markets()
|
|
1129
|
+
symbols = self.market_symbols(symbols, None, False)
|
|
1130
|
+
depth = None
|
|
1131
|
+
depth, params = self.handle_option_and_params(params, 'watchOrderBook', 'depth', 'books')
|
|
1132
|
+
limit = self.safe_integer(params, 'limit')
|
|
1133
|
+
if limit is not None:
|
|
1134
|
+
if limit == 1:
|
|
1135
|
+
depth = 'bbo-tbt'
|
|
1136
|
+
elif limit > 1 and limit <= 5:
|
|
1137
|
+
depth = 'books5'
|
|
1138
|
+
elif limit == 50:
|
|
1139
|
+
depth = 'books50-l2-tbt' # Make sure you have VIP4 and above
|
|
1140
|
+
elif limit == 400:
|
|
1141
|
+
depth = 'books'
|
|
1142
|
+
topics = []
|
|
1143
|
+
subMessageHashes = []
|
|
1144
|
+
messageHashes = []
|
|
1145
|
+
for i in range(0, len(symbols)):
|
|
1146
|
+
symbol = symbols[i]
|
|
1147
|
+
subMessageHashes.append(depth + ':' + symbol)
|
|
1148
|
+
messageHashes.append('unsubscribe:orderbook:' + symbol)
|
|
1149
|
+
marketId = self.market_id(symbol)
|
|
1150
|
+
topic: dict = {
|
|
1151
|
+
'channel': depth,
|
|
1152
|
+
'instId': marketId,
|
|
1153
|
+
}
|
|
1154
|
+
topics.append(topic)
|
|
1155
|
+
request: dict = {
|
|
1156
|
+
'op': 'unsubscribe',
|
|
1157
|
+
'args': topics,
|
|
1158
|
+
}
|
|
1159
|
+
url = self.get_url(depth, 'public')
|
|
1160
|
+
return await self.watch_multiple(url, messageHashes, request, messageHashes)
|
|
1161
|
+
|
|
1162
|
+
async def un_watch_order_book(self, symbol: str, params={}) -> Any:
|
|
1163
|
+
"""
|
|
1164
|
+
|
|
1165
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-order-book-channel
|
|
1166
|
+
|
|
1167
|
+
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
1168
|
+
:param str symbol: unified array of symbols
|
|
1169
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1170
|
+
:param int [params.limit]: the maximum amount of order book entries to return
|
|
1171
|
+
:param str [params.depth]: okx order book depth, can be books, books5, books-l2-tbt, books50-l2-tbt, bbo-tbt
|
|
1172
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
|
1173
|
+
"""
|
|
1174
|
+
return await self.un_watch_order_book_for_symbols([symbol], params)
|
|
1175
|
+
|
|
822
1176
|
def handle_delta(self, bookside, delta):
|
|
823
1177
|
#
|
|
824
1178
|
# [
|
|
@@ -836,7 +1190,7 @@ class okx(ccxt.async_support.okx):
|
|
|
836
1190
|
for i in range(0, len(deltas)):
|
|
837
1191
|
self.handle_delta(bookside, deltas[i])
|
|
838
1192
|
|
|
839
|
-
def handle_order_book_message(self, client: Client, message, orderbook, messageHash):
|
|
1193
|
+
def handle_order_book_message(self, client: Client, message, orderbook, messageHash, market=None):
|
|
840
1194
|
#
|
|
841
1195
|
# {
|
|
842
1196
|
# "asks": [
|
|
@@ -851,6 +1205,9 @@ class okx(ccxt.async_support.okx):
|
|
|
851
1205
|
# ],
|
|
852
1206
|
# "instId": "BTC-USDT",
|
|
853
1207
|
# "ts": "1626537446491"
|
|
1208
|
+
# "checksum": -855196043,
|
|
1209
|
+
# "prevSeqId": 123456,
|
|
1210
|
+
# "seqId": 123457
|
|
854
1211
|
# }
|
|
855
1212
|
#
|
|
856
1213
|
asks = self.safe_value(message, 'asks', [])
|
|
@@ -860,9 +1217,12 @@ class okx(ccxt.async_support.okx):
|
|
|
860
1217
|
self.handle_deltas(storedAsks, asks)
|
|
861
1218
|
self.handle_deltas(storedBids, bids)
|
|
862
1219
|
marketId = self.safe_string(message, 'instId')
|
|
863
|
-
symbol = self.safe_symbol(marketId)
|
|
864
|
-
checksum = self.
|
|
1220
|
+
symbol = self.safe_symbol(marketId, market)
|
|
1221
|
+
checksum = self.handle_option('watchOrderBook', 'checksum', True)
|
|
1222
|
+
seqId = self.safe_integer(message, 'seqId')
|
|
865
1223
|
if checksum:
|
|
1224
|
+
prevSeqId = self.safe_integer(message, 'prevSeqId')
|
|
1225
|
+
nonce = orderbook['nonce']
|
|
866
1226
|
asksLength = len(storedAsks)
|
|
867
1227
|
bidsLength = len(storedBids)
|
|
868
1228
|
payloadArray = []
|
|
@@ -876,12 +1236,17 @@ class okx(ccxt.async_support.okx):
|
|
|
876
1236
|
payload = ':'.join(payloadArray)
|
|
877
1237
|
responseChecksum = self.safe_integer(message, 'checksum')
|
|
878
1238
|
localChecksum = self.crc32(payload, True)
|
|
1239
|
+
error = None
|
|
1240
|
+
if prevSeqId != -1 and nonce != prevSeqId:
|
|
1241
|
+
error = InvalidNonce(self.id + ' watchOrderBook received invalid nonce')
|
|
879
1242
|
if responseChecksum != localChecksum:
|
|
880
|
-
error =
|
|
1243
|
+
error = ChecksumError(self.id + ' ' + self.orderbook_checksum_message(symbol))
|
|
1244
|
+
if error is not None:
|
|
881
1245
|
del client.subscriptions[messageHash]
|
|
882
1246
|
del self.orderbooks[symbol]
|
|
883
1247
|
client.reject(error, messageHash)
|
|
884
1248
|
timestamp = self.safe_integer(message, 'ts')
|
|
1249
|
+
orderbook['nonce'] = seqId
|
|
885
1250
|
orderbook['timestamp'] = timestamp
|
|
886
1251
|
orderbook['datetime'] = self.iso8601(timestamp)
|
|
887
1252
|
return orderbook
|
|
@@ -1001,7 +1366,7 @@ class okx(ccxt.async_support.okx):
|
|
|
1001
1366
|
orderbook = self.orderbooks[symbol]
|
|
1002
1367
|
for i in range(0, len(data)):
|
|
1003
1368
|
update = data[i]
|
|
1004
|
-
self.handle_order_book_message(client, update, orderbook, messageHash)
|
|
1369
|
+
self.handle_order_book_message(client, update, orderbook, messageHash, market)
|
|
1005
1370
|
client.resolve(orderbook, messageHash)
|
|
1006
1371
|
elif (channel == 'books5') or (channel == 'bbo-tbt'):
|
|
1007
1372
|
if not (symbol in self.orderbooks):
|
|
@@ -1042,8 +1407,10 @@ class okx(ccxt.async_support.okx):
|
|
|
1042
1407
|
},
|
|
1043
1408
|
],
|
|
1044
1409
|
}
|
|
1045
|
-
|
|
1046
|
-
|
|
1410
|
+
# Only add params['access'] to prevent sending custom parameters, such.
|
|
1411
|
+
if 'access' in params:
|
|
1412
|
+
request['access'] = params['access']
|
|
1413
|
+
self.watch(url, messageHash, request, messageHash)
|
|
1047
1414
|
return await future
|
|
1048
1415
|
|
|
1049
1416
|
async def watch_balance(self, params={}) -> Balances:
|
|
@@ -1139,24 +1506,26 @@ class okx(ccxt.async_support.okx):
|
|
|
1139
1506
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
1140
1507
|
"""
|
|
1141
1508
|
watches information on multiple trades made by the user
|
|
1142
|
-
|
|
1509
|
+
|
|
1510
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-order-channel
|
|
1511
|
+
|
|
1143
1512
|
:param str [symbol]: unified market symbol of the market trades were made in
|
|
1144
1513
|
:param int [since]: the earliest time in ms to fetch trades for
|
|
1145
1514
|
:param int [limit]: the maximum number of trade structures to retrieve
|
|
1146
1515
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1147
|
-
:param bool [params.
|
|
1516
|
+
:param bool [params.trigger]: True if fetching trigger or conditional trades
|
|
1148
1517
|
:param str [params.type]: 'spot', 'swap', 'future', 'option', 'ANY', 'SPOT', 'MARGIN', 'SWAP', 'FUTURES' or 'OPTION'
|
|
1149
1518
|
:param str [params.marginMode]: 'cross' or 'isolated', for automatically setting the type to spot margin
|
|
1150
|
-
:returns dict[]: a list of
|
|
1519
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
|
1151
1520
|
"""
|
|
1152
1521
|
# By default, receive order updates from any instrument type
|
|
1153
1522
|
type = None
|
|
1154
1523
|
type, params = self.handle_option_and_params(params, 'watchMyTrades', 'type', 'ANY')
|
|
1155
|
-
|
|
1156
|
-
params = self.omit(params, ['stop'])
|
|
1524
|
+
isTrigger = self.safe_bool_2(params, 'trigger', 'stop', False)
|
|
1525
|
+
params = self.omit(params, ['trigger', 'stop'])
|
|
1157
1526
|
await self.load_markets()
|
|
1158
|
-
await self.authenticate({'access': 'business' if
|
|
1159
|
-
channel = 'orders-algo' if
|
|
1527
|
+
await self.authenticate({'access': 'business' if isTrigger else 'private'})
|
|
1528
|
+
channel = 'orders-algo' if isTrigger else 'orders'
|
|
1160
1529
|
messageHash = channel + '::myTrades'
|
|
1161
1530
|
market = None
|
|
1162
1531
|
if symbol is not None:
|
|
@@ -1182,9 +1551,13 @@ class okx(ccxt.async_support.okx):
|
|
|
1182
1551
|
|
|
1183
1552
|
async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
|
|
1184
1553
|
"""
|
|
1185
|
-
|
|
1554
|
+
|
|
1555
|
+
https://www.okx.com/docs-v5/en/#trading-account-websocket-positions-channel
|
|
1556
|
+
|
|
1186
1557
|
watch all open positions
|
|
1187
1558
|
:param str[]|None symbols: list of unified market symbols
|
|
1559
|
+
@param since
|
|
1560
|
+
@param limit
|
|
1188
1561
|
:param dict params: extra parameters specific to the exchange API endpoint
|
|
1189
1562
|
:returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
|
|
1190
1563
|
"""
|
|
@@ -1201,7 +1574,7 @@ class okx(ccxt.async_support.okx):
|
|
|
1201
1574
|
'channel': 'positions',
|
|
1202
1575
|
'instType': 'ANY',
|
|
1203
1576
|
}
|
|
1204
|
-
args = [arg]
|
|
1577
|
+
args = [self.extend(arg, params)]
|
|
1205
1578
|
nonSymbolRequest: dict = {
|
|
1206
1579
|
'op': 'subscribe',
|
|
1207
1580
|
'args': args,
|
|
@@ -1282,6 +1655,9 @@ class okx(ccxt.async_support.okx):
|
|
|
1282
1655
|
# }
|
|
1283
1656
|
#
|
|
1284
1657
|
arg = self.safe_value(message, 'arg', {})
|
|
1658
|
+
marketId = self.safe_string(arg, 'instId')
|
|
1659
|
+
market = self.safe_market(marketId, None, '-')
|
|
1660
|
+
symbol = market['symbol']
|
|
1285
1661
|
channel = self.safe_string(arg, 'channel', '')
|
|
1286
1662
|
data = self.safe_value(message, 'data', [])
|
|
1287
1663
|
if self.positions is None:
|
|
@@ -1291,28 +1667,30 @@ class okx(ccxt.async_support.okx):
|
|
|
1291
1667
|
for i in range(0, len(data)):
|
|
1292
1668
|
rawPosition = data[i]
|
|
1293
1669
|
position = self.parse_position(rawPosition)
|
|
1670
|
+
if position['contracts'] == 0:
|
|
1671
|
+
position['side'] = 'long'
|
|
1672
|
+
shortPosition = self.clone(position)
|
|
1673
|
+
shortPosition['side'] = 'short'
|
|
1674
|
+
cache.append(shortPosition)
|
|
1675
|
+
newPositions.append(shortPosition)
|
|
1294
1676
|
newPositions.append(position)
|
|
1295
1677
|
cache.append(position)
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
messageHash =
|
|
1299
|
-
|
|
1300
|
-
symbolsString = parts[1]
|
|
1301
|
-
symbols = symbolsString.split(',')
|
|
1302
|
-
positions = self.filter_by_array(newPositions, 'symbol', symbols, False)
|
|
1303
|
-
if not self.is_empty(positions):
|
|
1304
|
-
client.resolve(positions, messageHash)
|
|
1305
|
-
client.resolve(newPositions, channel)
|
|
1678
|
+
messageHash = channel
|
|
1679
|
+
if symbol is not None:
|
|
1680
|
+
messageHash = channel + '::' + symbol
|
|
1681
|
+
client.resolve(newPositions, messageHash)
|
|
1306
1682
|
|
|
1307
1683
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
1308
1684
|
"""
|
|
1309
1685
|
watches information on multiple orders made by the user
|
|
1310
|
-
|
|
1686
|
+
|
|
1687
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-order-channel
|
|
1688
|
+
|
|
1311
1689
|
:param str [symbol]: unified market symbol of the market the orders were made in
|
|
1312
1690
|
:param int [since]: the earliest time in ms to fetch orders for
|
|
1313
1691
|
:param int [limit]: the maximum number of order structures to retrieve
|
|
1314
1692
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1315
|
-
:param bool [params.
|
|
1693
|
+
:param bool [params.trigger]: True if fetching trigger or conditional orders
|
|
1316
1694
|
:param str [params.type]: 'spot', 'swap', 'future', 'option', 'ANY', 'SPOT', 'MARGIN', 'SWAP', 'FUTURES' or 'OPTION'
|
|
1317
1695
|
:param str [params.marginMode]: 'cross' or 'isolated', for automatically setting the type to spot margin
|
|
1318
1696
|
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
@@ -1320,10 +1698,10 @@ class okx(ccxt.async_support.okx):
|
|
|
1320
1698
|
type = None
|
|
1321
1699
|
# By default, receive order updates from any instrument type
|
|
1322
1700
|
type, params = self.handle_option_and_params(params, 'watchOrders', 'type', 'ANY')
|
|
1323
|
-
|
|
1701
|
+
isTrigger = self.safe_value_2(params, 'stop', 'trigger', False)
|
|
1324
1702
|
params = self.omit(params, ['stop', 'trigger'])
|
|
1325
1703
|
await self.load_markets()
|
|
1326
|
-
await self.authenticate({'access': 'business' if
|
|
1704
|
+
await self.authenticate({'access': 'business' if isTrigger else 'private'})
|
|
1327
1705
|
market = None
|
|
1328
1706
|
if symbol is not None:
|
|
1329
1707
|
market = self.market(symbol)
|
|
@@ -1340,7 +1718,7 @@ class okx(ccxt.async_support.okx):
|
|
|
1340
1718
|
request: dict = {
|
|
1341
1719
|
'instType': uppercaseType,
|
|
1342
1720
|
}
|
|
1343
|
-
channel = 'orders-algo' if
|
|
1721
|
+
channel = 'orders-algo' if isTrigger else 'orders'
|
|
1344
1722
|
orders = await self.subscribe('private', channel, channel, symbol, self.extend(request, params))
|
|
1345
1723
|
if self.newUpdates:
|
|
1346
1724
|
limit = orders.getLimit(symbol, limit)
|
|
@@ -1510,17 +1888,25 @@ class okx(ccxt.async_support.okx):
|
|
|
1510
1888
|
tradeSymbols = list(symbols.keys())
|
|
1511
1889
|
for i in range(0, len(tradeSymbols)):
|
|
1512
1890
|
symbolMessageHash = messageHash + '::' + tradeSymbols[i]
|
|
1513
|
-
client.resolve(self.
|
|
1891
|
+
client.resolve(self.myTrades, symbolMessageHash)
|
|
1892
|
+
|
|
1893
|
+
def request_id(self):
|
|
1894
|
+
ts = str(self.milliseconds())
|
|
1895
|
+
randomNumber = self.rand_number(4)
|
|
1896
|
+
randomPart = str(randomNumber)
|
|
1897
|
+
return ts + randomPart
|
|
1514
1898
|
|
|
1515
1899
|
async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
|
|
1516
1900
|
"""
|
|
1517
|
-
|
|
1901
|
+
|
|
1902
|
+
https://www.okx.com/docs-v5/en/#websocket-api-trade-place-order
|
|
1903
|
+
|
|
1518
1904
|
create a trade order
|
|
1519
1905
|
:param str symbol: unified symbol of the market to create an order in
|
|
1520
1906
|
:param str type: 'market' or 'limit'
|
|
1521
1907
|
:param str side: 'buy' or 'sell'
|
|
1522
1908
|
:param float amount: how much of currency you want to trade in units of base currency
|
|
1523
|
-
:param float|None [price]: the price at which the order is to be
|
|
1909
|
+
:param float|None [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
1524
1910
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1525
1911
|
:param boolean params['test']: test order, default False
|
|
1526
1912
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
@@ -1528,7 +1914,7 @@ class okx(ccxt.async_support.okx):
|
|
|
1528
1914
|
await self.load_markets()
|
|
1529
1915
|
await self.authenticate()
|
|
1530
1916
|
url = self.get_url('private', 'private')
|
|
1531
|
-
messageHash =
|
|
1917
|
+
messageHash = self.request_id()
|
|
1532
1918
|
op = None
|
|
1533
1919
|
op, params = self.handle_option_and_params(params, 'createOrderWs', 'op', 'batch-orders')
|
|
1534
1920
|
args = self.create_order_request(symbol, type, side, amount, price, params)
|
|
@@ -1571,7 +1957,7 @@ class okx(ccxt.async_support.okx):
|
|
|
1571
1957
|
if self.is_empty(args):
|
|
1572
1958
|
method = self.safe_string(message, 'op')
|
|
1573
1959
|
stringMsg = self.json(message)
|
|
1574
|
-
self.handle_errors(
|
|
1960
|
+
self.handle_errors(1, '', client.url, method, {}, stringMsg, message, {}, {})
|
|
1575
1961
|
orders = self.parse_orders(args, None, None, None)
|
|
1576
1962
|
first = self.safe_dict(orders, 0, {})
|
|
1577
1963
|
client.resolve(first, messageHash)
|
|
@@ -1579,21 +1965,23 @@ class okx(ccxt.async_support.okx):
|
|
|
1579
1965
|
async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}) -> Order:
|
|
1580
1966
|
"""
|
|
1581
1967
|
edit a trade order
|
|
1582
|
-
|
|
1583
|
-
|
|
1968
|
+
|
|
1969
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-order
|
|
1970
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-multiple-orders
|
|
1971
|
+
|
|
1584
1972
|
:param str id: order id
|
|
1585
1973
|
:param str symbol: unified symbol of the market to create an order in
|
|
1586
1974
|
:param str type: 'market' or 'limit'
|
|
1587
1975
|
:param str side: 'buy' or 'sell'
|
|
1588
1976
|
:param float amount: how much of the currency you want to trade in units of the base currency
|
|
1589
|
-
:param float|None [price]: the price at which the order is to be
|
|
1977
|
+
:param float|None [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
1590
1978
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1591
1979
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
1592
1980
|
"""
|
|
1593
1981
|
await self.load_markets()
|
|
1594
1982
|
await self.authenticate()
|
|
1595
1983
|
url = self.get_url('private', 'private')
|
|
1596
|
-
messageHash =
|
|
1984
|
+
messageHash = self.request_id()
|
|
1597
1985
|
op = None
|
|
1598
1986
|
op, params = self.handle_option_and_params(params, 'editOrderWs', 'op', 'amend-order')
|
|
1599
1987
|
args = self.edit_order_request(id, symbol, type, side, amount, price, params)
|
|
@@ -1606,7 +1994,9 @@ class okx(ccxt.async_support.okx):
|
|
|
1606
1994
|
|
|
1607
1995
|
async def cancel_order_ws(self, id: str, symbol: Str = None, params={}) -> Order:
|
|
1608
1996
|
"""
|
|
1609
|
-
|
|
1997
|
+
|
|
1998
|
+
https://okx-docs.github.io/apidocs/websocket_api/en/#cancel-order-trade
|
|
1999
|
+
|
|
1610
2000
|
cancel multiple orders
|
|
1611
2001
|
:param str id: order id
|
|
1612
2002
|
:param str symbol: unified market symbol, default is None
|
|
@@ -1619,7 +2009,7 @@ class okx(ccxt.async_support.okx):
|
|
|
1619
2009
|
await self.load_markets()
|
|
1620
2010
|
await self.authenticate()
|
|
1621
2011
|
url = self.get_url('private', 'private')
|
|
1622
|
-
messageHash =
|
|
2012
|
+
messageHash = self.request_id()
|
|
1623
2013
|
clientOrderId = self.safe_string_2(params, 'clOrdId', 'clientOrderId')
|
|
1624
2014
|
params = self.omit(params, ['clientOrderId', 'clOrdId'])
|
|
1625
2015
|
arg: dict = {
|
|
@@ -1638,14 +2028,16 @@ class okx(ccxt.async_support.okx):
|
|
|
1638
2028
|
|
|
1639
2029
|
async def cancel_orders_ws(self, ids: List[str], symbol: Str = None, params={}):
|
|
1640
2030
|
"""
|
|
1641
|
-
|
|
2031
|
+
|
|
2032
|
+
https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-mass-cancel-order
|
|
2033
|
+
|
|
1642
2034
|
cancel multiple orders
|
|
1643
2035
|
:param str[] ids: order ids
|
|
1644
2036
|
:param str symbol: unified market symbol, default is None
|
|
1645
2037
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1646
2038
|
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
1647
2039
|
"""
|
|
1648
|
-
idsLength = len(ids)
|
|
2040
|
+
idsLength: number = len(ids)
|
|
1649
2041
|
if idsLength > 20:
|
|
1650
2042
|
raise BadRequest(self.id + ' cancelOrdersWs() accepts up to 20 ids at a time')
|
|
1651
2043
|
if symbol is None:
|
|
@@ -1653,7 +2045,7 @@ class okx(ccxt.async_support.okx):
|
|
|
1653
2045
|
await self.load_markets()
|
|
1654
2046
|
await self.authenticate()
|
|
1655
2047
|
url = self.get_url('private', 'private')
|
|
1656
|
-
messageHash =
|
|
2048
|
+
messageHash = self.request_id()
|
|
1657
2049
|
args = []
|
|
1658
2050
|
for i in range(0, idsLength):
|
|
1659
2051
|
arg: dict = {
|
|
@@ -1670,7 +2062,9 @@ class okx(ccxt.async_support.okx):
|
|
|
1670
2062
|
|
|
1671
2063
|
async def cancel_all_orders_ws(self, symbol: Str = None, params={}):
|
|
1672
2064
|
"""
|
|
1673
|
-
|
|
2065
|
+
|
|
2066
|
+
https://docs.okx.com/websockets/#message-cancelAll
|
|
2067
|
+
|
|
1674
2068
|
cancel all open orders of a type. Only applicable to Option in Portfolio Margin mode, and MMP privilege is required.
|
|
1675
2069
|
:param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
|
|
1676
2070
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -1682,9 +2076,9 @@ class okx(ccxt.async_support.okx):
|
|
|
1682
2076
|
await self.authenticate()
|
|
1683
2077
|
market = self.market(symbol)
|
|
1684
2078
|
if market['type'] != 'option':
|
|
1685
|
-
raise BadRequest(self.id + 'cancelAllOrdersWs is only applicable to Option in Portfolio Margin mode, and MMP privilege is required.')
|
|
2079
|
+
raise BadRequest(self.id + ' cancelAllOrdersWs is only applicable to Option in Portfolio Margin mode, and MMP privilege is required.')
|
|
1686
2080
|
url = self.get_url('private', 'private')
|
|
1687
|
-
messageHash =
|
|
2081
|
+
messageHash = self.request_id()
|
|
1688
2082
|
request: dict = {
|
|
1689
2083
|
'id': messageHash,
|
|
1690
2084
|
'op': 'mass-cancel',
|
|
@@ -1728,33 +2122,58 @@ class okx(ccxt.async_support.okx):
|
|
|
1728
2122
|
future = self.safe_value(client.futures, 'authenticated')
|
|
1729
2123
|
future.resolve(True)
|
|
1730
2124
|
|
|
1731
|
-
def ping(self, client):
|
|
1732
|
-
#
|
|
1733
|
-
#
|
|
2125
|
+
def ping(self, client: Client):
|
|
2126
|
+
# OKX does not support the built-in WebSocket protocol-level ping-pong.
|
|
2127
|
+
# Instead, it requires a custom text-based ping-pong mechanism.
|
|
1734
2128
|
return 'ping'
|
|
1735
2129
|
|
|
1736
2130
|
def handle_pong(self, client: Client, message):
|
|
1737
2131
|
client.lastPong = self.milliseconds()
|
|
1738
2132
|
return message
|
|
1739
2133
|
|
|
1740
|
-
def handle_error_message(self, client: Client, message):
|
|
2134
|
+
def handle_error_message(self, client: Client, message) -> Bool:
|
|
1741
2135
|
#
|
|
1742
2136
|
# {event: 'error', msg: "Illegal request: {"op":"subscribe","args":["spot/ticker:BTC-USDT"]}", code: "60012"}
|
|
1743
2137
|
# {event: 'error", msg: "channel:ticker,instId:BTC-USDT doesn"t exist", code: "60018"}
|
|
2138
|
+
# {"event":"error","msg":"Illegal request: {\\"id\\":\\"17321173472466905\\",\\"op\\":\\"amend-order\\",\\"args\\":[{\\"instId\\":\\"ETH-USDC\\",\\"ordId\\":\\"2000345622407479296\\",\\"newSz\\":\\"0.050857\\",\\"newPx\\":\\"2949.4\\",\\"postOnly\\":true}],\\"postOnly\\":true}","code":"60012","connId":"0808af6c"}
|
|
1744
2139
|
#
|
|
1745
2140
|
errorCode = self.safe_string(message, 'code')
|
|
1746
2141
|
try:
|
|
1747
2142
|
if errorCode and errorCode != '0':
|
|
1748
2143
|
feedback = self.id + ' ' + self.json(message)
|
|
1749
|
-
|
|
2144
|
+
if errorCode != '1':
|
|
2145
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
|
|
1750
2146
|
messageString = self.safe_value(message, 'msg')
|
|
1751
2147
|
if messageString is not None:
|
|
1752
2148
|
self.throw_broadly_matched_exception(self.exceptions['broad'], messageString, feedback)
|
|
2149
|
+
else:
|
|
2150
|
+
data = self.safe_list(message, 'data', [])
|
|
2151
|
+
for i in range(0, len(data)):
|
|
2152
|
+
d = data[i]
|
|
2153
|
+
errorCode = self.safe_string(d, 'sCode')
|
|
2154
|
+
if errorCode is not None:
|
|
2155
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
|
|
2156
|
+
messageString = self.safe_value(message, 'sMsg')
|
|
2157
|
+
if messageString is not None:
|
|
2158
|
+
self.throw_broadly_matched_exception(self.exceptions['broad'], messageString, feedback)
|
|
1753
2159
|
raise ExchangeError(feedback)
|
|
1754
2160
|
except Exception as e:
|
|
2161
|
+
# if the message contains an id, it means it is a response to a request
|
|
2162
|
+
# so we only reject that promise, instead of deleting all futures, destroying the authentication future
|
|
2163
|
+
id = self.safe_string(message, 'id')
|
|
2164
|
+
if id is None:
|
|
2165
|
+
# try to parse it from the stringified json inside msg
|
|
2166
|
+
msg = self.safe_string(message, 'msg')
|
|
2167
|
+
if msg is not None and msg.startswith('Illegal request: {'):
|
|
2168
|
+
stringifiedJson = msg.replace('Illegal request: ', '')
|
|
2169
|
+
parsedJson = self.parse_json(stringifiedJson)
|
|
2170
|
+
id = self.safe_string(parsedJson, 'id')
|
|
2171
|
+
if id is not None:
|
|
2172
|
+
client.reject(e, id)
|
|
2173
|
+
return False
|
|
1755
2174
|
client.reject(e)
|
|
1756
2175
|
return False
|
|
1757
|
-
return
|
|
2176
|
+
return True
|
|
1758
2177
|
|
|
1759
2178
|
def handle_message(self, client: Client, message):
|
|
1760
2179
|
if not self.handle_error_message(client, message):
|
|
@@ -1810,6 +2229,7 @@ class okx(ccxt.async_support.okx):
|
|
|
1810
2229
|
# 'book': 'handleOrderBook',
|
|
1811
2230
|
'login': self.handle_authenticate,
|
|
1812
2231
|
'subscribe': self.handle_subscription_status,
|
|
2232
|
+
'unsubscribe': self.handle_unsubscription,
|
|
1813
2233
|
'order': self.handle_place_orders,
|
|
1814
2234
|
'batch-orders': self.handle_place_orders,
|
|
1815
2235
|
'amend-order': self.handle_place_orders,
|
|
@@ -1830,6 +2250,7 @@ class okx(ccxt.async_support.okx):
|
|
|
1830
2250
|
'books50-l2-tbt': self.handle_order_book, # only users who're VIP4 and above can subscribe, identity verification required before subscription
|
|
1831
2251
|
'books-l2-tbt': self.handle_order_book, # only users who're VIP5 and above can subscribe, identity verification required before subscription
|
|
1832
2252
|
'tickers': self.handle_ticker,
|
|
2253
|
+
'mark-price': self.handle_ticker,
|
|
1833
2254
|
'positions': self.handle_positions,
|
|
1834
2255
|
'index-tickers': self.handle_ticker,
|
|
1835
2256
|
'sprd-tickers': self.handle_ticker,
|
|
@@ -1849,3 +2270,57 @@ class okx(ccxt.async_support.okx):
|
|
|
1849
2270
|
self.handle_ohlcv(client, message)
|
|
1850
2271
|
else:
|
|
1851
2272
|
method(client, message)
|
|
2273
|
+
|
|
2274
|
+
def handle_un_subscription_trades(self, client: Client, symbol: str):
|
|
2275
|
+
subMessageHash = 'trades:' + symbol
|
|
2276
|
+
messageHash = 'unsubscribe:trades:' + symbol
|
|
2277
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
|
2278
|
+
if symbol in self.trades:
|
|
2279
|
+
del self.trades[symbol]
|
|
2280
|
+
|
|
2281
|
+
def handle_unsubscription_order_book(self, client: Client, symbol: str, channel: str):
|
|
2282
|
+
subMessageHash = channel + ':' + symbol
|
|
2283
|
+
messageHash = 'unsubscribe:orderbook:' + symbol
|
|
2284
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
|
2285
|
+
if symbol in self.orderbooks:
|
|
2286
|
+
del self.orderbooks[symbol]
|
|
2287
|
+
|
|
2288
|
+
def handle_unsubscription_ohlcv(self, client: Client, symbol: str, channel: str):
|
|
2289
|
+
tf = channel.replace('candle', '')
|
|
2290
|
+
timeframe = self.find_timeframe(tf)
|
|
2291
|
+
subMessageHash = 'multi:' + channel + ':' + symbol
|
|
2292
|
+
messageHash = 'unsubscribe:' + subMessageHash
|
|
2293
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
|
2294
|
+
if timeframe in self.ohlcvs[symbol]:
|
|
2295
|
+
del self.ohlcvs[symbol][timeframe]
|
|
2296
|
+
|
|
2297
|
+
def handle_unsubscription_ticker(self, client: Client, symbol: str, channel):
|
|
2298
|
+
subMessageHash = channel + '::' + symbol
|
|
2299
|
+
messageHash = 'unsubscribe:ticker:' + symbol
|
|
2300
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
|
2301
|
+
if symbol in self.tickers:
|
|
2302
|
+
del self.tickers[symbol]
|
|
2303
|
+
|
|
2304
|
+
def handle_unsubscription(self, client: Client, message):
|
|
2305
|
+
#
|
|
2306
|
+
# {
|
|
2307
|
+
# "event": "unsubscribe",
|
|
2308
|
+
# "arg": {
|
|
2309
|
+
# "channel": "tickers",
|
|
2310
|
+
# "instId": "LTC-USD-200327"
|
|
2311
|
+
# },
|
|
2312
|
+
# "connId": "a4d3ae55"
|
|
2313
|
+
# }
|
|
2314
|
+
# arg might be an array or list
|
|
2315
|
+
arg = self.safe_dict(message, 'arg', {})
|
|
2316
|
+
channel = self.safe_string(arg, 'channel', '')
|
|
2317
|
+
marketId = self.safe_string(arg, 'instId')
|
|
2318
|
+
symbol = self.safe_symbol(marketId)
|
|
2319
|
+
if channel == 'trades':
|
|
2320
|
+
self.handle_un_subscription_trades(client, symbol)
|
|
2321
|
+
elif channel.startswith('bbo') or channel.startswith('book'):
|
|
2322
|
+
self.handle_unsubscription_order_book(client, symbol, channel)
|
|
2323
|
+
elif channel.find('tickers') > -1:
|
|
2324
|
+
self.handle_unsubscription_ticker(client, symbol, channel)
|
|
2325
|
+
elif channel.startswith('candle'):
|
|
2326
|
+
self.handle_unsubscription_ohlcv(client, symbol, channel)
|