ccxt-ir 4.3.46.0.2__py2.py3-none-any.whl → 4.5.0__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 +9 -9
- 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 +7 -7
- 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 +10 -10
- ccxt/async_support/afratether.py +9 -9
- 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 +31 -37
- 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 +25 -24
- 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 +30 -27
- ccxt/async_support/sarmayex.py +9 -9
- ccxt/async_support/sarrafex.py +13 -13
- ccxt/async_support/tabdeal.py +14 -13
- 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 +29 -35
- 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 +22 -21
- 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 +28 -25
- 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 +12 -11
- 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.2.dist-info → ccxt_ir-4.5.0.dist-info}/METADATA +225 -73
- ccxt_ir-4.5.0.dist-info/RECORD +743 -0
- {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/WHEEL +1 -1
- 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.2.dist-info/RECORD +0 -772
- /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
- {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info/licenses}/LICENSE.txt +0 -0
- {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/top_level.txt +0 -0
ccxt/pro/bybit.py
CHANGED
|
@@ -7,18 +7,19 @@ import ccxt.async_support
|
|
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
|
|
8
8
|
import asyncio
|
|
9
9
|
import hashlib
|
|
10
|
-
from ccxt.base.types import Balances, Int, Liquidation, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade
|
|
10
|
+
from ccxt.base.types import Any, Balances, Bool, Int, Liquidation, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade
|
|
11
11
|
from ccxt.async_support.base.ws.client import Client
|
|
12
12
|
from typing import List
|
|
13
13
|
from ccxt.base.errors import ExchangeError
|
|
14
14
|
from ccxt.base.errors import AuthenticationError
|
|
15
15
|
from ccxt.base.errors import ArgumentsRequired
|
|
16
16
|
from ccxt.base.errors import BadRequest
|
|
17
|
+
from ccxt.base.errors import NotSupported
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class bybit(ccxt.async_support.bybit):
|
|
20
21
|
|
|
21
|
-
def describe(self):
|
|
22
|
+
def describe(self) -> Any:
|
|
22
23
|
return self.deep_extend(super(bybit, self).describe(), {
|
|
23
24
|
'has': {
|
|
24
25
|
'ws': True,
|
|
@@ -32,13 +33,14 @@ class bybit(ccxt.async_support.bybit):
|
|
|
32
33
|
'fetchTradesWs': False,
|
|
33
34
|
'fetchBalanceWs': False,
|
|
34
35
|
'watchBalance': True,
|
|
36
|
+
'watchBidsAsks': True,
|
|
35
37
|
'watchLiquidations': True,
|
|
36
38
|
'watchLiquidationsForSymbols': False,
|
|
37
39
|
'watchMyLiquidations': False,
|
|
38
40
|
'watchMyLiquidationsForSymbols': False,
|
|
39
41
|
'watchMyTrades': True,
|
|
40
42
|
'watchOHLCV': True,
|
|
41
|
-
'watchOHLCVForSymbols':
|
|
43
|
+
'watchOHLCVForSymbols': True,
|
|
42
44
|
'watchOrderBook': True,
|
|
43
45
|
'watchOrderBookForSymbols': True,
|
|
44
46
|
'watchOrders': True,
|
|
@@ -47,6 +49,17 @@ class bybit(ccxt.async_support.bybit):
|
|
|
47
49
|
'watchTrades': True,
|
|
48
50
|
'watchPositions': True,
|
|
49
51
|
'watchTradesForSymbols': True,
|
|
52
|
+
'unWatchTicker': True,
|
|
53
|
+
'unWatchTickers': True,
|
|
54
|
+
'unWatchOHLCV': True,
|
|
55
|
+
'unWatchOHLCVForSymbols': True,
|
|
56
|
+
'unWatchOrderBook': True,
|
|
57
|
+
'unWatchOrderBookForSymbols': True,
|
|
58
|
+
'unWatchTrades': True,
|
|
59
|
+
'unWatchTradesForSymbols': True,
|
|
60
|
+
'unWatchMyTrades': True,
|
|
61
|
+
'unWatchOrders': True,
|
|
62
|
+
'unWatchPositions': True,
|
|
50
63
|
},
|
|
51
64
|
'urls': {
|
|
52
65
|
'api': {
|
|
@@ -87,6 +100,25 @@ class bybit(ccxt.async_support.bybit):
|
|
|
87
100
|
},
|
|
88
101
|
},
|
|
89
102
|
},
|
|
103
|
+
'demotrading': {
|
|
104
|
+
'ws': {
|
|
105
|
+
'public': {
|
|
106
|
+
'spot': 'wss://stream.{hostname}/v5/public/spot',
|
|
107
|
+
'inverse': 'wss://stream.{hostname}/v5/public/inverse',
|
|
108
|
+
'option': 'wss://stream.{hostname}/v5/public/option',
|
|
109
|
+
'linear': 'wss://stream.{hostname}/v5/public/linear',
|
|
110
|
+
},
|
|
111
|
+
'private': {
|
|
112
|
+
'spot': {
|
|
113
|
+
'unified': 'wss://stream-demo.{hostname}/v5/private',
|
|
114
|
+
'nonUnified': 'wss://stream-demo.{hostname}/spot/private/v3',
|
|
115
|
+
},
|
|
116
|
+
'contract': 'wss://stream-demo.{hostname}/v5/private',
|
|
117
|
+
'usdc': 'wss://stream-demo.{hostname}/trade/option/usdc/private/v1',
|
|
118
|
+
'trade': 'wss://stream-demo.bybit.com/v5/trade',
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
90
122
|
},
|
|
91
123
|
'options': {
|
|
92
124
|
'watchTicker': {
|
|
@@ -96,6 +128,12 @@ class bybit(ccxt.async_support.bybit):
|
|
|
96
128
|
'fetchPositionsSnapshot': True, # or False
|
|
97
129
|
'awaitPositionsSnapshot': True, # whether to wait for the positions snapshot before providing updates
|
|
98
130
|
},
|
|
131
|
+
'watchMyTrades': {
|
|
132
|
+
# filter execType: https://bybit-exchange.github.io/docs/api-explorer/v5/position/execution
|
|
133
|
+
'filterExecTypes': [
|
|
134
|
+
'Trade', 'AdlTrade', 'BustTrade', 'Settle',
|
|
135
|
+
],
|
|
136
|
+
},
|
|
99
137
|
'spot': {
|
|
100
138
|
'timeframes': {
|
|
101
139
|
'1m': '1m',
|
|
@@ -142,7 +180,7 @@ class bybit(ccxt.async_support.bybit):
|
|
|
142
180
|
self.options['requestId'] = requestId
|
|
143
181
|
return requestId
|
|
144
182
|
|
|
145
|
-
def get_url_by_market_type(self, symbol: Str = None, isPrivate=False, method: Str = None, params={}):
|
|
183
|
+
async def get_url_by_market_type(self, symbol: Str = None, isPrivate=False, method: Str = None, params={}):
|
|
146
184
|
accessibility = 'private' if isPrivate else 'public'
|
|
147
185
|
isUsdcSettled = None
|
|
148
186
|
isSpot = None
|
|
@@ -160,11 +198,17 @@ class bybit(ccxt.async_support.bybit):
|
|
|
160
198
|
isUsdcSettled = (defaultSettle == 'USDC')
|
|
161
199
|
isSpot = (type == 'spot')
|
|
162
200
|
if isPrivate:
|
|
163
|
-
|
|
201
|
+
unified = await self.isUnifiedEnabled()
|
|
202
|
+
isUnifiedMargin = self.safe_bool(unified, 0, False)
|
|
203
|
+
isUnifiedAccount = self.safe_bool(unified, 1, False)
|
|
204
|
+
if isUsdcSettled and not isUnifiedMargin and not isUnifiedAccount:
|
|
205
|
+
url = url[accessibility]['usdc']
|
|
206
|
+
else:
|
|
207
|
+
url = url[accessibility]['contract']
|
|
164
208
|
else:
|
|
165
209
|
if isSpot:
|
|
166
210
|
url = url[accessibility]['spot']
|
|
167
|
-
elif type == 'swap':
|
|
211
|
+
elif (type == 'swap') or (type == 'future'):
|
|
168
212
|
subType = None
|
|
169
213
|
subType, params = self.handle_sub_type_and_params(method, market, params, 'linear')
|
|
170
214
|
url = url[accessibility][subType]
|
|
@@ -181,13 +225,15 @@ class bybit(ccxt.async_support.bybit):
|
|
|
181
225
|
async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
|
182
226
|
"""
|
|
183
227
|
create a trade order
|
|
184
|
-
|
|
185
|
-
|
|
228
|
+
|
|
229
|
+
https://bybit-exchange.github.io/docs/v5/order/create-order
|
|
230
|
+
https://bybit-exchange.github.io/docs/v5/websocket/trade/guideline#createamendcancel-order
|
|
231
|
+
|
|
186
232
|
:param str symbol: unified symbol of the market to create an order in
|
|
187
233
|
:param str type: 'market' or 'limit'
|
|
188
234
|
:param str side: 'buy' or 'sell'
|
|
189
235
|
:param float amount: how much of currency you want to trade in units of base currency
|
|
190
|
-
:param float [price]: the price at which the order is to be
|
|
236
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
191
237
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
192
238
|
:param str [params.timeInForce]: "GTC", "IOC", "FOK"
|
|
193
239
|
:param bool [params.postOnly]: True or False whether the order is post-only
|
|
@@ -229,14 +275,16 @@ class bybit(ccxt.async_support.bybit):
|
|
|
229
275
|
async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
|
230
276
|
"""
|
|
231
277
|
edit a trade order
|
|
232
|
-
|
|
233
|
-
|
|
278
|
+
|
|
279
|
+
https://bybit-exchange.github.io/docs/v5/order/amend-order
|
|
280
|
+
https://bybit-exchange.github.io/docs/v5/websocket/trade/guideline#createamendcancel-order
|
|
281
|
+
|
|
234
282
|
:param str id: cancel order id
|
|
235
283
|
:param str symbol: unified symbol of the market to create an order in
|
|
236
284
|
:param str type: 'market' or 'limit'
|
|
237
285
|
:param str side: 'buy' or 'sell'
|
|
238
286
|
:param float amount: how much of currency you want to trade in units of base currency
|
|
239
|
-
:param float price: the price at which the order is to be
|
|
287
|
+
:param float price: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
240
288
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
241
289
|
:param float [params.triggerPrice]: The price that a trigger order is triggered at
|
|
242
290
|
:param float [params.stopLossPrice]: The price that a stop loss order is triggered at
|
|
@@ -271,12 +319,14 @@ class bybit(ccxt.async_support.bybit):
|
|
|
271
319
|
async def cancel_order_ws(self, id: str, symbol: Str = None, params={}):
|
|
272
320
|
"""
|
|
273
321
|
cancels an open order
|
|
274
|
-
|
|
275
|
-
|
|
322
|
+
|
|
323
|
+
https://bybit-exchange.github.io/docs/v5/order/cancel-order
|
|
324
|
+
https://bybit-exchange.github.io/docs/v5/websocket/trade/guideline#createamendcancel-order
|
|
325
|
+
|
|
276
326
|
:param str id: order id
|
|
277
327
|
:param str symbol: unified symbol of the market the order was made in
|
|
278
328
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
279
|
-
:param boolean [params.
|
|
329
|
+
:param boolean [params.trigger]: *spot only* whether the order is a trigger order
|
|
280
330
|
:param str [params.orderFilter]: *spot only* 'Order' or 'StopOrder' or 'tpslOrder'
|
|
281
331
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
282
332
|
"""
|
|
@@ -303,8 +353,10 @@ class bybit(ccxt.async_support.bybit):
|
|
|
303
353
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
|
304
354
|
"""
|
|
305
355
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
306
|
-
|
|
307
|
-
|
|
356
|
+
|
|
357
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/ticker
|
|
358
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-ticker
|
|
359
|
+
|
|
308
360
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
|
309
361
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
310
362
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
@@ -313,7 +365,7 @@ class bybit(ccxt.async_support.bybit):
|
|
|
313
365
|
market = self.market(symbol)
|
|
314
366
|
symbol = market['symbol']
|
|
315
367
|
messageHash = 'ticker:' + symbol
|
|
316
|
-
url = self.get_url_by_market_type(symbol, False, 'watchTicker', params)
|
|
368
|
+
url = await self.get_url_by_market_type(symbol, False, 'watchTicker', params)
|
|
317
369
|
params = self.clean_params(params)
|
|
318
370
|
options = self.safe_value(self.options, 'watchTicker', {})
|
|
319
371
|
topic = self.safe_string(options, 'name', 'tickers')
|
|
@@ -326,8 +378,10 @@ class bybit(ccxt.async_support.bybit):
|
|
|
326
378
|
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
|
327
379
|
"""
|
|
328
380
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
329
|
-
|
|
330
|
-
|
|
381
|
+
|
|
382
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/ticker
|
|
383
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-ticker
|
|
384
|
+
|
|
331
385
|
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
332
386
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
333
387
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
@@ -335,7 +389,7 @@ class bybit(ccxt.async_support.bybit):
|
|
|
335
389
|
await self.load_markets()
|
|
336
390
|
symbols = self.market_symbols(symbols, None, False)
|
|
337
391
|
messageHashes = []
|
|
338
|
-
url = self.get_url_by_market_type(symbols[0], False, 'watchTickers', params)
|
|
392
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'watchTickers', params)
|
|
339
393
|
params = self.clean_params(params)
|
|
340
394
|
options = self.safe_value(self.options, 'watchTickers', {})
|
|
341
395
|
topic = self.safe_string(options, 'name', 'tickers')
|
|
@@ -352,6 +406,48 @@ class bybit(ccxt.async_support.bybit):
|
|
|
352
406
|
return result
|
|
353
407
|
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
|
354
408
|
|
|
409
|
+
async def un_watch_tickers(self, symbols: Strings = None, params={}) -> Any:
|
|
410
|
+
"""
|
|
411
|
+
unWatches a price ticker
|
|
412
|
+
|
|
413
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/ticker
|
|
414
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-ticker
|
|
415
|
+
|
|
416
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
417
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
418
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
419
|
+
"""
|
|
420
|
+
await self.load_markets()
|
|
421
|
+
symbols = self.market_symbols(symbols, None, False)
|
|
422
|
+
options = self.safe_value(self.options, 'watchTickers', {})
|
|
423
|
+
topic = self.safe_string(options, 'name', 'tickers')
|
|
424
|
+
messageHashes = []
|
|
425
|
+
subMessageHashes = []
|
|
426
|
+
marketIds = self.market_ids(symbols)
|
|
427
|
+
topics = []
|
|
428
|
+
for i in range(0, len(marketIds)):
|
|
429
|
+
marketId = marketIds[i]
|
|
430
|
+
symbol = symbols[i]
|
|
431
|
+
topics.append(topic + '.' + marketId)
|
|
432
|
+
subMessageHashes.append('ticker:' + symbol)
|
|
433
|
+
messageHashes.append('unsubscribe:ticker:' + symbol)
|
|
434
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'watchTickers', params)
|
|
435
|
+
return await self.un_watch_topics(url, 'ticker', symbols, messageHashes, subMessageHashes, topics, params)
|
|
436
|
+
|
|
437
|
+
async def un_watch_ticker(self, symbols: str, params={}) -> Any:
|
|
438
|
+
"""
|
|
439
|
+
unWatches a price ticker
|
|
440
|
+
|
|
441
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/ticker
|
|
442
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-ticker
|
|
443
|
+
|
|
444
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
445
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
446
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
447
|
+
"""
|
|
448
|
+
await self.load_markets()
|
|
449
|
+
return await self.un_watch_tickers([symbols], params)
|
|
450
|
+
|
|
355
451
|
def handle_ticker(self, client: Client, message):
|
|
356
452
|
#
|
|
357
453
|
# linear
|
|
@@ -495,11 +591,57 @@ class bybit(ccxt.async_support.bybit):
|
|
|
495
591
|
messageHash = 'ticker:' + symbol
|
|
496
592
|
client.resolve(self.tickers[symbol], messageHash)
|
|
497
593
|
|
|
594
|
+
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
|
595
|
+
"""
|
|
596
|
+
watches best bid & ask for symbols
|
|
597
|
+
|
|
598
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
|
|
599
|
+
|
|
600
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
601
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
602
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
603
|
+
"""
|
|
604
|
+
await self.load_markets()
|
|
605
|
+
symbols = self.market_symbols(symbols, None, False)
|
|
606
|
+
messageHashes = []
|
|
607
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'watchBidsAsks', params)
|
|
608
|
+
params = self.clean_params(params)
|
|
609
|
+
marketIds = self.market_ids(symbols)
|
|
610
|
+
topics = []
|
|
611
|
+
for i in range(0, len(marketIds)):
|
|
612
|
+
marketId = marketIds[i]
|
|
613
|
+
topic = 'orderbook.1.' + marketId
|
|
614
|
+
topics.append(topic)
|
|
615
|
+
messageHashes.append('bidask:' + symbols[i])
|
|
616
|
+
ticker = await self.watch_topics(url, messageHashes, topics, params)
|
|
617
|
+
if self.newUpdates:
|
|
618
|
+
return ticker
|
|
619
|
+
return self.filter_by_array(self.bidsasks, 'symbol', symbols)
|
|
620
|
+
|
|
621
|
+
def parse_ws_bid_ask(self, orderbook, market=None):
|
|
622
|
+
timestamp = self.safe_integer(orderbook, 'timestamp')
|
|
623
|
+
bids = self.sort_by(self.aggregate(orderbook['bids']), 0)
|
|
624
|
+
asks = self.sort_by(self.aggregate(orderbook['asks']), 0)
|
|
625
|
+
bestBid = self.safe_list(bids, 0, [])
|
|
626
|
+
bestAsk = self.safe_list(asks, 0, [])
|
|
627
|
+
return self.safe_ticker({
|
|
628
|
+
'symbol': market['symbol'],
|
|
629
|
+
'timestamp': timestamp,
|
|
630
|
+
'datetime': self.iso8601(timestamp),
|
|
631
|
+
'ask': self.safe_number(bestAsk, 0),
|
|
632
|
+
'askVolume': self.safe_number(bestAsk, 1),
|
|
633
|
+
'bid': self.safe_number(bestBid, 0),
|
|
634
|
+
'bidVolume': self.safe_number(bestBid, 1),
|
|
635
|
+
'info': orderbook,
|
|
636
|
+
}, market)
|
|
637
|
+
|
|
498
638
|
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
|
499
639
|
"""
|
|
500
640
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
501
|
-
|
|
502
|
-
|
|
641
|
+
|
|
642
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/kline
|
|
643
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
|
|
644
|
+
|
|
503
645
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
|
504
646
|
:param str timeframe: the length of time each candle represents
|
|
505
647
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
|
@@ -507,19 +649,93 @@ class bybit(ccxt.async_support.bybit):
|
|
|
507
649
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
508
650
|
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
|
509
651
|
"""
|
|
652
|
+
params['callerMethodName'] = 'watchOHLCV'
|
|
653
|
+
result = await self.watch_ohlcv_for_symbols([[symbol, timeframe]], since, limit, params)
|
|
654
|
+
return result[symbol][timeframe]
|
|
655
|
+
|
|
656
|
+
async def watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], since: Int = None, limit: Int = None, params={}):
|
|
657
|
+
"""
|
|
658
|
+
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
659
|
+
|
|
660
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/kline
|
|
661
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
|
|
662
|
+
|
|
663
|
+
:param str[][] symbolsAndTimeframes: array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
|
664
|
+
:param int [since]: timestamp in ms of the earliest candle to fetch
|
|
665
|
+
:param int [limit]: the maximum amount of candles to fetch
|
|
666
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
667
|
+
:returns dict: A list of candles ordered, open, high, low, close, volume
|
|
668
|
+
"""
|
|
510
669
|
await self.load_markets()
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
670
|
+
symbols = self.get_list_from_object_values(symbolsAndTimeframes, 0)
|
|
671
|
+
marketSymbols = self.market_symbols(symbols, None, False, True, True)
|
|
672
|
+
firstSymbol = marketSymbols[0]
|
|
673
|
+
url = await self.get_url_by_market_type(firstSymbol, False, 'watchOHLCVForSymbols', params)
|
|
674
|
+
rawHashes = []
|
|
675
|
+
messageHashes = []
|
|
676
|
+
for i in range(0, len(symbolsAndTimeframes)):
|
|
677
|
+
data = symbolsAndTimeframes[i]
|
|
678
|
+
symbolString = self.safe_string(data, 0)
|
|
679
|
+
market = self.market(symbolString)
|
|
680
|
+
symbolString = market['symbol']
|
|
681
|
+
unfiedTimeframe = self.safe_string(data, 1)
|
|
682
|
+
timeframeId = self.safe_string(self.timeframes, unfiedTimeframe, unfiedTimeframe)
|
|
683
|
+
rawHashes.append('kline.' + timeframeId + '.' + market['id'])
|
|
684
|
+
messageHashes.append('ohlcv::' + symbolString + '::' + unfiedTimeframe)
|
|
685
|
+
symbol, timeframe, stored = await self.watch_topics(url, messageHashes, rawHashes, params)
|
|
520
686
|
if self.newUpdates:
|
|
521
|
-
limit =
|
|
522
|
-
|
|
687
|
+
limit = stored.getLimit(symbol, limit)
|
|
688
|
+
filtered = self.filter_by_since_limit(stored, since, limit, 0, True)
|
|
689
|
+
return self.create_ohlcv_object(symbol, timeframe, filtered)
|
|
690
|
+
|
|
691
|
+
async def un_watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], params={}) -> Any:
|
|
692
|
+
"""
|
|
693
|
+
unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
694
|
+
|
|
695
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/kline
|
|
696
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
|
|
697
|
+
|
|
698
|
+
:param str[][] symbolsAndTimeframes: array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
|
699
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
700
|
+
:returns dict: A list of candles ordered, open, high, low, close, volume
|
|
701
|
+
"""
|
|
702
|
+
await self.load_markets()
|
|
703
|
+
symbols = self.get_list_from_object_values(symbolsAndTimeframes, 0)
|
|
704
|
+
marketSymbols = self.market_symbols(symbols, None, False, True, True)
|
|
705
|
+
firstSymbol = marketSymbols[0]
|
|
706
|
+
url = await self.get_url_by_market_type(firstSymbol, False, 'watchOHLCVForSymbols', params)
|
|
707
|
+
rawHashes = []
|
|
708
|
+
subMessageHashes = []
|
|
709
|
+
messageHashes = []
|
|
710
|
+
for i in range(0, len(symbolsAndTimeframes)):
|
|
711
|
+
data = symbolsAndTimeframes[i]
|
|
712
|
+
symbolString = self.safe_string(data, 0)
|
|
713
|
+
market = self.market(symbolString)
|
|
714
|
+
symbolString = market['symbol']
|
|
715
|
+
unfiedTimeframe = self.safe_string(data, 1)
|
|
716
|
+
timeframeId = self.safe_string(self.timeframes, unfiedTimeframe, unfiedTimeframe)
|
|
717
|
+
rawHashes.append('kline.' + timeframeId + '.' + market['id'])
|
|
718
|
+
subMessageHashes.append('ohlcv::' + symbolString + '::' + unfiedTimeframe)
|
|
719
|
+
messageHashes.append('unsubscribe::ohlcv::' + symbolString + '::' + unfiedTimeframe)
|
|
720
|
+
subExtension = {
|
|
721
|
+
'symbolsAndTimeframes': symbolsAndTimeframes,
|
|
722
|
+
}
|
|
723
|
+
return await self.un_watch_topics(url, 'ohlcv', symbols, messageHashes, subMessageHashes, rawHashes, params, subExtension)
|
|
724
|
+
|
|
725
|
+
async def un_watch_ohlcv(self, symbol: str, timeframe='1m', params={}) -> Any:
|
|
726
|
+
"""
|
|
727
|
+
unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
728
|
+
|
|
729
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/kline
|
|
730
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
|
|
731
|
+
|
|
732
|
+
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
|
733
|
+
:param str timeframe: the length of time each candle represents
|
|
734
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
735
|
+
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
|
736
|
+
"""
|
|
737
|
+
params['callerMethodName'] = 'watchOHLCV'
|
|
738
|
+
return await self.un_watch_ohlcv_for_symbols([[symbol, timeframe]], params)
|
|
523
739
|
|
|
524
740
|
def handle_ohlcv(self, client: Client, message):
|
|
525
741
|
#
|
|
@@ -558,16 +774,16 @@ class bybit(ccxt.async_support.bybit):
|
|
|
558
774
|
ohlcvsByTimeframe = self.safe_value(self.ohlcvs, symbol)
|
|
559
775
|
if ohlcvsByTimeframe is None:
|
|
560
776
|
self.ohlcvs[symbol] = {}
|
|
561
|
-
|
|
562
|
-
if stored is None:
|
|
777
|
+
if self.safe_value(ohlcvsByTimeframe, timeframe) is None:
|
|
563
778
|
limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
|
|
564
|
-
|
|
565
|
-
|
|
779
|
+
self.ohlcvs[symbol][timeframe] = ArrayCacheByTimestamp(limit)
|
|
780
|
+
stored = self.ohlcvs[symbol][timeframe]
|
|
566
781
|
for i in range(0, len(data)):
|
|
567
|
-
parsed = self.parse_ws_ohlcv(data[i])
|
|
782
|
+
parsed = self.parse_ws_ohlcv(data[i], market)
|
|
568
783
|
stored.append(parsed)
|
|
569
|
-
messageHash = '
|
|
570
|
-
|
|
784
|
+
messageHash = 'ohlcv::' + symbol + '::' + timeframe
|
|
785
|
+
resolveData = [symbol, timeframe, stored]
|
|
786
|
+
client.resolve(resolveData, messageHash)
|
|
571
787
|
|
|
572
788
|
def parse_ws_ohlcv(self, ohlcv, market=None) -> list:
|
|
573
789
|
#
|
|
@@ -585,19 +801,22 @@ class bybit(ccxt.async_support.bybit):
|
|
|
585
801
|
# "timestamp": 1670363219614
|
|
586
802
|
# }
|
|
587
803
|
#
|
|
804
|
+
volumeIndex = 'turnover' if (market['inverse']) else 'volume'
|
|
588
805
|
return [
|
|
589
806
|
self.safe_integer(ohlcv, 'start'),
|
|
590
807
|
self.safe_number(ohlcv, 'open'),
|
|
591
808
|
self.safe_number(ohlcv, 'high'),
|
|
592
809
|
self.safe_number(ohlcv, 'low'),
|
|
593
810
|
self.safe_number(ohlcv, 'close'),
|
|
594
|
-
self.
|
|
811
|
+
self.safe_number(ohlcv, volumeIndex),
|
|
595
812
|
]
|
|
596
813
|
|
|
597
814
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
|
598
815
|
"""
|
|
599
816
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
600
|
-
|
|
817
|
+
|
|
818
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
|
|
819
|
+
|
|
601
820
|
:param str symbol: unified symbol of the market to fetch the order book for
|
|
602
821
|
:param int [limit]: the maximum amount of order book entries to return.
|
|
603
822
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -608,7 +827,9 @@ class bybit(ccxt.async_support.bybit):
|
|
|
608
827
|
async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
|
|
609
828
|
"""
|
|
610
829
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
611
|
-
|
|
830
|
+
|
|
831
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
|
|
832
|
+
|
|
612
833
|
:param str[] symbols: unified array of symbols
|
|
613
834
|
:param int [limit]: the maximum amount of order book entries to return.
|
|
614
835
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -619,16 +840,22 @@ class bybit(ccxt.async_support.bybit):
|
|
|
619
840
|
if symbolsLength == 0:
|
|
620
841
|
raise ArgumentsRequired(self.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols')
|
|
621
842
|
symbols = self.market_symbols(symbols)
|
|
622
|
-
url = self.get_url_by_market_type(symbols[0], False, 'watchOrderBook', params)
|
|
843
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'watchOrderBook', params)
|
|
623
844
|
params = self.clean_params(params)
|
|
624
845
|
market = self.market(symbols[0])
|
|
625
846
|
if limit is None:
|
|
626
847
|
limit = 50 if (market['spot']) else 500
|
|
848
|
+
if market['option']:
|
|
849
|
+
limit = 100
|
|
627
850
|
else:
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
851
|
+
limits = {
|
|
852
|
+
'spot': [1, 50, 200, 1000],
|
|
853
|
+
'option': [25, 100],
|
|
854
|
+
'default': [1, 50, 200, 500, 1000],
|
|
855
|
+
}
|
|
856
|
+
selectedLimits = self.safe_list_2(limits, market['type'], 'default')
|
|
857
|
+
if not self.in_array(limit, selectedLimits):
|
|
858
|
+
raise BadRequest(self.id + ' watchOrderBookForSymbols(): for ' + market['type'] + ' markets limit can be one of: ' + self.json(selectedLimits))
|
|
632
859
|
topics = []
|
|
633
860
|
messageHashes = []
|
|
634
861
|
for i in range(0, len(symbols)):
|
|
@@ -641,6 +868,55 @@ class bybit(ccxt.async_support.bybit):
|
|
|
641
868
|
orderbook = await self.watch_topics(url, messageHashes, topics, params)
|
|
642
869
|
return orderbook.limit()
|
|
643
870
|
|
|
871
|
+
async def un_watch_order_book_for_symbols(self, symbols: List[str], params={}) -> Any:
|
|
872
|
+
"""
|
|
873
|
+
unsubscribe from the orderbook channel
|
|
874
|
+
|
|
875
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
|
|
876
|
+
|
|
877
|
+
:param str[] symbols: unified symbol of the market to unwatch the trades for
|
|
878
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
879
|
+
:param int [params.limit]: orderbook limit, default is None
|
|
880
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
|
881
|
+
"""
|
|
882
|
+
await self.load_markets()
|
|
883
|
+
symbols = self.market_symbols(symbols, None, False)
|
|
884
|
+
channel = 'orderbook.'
|
|
885
|
+
limit = self.safe_integer(params, 'limit')
|
|
886
|
+
if limit is not None:
|
|
887
|
+
params = self.omit(params, 'limit')
|
|
888
|
+
else:
|
|
889
|
+
firstMarket = self.market(symbols[0])
|
|
890
|
+
limit = 50 if firstMarket['spot'] else 500
|
|
891
|
+
channel += str(limit)
|
|
892
|
+
subMessageHashes = []
|
|
893
|
+
messageHashes = []
|
|
894
|
+
topics = []
|
|
895
|
+
for i in range(0, len(symbols)):
|
|
896
|
+
symbol = symbols[i]
|
|
897
|
+
market = self.market(symbol)
|
|
898
|
+
marketId = market['id']
|
|
899
|
+
topic = channel + '.' + marketId
|
|
900
|
+
messageHashes.append('unsubscribe:orderbook:' + symbol)
|
|
901
|
+
subMessageHashes.append('orderbook:' + symbol)
|
|
902
|
+
topics.append(topic)
|
|
903
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'watchOrderBook', params)
|
|
904
|
+
return await self.un_watch_topics(url, 'orderbook', symbols, messageHashes, subMessageHashes, topics, params)
|
|
905
|
+
|
|
906
|
+
async def un_watch_order_book(self, symbol: str, params={}) -> Any:
|
|
907
|
+
"""
|
|
908
|
+
unsubscribe from the orderbook channel
|
|
909
|
+
|
|
910
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
|
|
911
|
+
|
|
912
|
+
:param str symbol: symbol of the market to unwatch the trades for
|
|
913
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
914
|
+
:param int [params.limit]: orderbook limit, default is None
|
|
915
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
|
916
|
+
"""
|
|
917
|
+
await self.load_markets()
|
|
918
|
+
return await self.un_watch_order_book_for_symbols([symbol], params)
|
|
919
|
+
|
|
644
920
|
def handle_order_book(self, client: Client, message):
|
|
645
921
|
#
|
|
646
922
|
# {
|
|
@@ -675,6 +951,8 @@ class bybit(ccxt.async_support.bybit):
|
|
|
675
951
|
# }
|
|
676
952
|
# }
|
|
677
953
|
#
|
|
954
|
+
topic = self.safe_string(message, 'topic')
|
|
955
|
+
limit = topic.split('.')[1]
|
|
678
956
|
isSpot = client.url.find('spot') >= 0
|
|
679
957
|
type = self.safe_string(message, 'type')
|
|
680
958
|
isSnapshot = (type == 'snapshot')
|
|
@@ -700,6 +978,12 @@ class bybit(ccxt.async_support.bybit):
|
|
|
700
978
|
messageHash = 'orderbook' + ':' + symbol
|
|
701
979
|
self.orderbooks[symbol] = orderbook
|
|
702
980
|
client.resolve(orderbook, messageHash)
|
|
981
|
+
if limit == '1':
|
|
982
|
+
bidask = self.parse_ws_bid_ask(self.orderbooks[symbol], market)
|
|
983
|
+
newBidsAsks: dict = {}
|
|
984
|
+
newBidsAsks[symbol] = bidask
|
|
985
|
+
self.bidsasks[symbol] = bidask
|
|
986
|
+
client.resolve(newBidsAsks, 'bidask:' + symbol)
|
|
703
987
|
|
|
704
988
|
def handle_delta(self, bookside, delta):
|
|
705
989
|
bidAsk = self.parse_bid_ask(delta, 0, 1)
|
|
@@ -712,19 +996,23 @@ class bybit(ccxt.async_support.bybit):
|
|
|
712
996
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
713
997
|
"""
|
|
714
998
|
watches information on multiple trades made in a market
|
|
715
|
-
|
|
999
|
+
|
|
1000
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/trade
|
|
1001
|
+
|
|
716
1002
|
:param str symbol: unified market symbol of the market trades were made in
|
|
717
1003
|
:param int [since]: the earliest time in ms to fetch trades for
|
|
718
1004
|
:param int [limit]: the maximum number of trade structures to retrieve
|
|
719
1005
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
720
|
-
:returns dict[]: a list of
|
|
1006
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
|
721
1007
|
"""
|
|
722
1008
|
return await self.watch_trades_for_symbols([symbol], since, limit, params)
|
|
723
1009
|
|
|
724
1010
|
async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
725
1011
|
"""
|
|
726
1012
|
get the list of most recent trades for a list of symbols
|
|
727
|
-
|
|
1013
|
+
|
|
1014
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/trade
|
|
1015
|
+
|
|
728
1016
|
:param str[] symbols: unified symbol of the market to fetch trades for
|
|
729
1017
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
|
730
1018
|
:param int [limit]: the maximum amount of trades to fetch
|
|
@@ -737,7 +1025,7 @@ class bybit(ccxt.async_support.bybit):
|
|
|
737
1025
|
if symbolsLength == 0:
|
|
738
1026
|
raise ArgumentsRequired(self.id + ' watchTradesForSymbols() requires a non-empty array of symbols')
|
|
739
1027
|
params = self.clean_params(params)
|
|
740
|
-
url = self.get_url_by_market_type(symbols[0], False, 'watchTrades', params)
|
|
1028
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'watchTrades', params)
|
|
741
1029
|
topics = []
|
|
742
1030
|
messageHashes = []
|
|
743
1031
|
for i in range(0, len(symbols)):
|
|
@@ -754,6 +1042,45 @@ class bybit(ccxt.async_support.bybit):
|
|
|
754
1042
|
limit = trades.getLimit(tradeSymbol, limit)
|
|
755
1043
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
|
756
1044
|
|
|
1045
|
+
async def un_watch_trades_for_symbols(self, symbols: List[str], params={}) -> Any:
|
|
1046
|
+
"""
|
|
1047
|
+
unsubscribe from the trades channel
|
|
1048
|
+
|
|
1049
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/trade
|
|
1050
|
+
|
|
1051
|
+
:param str[] symbols: unified symbol of the market to unwatch the trades for
|
|
1052
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1053
|
+
:returns any: status of the unwatch request
|
|
1054
|
+
"""
|
|
1055
|
+
await self.load_markets()
|
|
1056
|
+
symbols = self.market_symbols(symbols, None, False, True)
|
|
1057
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'unWatchTradesForSymbols', params)
|
|
1058
|
+
messageHashes = []
|
|
1059
|
+
topics = []
|
|
1060
|
+
subMessageHashes = []
|
|
1061
|
+
for i in range(0, len(symbols)):
|
|
1062
|
+
symbol = symbols[i]
|
|
1063
|
+
market = self.market(symbol)
|
|
1064
|
+
topic = 'publicTrade.' + market['id']
|
|
1065
|
+
topics.append(topic)
|
|
1066
|
+
messageHash = 'unsubscribe:trade:' + symbol
|
|
1067
|
+
messageHashes.append(messageHash)
|
|
1068
|
+
subMessageHashes.append('trade:' + symbol)
|
|
1069
|
+
return await self.un_watch_topics(url, 'trades', symbols, messageHashes, subMessageHashes, topics, params)
|
|
1070
|
+
|
|
1071
|
+
async def un_watch_trades(self, symbol: str, params={}) -> Any:
|
|
1072
|
+
"""
|
|
1073
|
+
unsubscribe from the trades channel
|
|
1074
|
+
|
|
1075
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/trade
|
|
1076
|
+
|
|
1077
|
+
:param str symbol: unified symbol of the market to unwatch the trades for
|
|
1078
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1079
|
+
:returns any: status of the unwatch request
|
|
1080
|
+
"""
|
|
1081
|
+
await self.load_markets()
|
|
1082
|
+
return await self.un_watch_trades_for_symbols([symbol], params)
|
|
1083
|
+
|
|
757
1084
|
def handle_trades(self, client: Client, message):
|
|
758
1085
|
#
|
|
759
1086
|
# {
|
|
@@ -873,13 +1200,15 @@ class bybit(ccxt.async_support.bybit):
|
|
|
873
1200
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
874
1201
|
"""
|
|
875
1202
|
watches information on multiple trades made by the user
|
|
876
|
-
|
|
1203
|
+
|
|
1204
|
+
https://bybit-exchange.github.io/docs/v5/websocket/private/execution
|
|
1205
|
+
|
|
877
1206
|
:param str symbol: unified market symbol of the market orders were made in
|
|
878
1207
|
:param int [since]: the earliest time in ms to fetch orders for
|
|
879
1208
|
:param int [limit]: the maximum number of order structures to retrieve
|
|
880
1209
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
881
1210
|
:param boolean [params.unifiedMargin]: use unified margin account
|
|
882
|
-
:returns dict[]: a list of
|
|
1211
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
883
1212
|
"""
|
|
884
1213
|
method = 'watchMyTrades'
|
|
885
1214
|
messageHash = 'myTrades'
|
|
@@ -887,7 +1216,7 @@ class bybit(ccxt.async_support.bybit):
|
|
|
887
1216
|
if symbol is not None:
|
|
888
1217
|
symbol = self.symbol(symbol)
|
|
889
1218
|
messageHash += ':' + symbol
|
|
890
|
-
url = self.get_url_by_market_type(symbol, True, method, params)
|
|
1219
|
+
url = await self.get_url_by_market_type(symbol, True, method, params)
|
|
891
1220
|
await self.authenticate(url)
|
|
892
1221
|
topicByMarket: dict = {
|
|
893
1222
|
'spot': 'ticketInfo',
|
|
@@ -900,6 +1229,33 @@ class bybit(ccxt.async_support.bybit):
|
|
|
900
1229
|
limit = trades.getLimit(symbol, limit)
|
|
901
1230
|
return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
|
|
902
1231
|
|
|
1232
|
+
async def un_watch_my_trades(self, symbol: Str = None, params={}) -> Any:
|
|
1233
|
+
"""
|
|
1234
|
+
unWatches information on multiple trades made by the user
|
|
1235
|
+
|
|
1236
|
+
https://bybit-exchange.github.io/docs/v5/websocket/private/execution
|
|
1237
|
+
|
|
1238
|
+
:param str symbol: unified market symbol of the market orders were made in
|
|
1239
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1240
|
+
:param boolean [params.unifiedMargin]: use unified margin account
|
|
1241
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
1242
|
+
"""
|
|
1243
|
+
method = 'watchMyTrades'
|
|
1244
|
+
messageHash = 'unsubscribe:myTrades'
|
|
1245
|
+
subHash = 'myTrades'
|
|
1246
|
+
await self.load_markets()
|
|
1247
|
+
if symbol is not None:
|
|
1248
|
+
raise NotSupported(self.id + ' unWatchMyTrades() does not support a symbol parameter, you must unwatch all my trades')
|
|
1249
|
+
url = await self.get_url_by_market_type(symbol, True, method, params)
|
|
1250
|
+
await self.authenticate(url)
|
|
1251
|
+
topicByMarket: dict = {
|
|
1252
|
+
'spot': 'ticketInfo',
|
|
1253
|
+
'unified': 'execution',
|
|
1254
|
+
'usdc': 'user.openapi.perp.trade',
|
|
1255
|
+
}
|
|
1256
|
+
topic = self.safe_value(topicByMarket, self.get_private_type(url))
|
|
1257
|
+
return await self.un_watch_topics(url, 'myTrades', [], [messageHash], [subHash], [topic], params)
|
|
1258
|
+
|
|
903
1259
|
def handle_my_trades(self, client: Client, message):
|
|
904
1260
|
#
|
|
905
1261
|
# spot
|
|
@@ -973,12 +1329,17 @@ class bybit(ccxt.async_support.bybit):
|
|
|
973
1329
|
self.myTrades = ArrayCacheBySymbolById(limit)
|
|
974
1330
|
trades = self.myTrades
|
|
975
1331
|
symbols: dict = {}
|
|
1332
|
+
filterExecTypes = self.handle_option('watchMyTrades', 'filterExecTypes', [])
|
|
976
1333
|
for i in range(0, len(data)):
|
|
977
1334
|
rawTrade = data[i]
|
|
978
1335
|
parsed = None
|
|
979
1336
|
if spot:
|
|
980
1337
|
parsed = self.parse_ws_trade(rawTrade)
|
|
981
1338
|
else:
|
|
1339
|
+
# filter unified trades
|
|
1340
|
+
execType = self.safe_string(rawTrade, 'execType', '')
|
|
1341
|
+
if not self.in_array(execType, filterExecTypes):
|
|
1342
|
+
continue
|
|
982
1343
|
parsed = self.parse_trade(rawTrade)
|
|
983
1344
|
symbol = parsed['symbol']
|
|
984
1345
|
symbols[symbol] = True
|
|
@@ -993,9 +1354,13 @@ class bybit(ccxt.async_support.bybit):
|
|
|
993
1354
|
|
|
994
1355
|
async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
|
|
995
1356
|
"""
|
|
996
|
-
|
|
1357
|
+
|
|
1358
|
+
https://bybit-exchange.github.io/docs/v5/websocket/private/position
|
|
1359
|
+
|
|
997
1360
|
watch all open positions
|
|
998
1361
|
:param str[] [symbols]: list of unified market symbols
|
|
1362
|
+
:param int [since]: the earliest time in ms to fetch positions for
|
|
1363
|
+
:param int [limit]: the maximum number of positions to retrieve
|
|
999
1364
|
:param dict params: extra parameters specific to the exchange API endpoint
|
|
1000
1365
|
:returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
|
|
1001
1366
|
"""
|
|
@@ -1006,14 +1371,14 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1006
1371
|
symbols = self.market_symbols(symbols)
|
|
1007
1372
|
messageHash = '::' + ','.join(symbols)
|
|
1008
1373
|
firstSymbol = self.safe_string(symbols, 0)
|
|
1009
|
-
url = self.get_url_by_market_type(firstSymbol, True, method, params)
|
|
1374
|
+
url = await self.get_url_by_market_type(firstSymbol, True, method, params)
|
|
1010
1375
|
messageHash = 'positions' + messageHash
|
|
1011
1376
|
client = self.client(url)
|
|
1012
1377
|
await self.authenticate(url)
|
|
1013
1378
|
self.set_positions_cache(client, symbols)
|
|
1014
1379
|
cache = self.positions
|
|
1015
1380
|
fetchPositionsSnapshot = self.handle_option('watchPositions', 'fetchPositionsSnapshot', True)
|
|
1016
|
-
awaitPositionsSnapshot = self.
|
|
1381
|
+
awaitPositionsSnapshot = self.handle_option('watchPositions', 'awaitPositionsSnapshot', True)
|
|
1017
1382
|
if fetchPositionsSnapshot and awaitPositionsSnapshot and cache is None:
|
|
1018
1383
|
snapshot = await client.future('fetchPositionsSnapshot')
|
|
1019
1384
|
return self.filter_by_symbols_since_limit(snapshot, symbols, since, limit, True)
|
|
@@ -1128,76 +1493,143 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1128
1493
|
client.resolve(positions, messageHash)
|
|
1129
1494
|
client.resolve(newPositions, 'positions')
|
|
1130
1495
|
|
|
1496
|
+
async def un_watch_positions(self, symbols: Strings = None, params={}) -> Any:
|
|
1497
|
+
"""
|
|
1498
|
+
unWatches all open positions
|
|
1499
|
+
|
|
1500
|
+
https://bybit-exchange.github.io/docs/v5/websocket/private/position
|
|
1501
|
+
|
|
1502
|
+
:param str[] [symbols]: list of unified market symbols
|
|
1503
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1504
|
+
:returns dict: status of the unwatch request
|
|
1505
|
+
"""
|
|
1506
|
+
await self.load_markets()
|
|
1507
|
+
method = 'watchPositions'
|
|
1508
|
+
messageHash = 'unsubscribe:positions'
|
|
1509
|
+
subHash = 'positions'
|
|
1510
|
+
if not self.is_empty(symbols):
|
|
1511
|
+
raise NotSupported(self.id + ' unWatchPositions() does not support a symbol parameter, you must unwatch all orders')
|
|
1512
|
+
url = await self.get_url_by_market_type(None, True, method, params)
|
|
1513
|
+
await self.authenticate(url)
|
|
1514
|
+
topics = ['position']
|
|
1515
|
+
return await self.un_watch_topics(url, 'positions', symbols, [messageHash], [subHash], topics, params)
|
|
1516
|
+
|
|
1131
1517
|
async def watch_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
|
1132
1518
|
"""
|
|
1133
1519
|
watch the public liquidations of a trading pair
|
|
1134
|
-
|
|
1520
|
+
|
|
1521
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/liquidation
|
|
1522
|
+
|
|
1135
1523
|
:param str symbol: unified CCXT market symbol
|
|
1136
1524
|
:param int [since]: the earliest time in ms to fetch liquidations for
|
|
1137
1525
|
:param int [limit]: the maximum number of liquidation structures to retrieve
|
|
1138
1526
|
:param dict [params]: exchange specific parameters for the bitmex api endpoint
|
|
1527
|
+
:param str [params.method]: exchange specific method, supported: liquidation, allLiquidation
|
|
1139
1528
|
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
|
1140
1529
|
"""
|
|
1141
1530
|
await self.load_markets()
|
|
1142
1531
|
market = self.market(symbol)
|
|
1143
1532
|
symbol = market['symbol']
|
|
1144
|
-
url = self.get_url_by_market_type(symbol, False, 'watchLiquidations', params)
|
|
1533
|
+
url = await self.get_url_by_market_type(symbol, False, 'watchLiquidations', params)
|
|
1145
1534
|
params = self.clean_params(params)
|
|
1535
|
+
method = None
|
|
1536
|
+
method, params = self.handle_option_and_params(params, 'watchLiquidations', 'method', 'liquidation')
|
|
1146
1537
|
messageHash = 'liquidations::' + symbol
|
|
1147
|
-
topic = '
|
|
1538
|
+
topic = method + '.' + market['id']
|
|
1148
1539
|
newLiquidation = await self.watch_topics(url, [messageHash], [topic], params)
|
|
1149
1540
|
if self.newUpdates:
|
|
1150
|
-
return
|
|
1541
|
+
return newLiquidation
|
|
1151
1542
|
return self.filter_by_symbols_since_limit(self.liquidations, [symbol], since, limit, True)
|
|
1152
1543
|
|
|
1153
1544
|
def handle_liquidation(self, client: Client, message):
|
|
1154
1545
|
#
|
|
1155
|
-
#
|
|
1156
|
-
#
|
|
1157
|
-
#
|
|
1158
|
-
#
|
|
1159
|
-
#
|
|
1160
|
-
#
|
|
1161
|
-
#
|
|
1162
|
-
#
|
|
1163
|
-
#
|
|
1164
|
-
#
|
|
1165
|
-
#
|
|
1166
|
-
#
|
|
1546
|
+
# {
|
|
1547
|
+
# "data": {
|
|
1548
|
+
# "price": "0.03803",
|
|
1549
|
+
# "side": "Buy",
|
|
1550
|
+
# "size": "1637",
|
|
1551
|
+
# "symbol": "GALAUSDT",
|
|
1552
|
+
# "updatedTime": 1673251091822
|
|
1553
|
+
# },
|
|
1554
|
+
# "topic": "liquidation.GALAUSDT",
|
|
1555
|
+
# "ts": 1673251091822,
|
|
1556
|
+
# "type": "snapshot"
|
|
1557
|
+
# }
|
|
1167
1558
|
#
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1559
|
+
# {
|
|
1560
|
+
# "topic": "allLiquidation.ROSEUSDT",
|
|
1561
|
+
# "type": "snapshot",
|
|
1562
|
+
# "ts": 1739502303204,
|
|
1563
|
+
# "data": [
|
|
1564
|
+
# {
|
|
1565
|
+
# "T": 1739502302929,
|
|
1566
|
+
# "s": "ROSEUSDT",
|
|
1567
|
+
# "S": "Sell",
|
|
1568
|
+
# "v": "20000",
|
|
1569
|
+
# "p": "0.04499"
|
|
1570
|
+
# }
|
|
1571
|
+
# ]
|
|
1572
|
+
# }
|
|
1573
|
+
#
|
|
1574
|
+
if isinstance(message['data'], list):
|
|
1575
|
+
rawLiquidations = self.safe_list(message, 'data', [])
|
|
1576
|
+
for i in range(0, len(rawLiquidations)):
|
|
1577
|
+
rawLiquidation = rawLiquidations[i]
|
|
1578
|
+
marketId = self.safe_string(rawLiquidation, 's')
|
|
1579
|
+
market = self.safe_market(marketId, None, '', 'contract')
|
|
1580
|
+
symbol = market['symbol']
|
|
1581
|
+
liquidation = self.parse_ws_liquidation(rawLiquidation, market)
|
|
1582
|
+
liquidations = self.safe_value(self.liquidations, symbol)
|
|
1583
|
+
if liquidations is None:
|
|
1584
|
+
limit = self.safe_integer(self.options, 'liquidationsLimit', 1000)
|
|
1585
|
+
liquidations = ArrayCache(limit)
|
|
1586
|
+
liquidations.append(liquidation)
|
|
1587
|
+
self.liquidations[symbol] = liquidations
|
|
1588
|
+
client.resolve([liquidation], 'liquidations')
|
|
1589
|
+
client.resolve([liquidation], 'liquidations::' + symbol)
|
|
1590
|
+
else:
|
|
1591
|
+
rawLiquidation = self.safe_dict(message, 'data', {})
|
|
1592
|
+
marketId = self.safe_string(rawLiquidation, 'symbol')
|
|
1593
|
+
market = self.safe_market(marketId, None, '', 'contract')
|
|
1594
|
+
symbol = market['symbol']
|
|
1595
|
+
liquidation = self.parse_ws_liquidation(rawLiquidation, market)
|
|
1596
|
+
liquidations = self.safe_value(self.liquidations, symbol)
|
|
1597
|
+
if liquidations is None:
|
|
1598
|
+
limit = self.safe_integer(self.options, 'liquidationsLimit', 1000)
|
|
1599
|
+
liquidations = ArrayCache(limit)
|
|
1600
|
+
liquidations.append(liquidation)
|
|
1601
|
+
self.liquidations[symbol] = liquidations
|
|
1602
|
+
client.resolve([liquidation], 'liquidations')
|
|
1603
|
+
client.resolve([liquidation], 'liquidations::' + symbol)
|
|
1181
1604
|
|
|
1182
1605
|
def parse_ws_liquidation(self, liquidation, market=None):
|
|
1183
1606
|
#
|
|
1184
|
-
#
|
|
1185
|
-
#
|
|
1186
|
-
#
|
|
1187
|
-
#
|
|
1188
|
-
#
|
|
1189
|
-
#
|
|
1190
|
-
#
|
|
1607
|
+
# {
|
|
1608
|
+
# "price": "0.03803",
|
|
1609
|
+
# "side": "Buy",
|
|
1610
|
+
# "size": "1637",
|
|
1611
|
+
# "symbol": "GALAUSDT",
|
|
1612
|
+
# "updatedTime": 1673251091822
|
|
1613
|
+
# }
|
|
1191
1614
|
#
|
|
1192
|
-
|
|
1615
|
+
# {
|
|
1616
|
+
# "T": 1739502302929,
|
|
1617
|
+
# "s": "ROSEUSDT",
|
|
1618
|
+
# "S": "Sell",
|
|
1619
|
+
# "v": "20000",
|
|
1620
|
+
# "p": "0.04499"
|
|
1621
|
+
# }
|
|
1622
|
+
#
|
|
1623
|
+
marketId = self.safe_string_2(liquidation, 'symbol', 's')
|
|
1193
1624
|
market = self.safe_market(marketId, market, '', 'contract')
|
|
1194
|
-
timestamp = self.
|
|
1625
|
+
timestamp = self.safe_integer_2(liquidation, 'updatedTime', 'T')
|
|
1195
1626
|
return self.safe_liquidation({
|
|
1196
1627
|
'info': liquidation,
|
|
1197
|
-
'symbol':
|
|
1198
|
-
'contracts': self.
|
|
1628
|
+
'symbol': market['symbol'],
|
|
1629
|
+
'contracts': self.safe_number_2(liquidation, 'size', 'v'),
|
|
1199
1630
|
'contractSize': self.safe_number(market, 'contractSize'),
|
|
1200
|
-
'price': self.
|
|
1631
|
+
'price': self.safe_number_2(liquidation, 'price', 'p'),
|
|
1632
|
+
'side': self.safe_string_lower(liquidation, 'side', 'S'),
|
|
1201
1633
|
'baseValue': None,
|
|
1202
1634
|
'quoteValue': None,
|
|
1203
1635
|
'timestamp': timestamp,
|
|
@@ -1207,12 +1639,14 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1207
1639
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
1208
1640
|
"""
|
|
1209
1641
|
watches information on multiple orders made by the user
|
|
1210
|
-
|
|
1642
|
+
|
|
1643
|
+
https://bybit-exchange.github.io/docs/v5/websocket/private/order
|
|
1644
|
+
|
|
1211
1645
|
:param str symbol: unified market symbol of the market orders were made in
|
|
1212
1646
|
:param int [since]: the earliest time in ms to fetch orders for
|
|
1213
1647
|
:param int [limit]: the maximum number of order structures to retrieve
|
|
1214
1648
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1215
|
-
:returns dict[]: a list of
|
|
1649
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
1216
1650
|
"""
|
|
1217
1651
|
await self.load_markets()
|
|
1218
1652
|
method = 'watchOrders'
|
|
@@ -1220,7 +1654,7 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1220
1654
|
if symbol is not None:
|
|
1221
1655
|
symbol = self.symbol(symbol)
|
|
1222
1656
|
messageHash += ':' + symbol
|
|
1223
|
-
url = self.get_url_by_market_type(symbol, True, method, params)
|
|
1657
|
+
url = await self.get_url_by_market_type(symbol, True, method, params)
|
|
1224
1658
|
await self.authenticate(url)
|
|
1225
1659
|
topicsByMarket: dict = {
|
|
1226
1660
|
'spot': ['order', 'stopOrder'],
|
|
@@ -1233,6 +1667,33 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1233
1667
|
limit = orders.getLimit(symbol, limit)
|
|
1234
1668
|
return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
|
|
1235
1669
|
|
|
1670
|
+
async def un_watch_orders(self, symbol: Str = None, params={}) -> Any:
|
|
1671
|
+
"""
|
|
1672
|
+
unWatches information on multiple orders made by the user
|
|
1673
|
+
|
|
1674
|
+
https://bybit-exchange.github.io/docs/v5/websocket/private/order
|
|
1675
|
+
|
|
1676
|
+
:param str symbol: unified market symbol of the market orders were made in
|
|
1677
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1678
|
+
:param boolean [params.unifiedMargin]: use unified margin account
|
|
1679
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
1680
|
+
"""
|
|
1681
|
+
await self.load_markets()
|
|
1682
|
+
method = 'watchOrders'
|
|
1683
|
+
messageHash = 'unsubscribe:orders'
|
|
1684
|
+
subHash = 'orders'
|
|
1685
|
+
if symbol is not None:
|
|
1686
|
+
raise NotSupported(self.id + ' unWatchOrders() does not support a symbol parameter, you must unwatch all orders')
|
|
1687
|
+
url = await self.get_url_by_market_type(symbol, True, method, params)
|
|
1688
|
+
await self.authenticate(url)
|
|
1689
|
+
topicsByMarket: dict = {
|
|
1690
|
+
'spot': ['order', 'stopOrder'],
|
|
1691
|
+
'unified': ['order'],
|
|
1692
|
+
'usdc': ['user.openapi.perp.order'],
|
|
1693
|
+
}
|
|
1694
|
+
topics = self.safe_value(topicsByMarket, self.get_private_type(url))
|
|
1695
|
+
return await self.un_watch_topics(url, 'orders', [], [messageHash], [subHash], topics, params)
|
|
1696
|
+
|
|
1236
1697
|
def handle_order_ws(self, client: Client, message):
|
|
1237
1698
|
#
|
|
1238
1699
|
# {
|
|
@@ -1355,11 +1816,12 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1355
1816
|
rawOrders = self.safe_value(rawOrders, 'result', rawOrders)
|
|
1356
1817
|
symbols: dict = {}
|
|
1357
1818
|
for i in range(0, len(rawOrders)):
|
|
1358
|
-
parsed =
|
|
1359
|
-
if isSpot:
|
|
1360
|
-
|
|
1361
|
-
else:
|
|
1362
|
-
|
|
1819
|
+
parsed = self.parse_order(rawOrders[i])
|
|
1820
|
+
# if isSpot:
|
|
1821
|
+
# parsed = self.parseWsSpotOrder(rawOrders[i])
|
|
1822
|
+
# else:
|
|
1823
|
+
# parsed = self.parse_order(rawOrders[i])
|
|
1824
|
+
# }
|
|
1363
1825
|
symbol = parsed['symbol']
|
|
1364
1826
|
symbols[symbol] = True
|
|
1365
1827
|
orders.append(parsed)
|
|
@@ -1370,141 +1832,12 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1370
1832
|
messageHash = 'orders'
|
|
1371
1833
|
client.resolve(orders, messageHash)
|
|
1372
1834
|
|
|
1373
|
-
def parse_ws_spot_order(self, order, market=None):
|
|
1374
|
-
#
|
|
1375
|
-
# {
|
|
1376
|
-
# "e": "executionReport",
|
|
1377
|
-
# "E": "1653297251061", # timestamp
|
|
1378
|
-
# "s": "LTCUSDT", # symbol
|
|
1379
|
-
# "c": "1653297250740", # user id
|
|
1380
|
-
# "S": "SELL", # side
|
|
1381
|
-
# "o": "MARKET_OF_BASE", # order type
|
|
1382
|
-
# "f": "GTC", # time in force
|
|
1383
|
-
# "q": "0.16233", # quantity
|
|
1384
|
-
# "p": "0", # price
|
|
1385
|
-
# "X": "NEW", # status
|
|
1386
|
-
# "i": "1162336018974750208", # order id
|
|
1387
|
-
# "M": "0",
|
|
1388
|
-
# "l": "0", # last filled
|
|
1389
|
-
# "z": "0", # total filled
|
|
1390
|
-
# "L": "0", # last traded price
|
|
1391
|
-
# "n": "0", # trading fee
|
|
1392
|
-
# "N": '', # fee asset
|
|
1393
|
-
# "u": True,
|
|
1394
|
-
# "w": True,
|
|
1395
|
-
# "m": False, # is limit_maker
|
|
1396
|
-
# "O": "1653297251042", # order creation
|
|
1397
|
-
# "Z": "0", # total filled
|
|
1398
|
-
# "A": "0", # account id
|
|
1399
|
-
# "C": False, # is close
|
|
1400
|
-
# "v": "0", # leverage
|
|
1401
|
-
# "d": "NO_LIQ"
|
|
1402
|
-
# }
|
|
1403
|
-
# v5
|
|
1404
|
-
# {
|
|
1405
|
-
# "category":"spot",
|
|
1406
|
-
# "symbol":"LTCUSDT",
|
|
1407
|
-
# "orderId":"1474764674982492160",
|
|
1408
|
-
# "orderLinkId":"1690541649154749",
|
|
1409
|
-
# "blockTradeId":"",
|
|
1410
|
-
# "side":"Buy",
|
|
1411
|
-
# "positionIdx":0,
|
|
1412
|
-
# "orderStatus":"Cancelled",
|
|
1413
|
-
# "cancelType":"UNKNOWN",
|
|
1414
|
-
# "rejectReason":"EC_NoError",
|
|
1415
|
-
# "timeInForce":"GTC",
|
|
1416
|
-
# "isLeverage":"0",
|
|
1417
|
-
# "price":"0",
|
|
1418
|
-
# "qty":"5.00000",
|
|
1419
|
-
# "avgPrice":"0",
|
|
1420
|
-
# "leavesQty":"0.00000",
|
|
1421
|
-
# "leavesValue":"5.0000000",
|
|
1422
|
-
# "cumExecQty":"0.00000",
|
|
1423
|
-
# "cumExecValue":"0.0000000",
|
|
1424
|
-
# "cumExecFee":"",
|
|
1425
|
-
# "orderType":"Market",
|
|
1426
|
-
# "stopOrderType":"",
|
|
1427
|
-
# "orderIv":"",
|
|
1428
|
-
# "triggerPrice":"0.000",
|
|
1429
|
-
# "takeProfit":"",
|
|
1430
|
-
# "stopLoss":"",
|
|
1431
|
-
# "triggerBy":"",
|
|
1432
|
-
# "tpTriggerBy":"",
|
|
1433
|
-
# "slTriggerBy":"",
|
|
1434
|
-
# "triggerDirection":0,
|
|
1435
|
-
# "placeType":"",
|
|
1436
|
-
# "lastPriceOnCreated":"0.000",
|
|
1437
|
-
# "closeOnTrigger":false,
|
|
1438
|
-
# "reduceOnly":false,
|
|
1439
|
-
# "smpGroup":0,
|
|
1440
|
-
# "smpType":"None",
|
|
1441
|
-
# "smpOrderId":"",
|
|
1442
|
-
# "createdTime":"1690541649160",
|
|
1443
|
-
# "updatedTime":"1690541649168"
|
|
1444
|
-
# }
|
|
1445
|
-
#
|
|
1446
|
-
id = self.safe_string_2(order, 'i', 'orderId')
|
|
1447
|
-
marketId = self.safe_string_2(order, 's', 'symbol')
|
|
1448
|
-
symbol = self.safe_symbol(marketId, market, None, 'spot')
|
|
1449
|
-
timestamp = self.safe_integer_2(order, 'O', 'createdTime')
|
|
1450
|
-
price = self.safe_string_2(order, 'p', 'price')
|
|
1451
|
-
if price == '0':
|
|
1452
|
-
price = None # market orders
|
|
1453
|
-
filled = self.safe_string_2(order, 'z', 'cumExecQty')
|
|
1454
|
-
status = self.parse_order_status(self.safe_string_2(order, 'X', 'orderStatus'))
|
|
1455
|
-
side = self.safe_string_lower_2(order, 'S', 'side')
|
|
1456
|
-
lastTradeTimestamp = self.safe_string_2(order, 'E', 'updatedTime')
|
|
1457
|
-
timeInForce = self.safe_string_2(order, 'f', 'timeInForce')
|
|
1458
|
-
amount = None
|
|
1459
|
-
cost = self.safe_string_2(order, 'Z', 'cumExecValue')
|
|
1460
|
-
type = self.safe_string_lower_2(order, 'o', 'orderType')
|
|
1461
|
-
if (type is not None) and (type.find('market') >= 0):
|
|
1462
|
-
type = 'market'
|
|
1463
|
-
if type == 'market' and side == 'buy':
|
|
1464
|
-
amount = filled
|
|
1465
|
-
else:
|
|
1466
|
-
amount = self.safe_string_2(order, 'orderQty', 'qty')
|
|
1467
|
-
fee = None
|
|
1468
|
-
feeCost = self.safe_string_2(order, 'n', 'cumExecFee')
|
|
1469
|
-
if feeCost is not None and feeCost != '0':
|
|
1470
|
-
feeCurrencyId = self.safe_string(order, 'N')
|
|
1471
|
-
feeCurrencyCode = self.safe_currency_code(feeCurrencyId)
|
|
1472
|
-
fee = {
|
|
1473
|
-
'cost': feeCost,
|
|
1474
|
-
'currency': feeCurrencyCode,
|
|
1475
|
-
}
|
|
1476
|
-
triggerPrice = self.omit_zero(self.safe_string(order, 'triggerPrice'))
|
|
1477
|
-
return self.safe_order({
|
|
1478
|
-
'info': order,
|
|
1479
|
-
'id': id,
|
|
1480
|
-
'clientOrderId': self.safe_string_2(order, 'c', 'orderLinkId'),
|
|
1481
|
-
'timestamp': timestamp,
|
|
1482
|
-
'datetime': self.iso8601(timestamp),
|
|
1483
|
-
'lastTradeTimestamp': lastTradeTimestamp,
|
|
1484
|
-
'symbol': symbol,
|
|
1485
|
-
'type': type,
|
|
1486
|
-
'timeInForce': timeInForce,
|
|
1487
|
-
'postOnly': None,
|
|
1488
|
-
'side': side,
|
|
1489
|
-
'price': price,
|
|
1490
|
-
'stopPrice': triggerPrice,
|
|
1491
|
-
'triggerPrice': triggerPrice,
|
|
1492
|
-
'takeProfitPrice': self.safe_string(order, 'takeProfit'),
|
|
1493
|
-
'stopLossPrice': self.safe_string(order, 'stopLoss'),
|
|
1494
|
-
'reduceOnly': self.safe_value(order, 'reduceOnly'),
|
|
1495
|
-
'amount': amount,
|
|
1496
|
-
'cost': cost,
|
|
1497
|
-
'average': self.safe_string(order, 'avgPrice'),
|
|
1498
|
-
'filled': filled,
|
|
1499
|
-
'remaining': None,
|
|
1500
|
-
'status': status,
|
|
1501
|
-
'fee': fee,
|
|
1502
|
-
}, market)
|
|
1503
|
-
|
|
1504
1835
|
async def watch_balance(self, params={}) -> Balances:
|
|
1505
1836
|
"""
|
|
1506
1837
|
watch balance and get the amount of funds available for trading or funds locked in orders
|
|
1507
|
-
|
|
1838
|
+
|
|
1839
|
+
https://bybit-exchange.github.io/docs/v5/websocket/private/wallet
|
|
1840
|
+
|
|
1508
1841
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1509
1842
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
|
1510
1843
|
"""
|
|
@@ -1518,7 +1851,7 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1518
1851
|
unified = await self.isUnifiedEnabled()
|
|
1519
1852
|
isUnifiedMargin = self.safe_bool(unified, 0, False)
|
|
1520
1853
|
isUnifiedAccount = self.safe_bool(unified, 1, False)
|
|
1521
|
-
url = self.get_url_by_market_type(None, True, method, params)
|
|
1854
|
+
url = await self.get_url_by_market_type(None, True, method, params)
|
|
1522
1855
|
await self.authenticate(url)
|
|
1523
1856
|
topicByMarket: dict = {
|
|
1524
1857
|
'spot': 'outboundAccountInfo',
|
|
@@ -1779,7 +2112,24 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1779
2112
|
'args': topics,
|
|
1780
2113
|
}
|
|
1781
2114
|
message = self.extend(request, params)
|
|
1782
|
-
return await self.watch_multiple(url, messageHashes, message,
|
|
2115
|
+
return await self.watch_multiple(url, messageHashes, message, messageHashes)
|
|
2116
|
+
|
|
2117
|
+
async def un_watch_topics(self, url: str, topic: str, symbols: Strings, messageHashes: List[str], subMessageHashes: List[str], topics, params={}, subExtension={}):
|
|
2118
|
+
reqId = self.request_id()
|
|
2119
|
+
request: dict = {
|
|
2120
|
+
'op': 'unsubscribe',
|
|
2121
|
+
'req_id': reqId,
|
|
2122
|
+
'args': topics,
|
|
2123
|
+
}
|
|
2124
|
+
subscription = {
|
|
2125
|
+
'id': reqId,
|
|
2126
|
+
'topic': topic,
|
|
2127
|
+
'messageHashes': messageHashes,
|
|
2128
|
+
'subMessageHashes': subMessageHashes,
|
|
2129
|
+
'symbols': symbols,
|
|
2130
|
+
}
|
|
2131
|
+
message = self.extend(request, params)
|
|
2132
|
+
return await self.watch_multiple(url, messageHashes, message, messageHashes, self.extend(subscription, subExtension))
|
|
1783
2133
|
|
|
1784
2134
|
async def authenticate(self, url, params={}):
|
|
1785
2135
|
self.check_required_credentials()
|
|
@@ -1803,7 +2153,7 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1803
2153
|
self.watch(url, messageHash, message, messageHash)
|
|
1804
2154
|
return await future
|
|
1805
2155
|
|
|
1806
|
-
def handle_error_message(self, client: Client, message):
|
|
2156
|
+
def handle_error_message(self, client: Client, message) -> Bool:
|
|
1807
2157
|
#
|
|
1808
2158
|
# {
|
|
1809
2159
|
# "success": False,
|
|
@@ -1894,7 +2244,7 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1894
2244
|
if event == 'sub':
|
|
1895
2245
|
self.handle_subscription_status(client, message)
|
|
1896
2246
|
return
|
|
1897
|
-
topic = self.safe_string_2(message, 'topic', 'op')
|
|
2247
|
+
topic = self.safe_string_2(message, 'topic', 'op', '')
|
|
1898
2248
|
methods: dict = {
|
|
1899
2249
|
'orderbook': self.handle_order_book,
|
|
1900
2250
|
'kline': self.handle_ohlcv,
|
|
@@ -1911,11 +2261,13 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1911
2261
|
'user.openapi.perp.trade': self.handle_my_trades,
|
|
1912
2262
|
'position': self.handle_positions,
|
|
1913
2263
|
'liquidation': self.handle_liquidation,
|
|
2264
|
+
'allLiquidation': self.handle_liquidation,
|
|
1914
2265
|
'pong': self.handle_pong,
|
|
1915
2266
|
'order.create': self.handle_order_ws,
|
|
1916
2267
|
'order.amend': self.handle_order_ws,
|
|
1917
2268
|
'order.cancel': self.handle_order_ws,
|
|
1918
2269
|
'auth': self.handle_authenticate,
|
|
2270
|
+
'unsubscribe': self.handle_un_subscribe,
|
|
1919
2271
|
}
|
|
1920
2272
|
exacMethod = self.safe_value(methods, topic)
|
|
1921
2273
|
if exacMethod is not None:
|
|
@@ -1933,7 +2285,7 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1933
2285
|
if type == 'AUTH_RESP':
|
|
1934
2286
|
self.handle_authenticate(client, message)
|
|
1935
2287
|
|
|
1936
|
-
def ping(self, client):
|
|
2288
|
+
def ping(self, client: Client):
|
|
1937
2289
|
return {
|
|
1938
2290
|
'req_id': self.request_id(),
|
|
1939
2291
|
'op': 'ping',
|
|
@@ -1998,3 +2350,38 @@ class bybit(ccxt.async_support.bybit):
|
|
|
1998
2350
|
# }
|
|
1999
2351
|
#
|
|
2000
2352
|
return message
|
|
2353
|
+
|
|
2354
|
+
def handle_un_subscribe(self, client: Client, message):
|
|
2355
|
+
#
|
|
2356
|
+
# {"success":true,"ret_msg":"","conn_id":"7188110e-6908-41e9-b863-6365127e92ad","req_id":"3","op":"unsubscribe"}
|
|
2357
|
+
#
|
|
2358
|
+
# client.subscription will be something like:
|
|
2359
|
+
# {
|
|
2360
|
+
# "publicTrade.LTCUSDT":true,
|
|
2361
|
+
# "publicTrade.ADAUSDT":true,
|
|
2362
|
+
# "unsubscribe:trade:LTC/USDT:USDT": {
|
|
2363
|
+
# "id":4,
|
|
2364
|
+
# "subHash": "trade:LTC/USDT"
|
|
2365
|
+
# },
|
|
2366
|
+
# }
|
|
2367
|
+
reqId = self.safe_string(message, 'req_id')
|
|
2368
|
+
keys = list(client.subscriptions.keys())
|
|
2369
|
+
for i in range(0, len(keys)):
|
|
2370
|
+
messageHash = keys[i]
|
|
2371
|
+
if not (messageHash in client.subscriptions):
|
|
2372
|
+
continue
|
|
2373
|
+
# the previous iteration can have deleted the messageHash from the subscriptions
|
|
2374
|
+
if messageHash.startswith('unsubscribe'):
|
|
2375
|
+
subscription = client.subscriptions[messageHash]
|
|
2376
|
+
subId = self.safe_string(subscription, 'id')
|
|
2377
|
+
if reqId != subId:
|
|
2378
|
+
continue
|
|
2379
|
+
messageHashes = self.safe_list(subscription, 'messageHashes', [])
|
|
2380
|
+
subMessageHashes = self.safe_list(subscription, 'subMessageHashes', [])
|
|
2381
|
+
for j in range(0, len(messageHashes)):
|
|
2382
|
+
unsubHash = messageHashes[j]
|
|
2383
|
+
subHash = subMessageHashes[j]
|
|
2384
|
+
usePrefix = (subHash == 'orders') or (subHash == 'myTrades')
|
|
2385
|
+
self.clean_unsubscription(client, subHash, unsubHash, usePrefix)
|
|
2386
|
+
self.clean_cache(subscription)
|
|
2387
|
+
return message
|