ccxt 4.2.76__py2.py3-none-any.whl → 4.4.48__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +36 -14
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +112 -48
- ccxt/abstract/binancecoinm.py +112 -48
- ccxt/abstract/binanceus.py +147 -83
- ccxt/abstract/binanceusdm.py +112 -48
- ccxt/abstract/bingx.py +133 -78
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitfinex1.py +69 -0
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +8 -1
- ccxt/abstract/bitmart.py +13 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitpanda.py +0 -12
- ccxt/abstract/bitrue.py +3 -3
- ccxt/abstract/bitstamp.py +26 -3
- ccxt/abstract/blofin.py +24 -0
- ccxt/abstract/btcbox.py +1 -0
- ccxt/abstract/bybit.py +29 -14
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbase.py +6 -0
- ccxt/abstract/coinbaseadvanced.py +94 -0
- ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/coincatch.py +94 -0
- ccxt/abstract/coinex.py +233 -123
- ccxt/abstract/coinmetro.py +1 -0
- ccxt/abstract/cryptocom.py +14 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/gate.py +20 -0
- ccxt/abstract/gateio.py +20 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hashkey.py +67 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +4 -3
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +25 -0
- ccxt/abstract/kucoinfutures.py +35 -0
- ccxt/abstract/luno.py +2 -0
- ccxt/abstract/mexc.py +4 -0
- ccxt/abstract/myokx.py +340 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +30 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/oxfun.py +34 -0
- ccxt/abstract/paradex.py +40 -0
- ccxt/abstract/phemex.py +1 -0
- ccxt/abstract/upbit.py +4 -0
- ccxt/abstract/vertex.py +19 -0
- ccxt/abstract/whitebit.py +31 -1
- ccxt/abstract/woo.py +6 -2
- ccxt/abstract/woofipro.py +119 -0
- ccxt/abstract/xt.py +153 -0
- ccxt/abstract/zonda.py +6 -0
- ccxt/ace.py +164 -60
- ccxt/alpaca.py +727 -63
- ccxt/ascendex.py +395 -249
- ccxt/async_support/__init__.py +36 -14
- ccxt/async_support/ace.py +164 -60
- ccxt/async_support/alpaca.py +727 -63
- ccxt/async_support/ascendex.py +396 -249
- ccxt/async_support/base/exchange.py +531 -155
- ccxt/async_support/base/ws/aiohttp_client.py +28 -5
- ccxt/async_support/base/ws/cache.py +3 -2
- ccxt/async_support/base/ws/client.py +26 -5
- ccxt/async_support/base/ws/fast_client.py +4 -3
- ccxt/async_support/base/ws/functions.py +1 -1
- ccxt/async_support/base/ws/future.py +40 -31
- ccxt/async_support/base/ws/order_book_side.py +3 -0
- ccxt/async_support/bequant.py +1 -1
- ccxt/async_support/bigone.py +329 -202
- ccxt/async_support/binance.py +3513 -1511
- ccxt/async_support/binancecoinm.py +2 -1
- ccxt/async_support/binanceus.py +12 -1
- ccxt/async_support/binanceusdm.py +3 -1
- ccxt/async_support/bingx.py +3105 -881
- ccxt/async_support/bit2c.py +119 -38
- ccxt/async_support/bitbank.py +215 -76
- ccxt/async_support/bitbns.py +124 -53
- ccxt/async_support/bitfinex.py +3236 -1078
- ccxt/async_support/bitfinex1.py +1711 -0
- ccxt/async_support/bitflyer.py +239 -50
- ccxt/async_support/bitget.py +1513 -563
- ccxt/async_support/bithumb.py +201 -67
- ccxt/async_support/bitmart.py +1320 -435
- ccxt/async_support/bitmex.py +308 -111
- ccxt/async_support/bitopro.py +256 -96
- ccxt/async_support/bitrue.py +365 -233
- ccxt/async_support/bitso.py +201 -89
- ccxt/async_support/bitstamp.py +438 -269
- ccxt/async_support/bitteam.py +179 -73
- ccxt/async_support/bitvavo.py +180 -70
- ccxt/async_support/bl3p.py +92 -25
- ccxt/async_support/blockchaincom.py +193 -79
- ccxt/async_support/blofin.py +403 -150
- ccxt/async_support/btcalpha.py +161 -55
- ccxt/async_support/btcbox.py +250 -34
- ccxt/async_support/btcmarkets.py +232 -85
- ccxt/async_support/btcturk.py +159 -60
- ccxt/async_support/bybit.py +2326 -1255
- ccxt/async_support/cex.py +1409 -1329
- ccxt/async_support/coinbase.py +1455 -288
- ccxt/async_support/coinbaseadvanced.py +17 -0
- ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/async_support/coinbaseinternational.py +428 -88
- ccxt/async_support/coincatch.py +5152 -0
- ccxt/async_support/coincheck.py +121 -38
- ccxt/async_support/coinex.py +4020 -3339
- ccxt/async_support/coinlist.py +273 -116
- ccxt/async_support/coinmate.py +204 -97
- ccxt/async_support/coinmetro.py +203 -110
- ccxt/async_support/coinone.py +142 -68
- ccxt/async_support/coinsph.py +206 -89
- ccxt/async_support/coinspot.py +137 -62
- ccxt/async_support/cryptocom.py +515 -185
- ccxt/async_support/currencycom.py +203 -85
- ccxt/async_support/defx.py +2066 -0
- ccxt/async_support/delta.py +467 -158
- ccxt/async_support/deribit.py +558 -324
- ccxt/async_support/digifinex.py +340 -223
- ccxt/async_support/ellipx.py +1826 -0
- ccxt/async_support/exmo.py +259 -128
- ccxt/async_support/gate.py +1473 -464
- ccxt/async_support/gemini.py +206 -84
- ccxt/async_support/hashkey.py +4164 -0
- ccxt/async_support/hitbtc.py +334 -178
- ccxt/async_support/hollaex.py +134 -83
- ccxt/async_support/htx.py +1095 -563
- ccxt/async_support/huobijp.py +105 -56
- ccxt/async_support/hyperliquid.py +1634 -269
- ccxt/async_support/idex.py +148 -95
- ccxt/async_support/independentreserve.py +236 -31
- ccxt/async_support/indodax.py +165 -62
- ccxt/async_support/kraken.py +871 -354
- ccxt/async_support/krakenfutures.py +324 -100
- ccxt/async_support/kucoin.py +1050 -355
- ccxt/async_support/kucoinfutures.py +1004 -149
- ccxt/async_support/kuna.py +138 -106
- ccxt/async_support/latoken.py +135 -79
- ccxt/async_support/lbank.py +290 -113
- ccxt/async_support/luno.py +112 -62
- ccxt/async_support/lykke.py +104 -55
- ccxt/async_support/mercado.py +36 -29
- ccxt/async_support/mexc.py +995 -429
- ccxt/async_support/myokx.py +43 -0
- ccxt/async_support/ndax.py +163 -82
- ccxt/async_support/novadax.py +121 -75
- ccxt/async_support/oceanex.py +175 -59
- ccxt/async_support/okcoin.py +222 -163
- ccxt/async_support/okx.py +1777 -455
- ccxt/async_support/onetrading.py +132 -414
- ccxt/async_support/oxfun.py +2832 -0
- ccxt/async_support/p2b.py +79 -51
- ccxt/async_support/paradex.py +2017 -0
- ccxt/async_support/paymium.py +56 -32
- ccxt/async_support/phemex.py +572 -196
- ccxt/async_support/poloniex.py +218 -95
- ccxt/async_support/poloniexfutures.py +260 -92
- ccxt/async_support/probit.py +143 -110
- ccxt/async_support/timex.py +123 -70
- ccxt/async_support/tokocrypto.py +129 -93
- ccxt/async_support/tradeogre.py +39 -25
- ccxt/async_support/upbit.py +322 -113
- ccxt/async_support/vertex.py +2983 -0
- ccxt/async_support/wavesexchange.py +227 -173
- ccxt/async_support/wazirx.py +145 -65
- ccxt/async_support/whitebit.py +533 -138
- ccxt/async_support/woo.py +1155 -295
- ccxt/async_support/woofipro.py +2716 -0
- ccxt/async_support/xt.py +4628 -0
- ccxt/async_support/yobit.py +160 -92
- ccxt/async_support/zaif.py +80 -33
- ccxt/async_support/zonda.py +140 -69
- ccxt/base/errors.py +51 -20
- ccxt/base/exchange.py +1729 -482
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +223 -4
- ccxt/bequant.py +1 -1
- ccxt/bigone.py +329 -202
- ccxt/binance.py +3513 -1511
- ccxt/binancecoinm.py +2 -1
- ccxt/binanceus.py +12 -1
- ccxt/binanceusdm.py +3 -1
- ccxt/bingx.py +3105 -881
- ccxt/bit2c.py +119 -38
- ccxt/bitbank.py +215 -76
- ccxt/bitbns.py +124 -53
- ccxt/bitfinex.py +3235 -1078
- ccxt/bitfinex1.py +1710 -0
- ccxt/bitflyer.py +239 -50
- ccxt/bitget.py +1513 -563
- ccxt/bithumb.py +200 -67
- ccxt/bitmart.py +1320 -435
- ccxt/bitmex.py +308 -111
- ccxt/bitopro.py +256 -96
- ccxt/bitrue.py +365 -233
- ccxt/bitso.py +201 -89
- ccxt/bitstamp.py +438 -269
- ccxt/bitteam.py +179 -73
- ccxt/bitvavo.py +180 -70
- ccxt/bl3p.py +92 -25
- ccxt/blockchaincom.py +193 -79
- ccxt/blofin.py +403 -150
- ccxt/btcalpha.py +161 -55
- ccxt/btcbox.py +250 -34
- ccxt/btcmarkets.py +232 -85
- ccxt/btcturk.py +159 -60
- ccxt/bybit.py +2326 -1255
- ccxt/cex.py +1408 -1329
- ccxt/coinbase.py +1455 -288
- ccxt/coinbaseadvanced.py +17 -0
- ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/coinbaseinternational.py +428 -88
- ccxt/coincatch.py +5152 -0
- ccxt/coincheck.py +121 -38
- ccxt/coinex.py +4020 -3339
- ccxt/coinlist.py +273 -116
- ccxt/coinmate.py +204 -97
- ccxt/coinmetro.py +203 -110
- ccxt/coinone.py +142 -68
- ccxt/coinsph.py +206 -89
- ccxt/coinspot.py +137 -62
- ccxt/cryptocom.py +515 -185
- ccxt/currencycom.py +203 -85
- ccxt/defx.py +2065 -0
- ccxt/delta.py +467 -158
- ccxt/deribit.py +558 -324
- ccxt/digifinex.py +340 -223
- ccxt/ellipx.py +1826 -0
- ccxt/exmo.py +259 -128
- ccxt/gate.py +1473 -464
- ccxt/gemini.py +206 -84
- ccxt/hashkey.py +4164 -0
- ccxt/hitbtc.py +334 -178
- ccxt/hollaex.py +134 -83
- ccxt/htx.py +1095 -563
- ccxt/huobijp.py +105 -56
- ccxt/hyperliquid.py +1633 -269
- ccxt/idex.py +148 -95
- ccxt/independentreserve.py +235 -31
- ccxt/indodax.py +165 -62
- ccxt/kraken.py +871 -354
- ccxt/krakenfutures.py +324 -100
- ccxt/kucoin.py +1050 -355
- ccxt/kucoinfutures.py +1004 -149
- ccxt/kuna.py +138 -106
- ccxt/latoken.py +135 -79
- ccxt/lbank.py +290 -113
- ccxt/luno.py +112 -62
- ccxt/lykke.py +104 -55
- ccxt/mercado.py +36 -29
- ccxt/mexc.py +994 -429
- ccxt/myokx.py +43 -0
- ccxt/ndax.py +163 -82
- ccxt/novadax.py +121 -75
- ccxt/oceanex.py +175 -59
- ccxt/okcoin.py +222 -163
- ccxt/okx.py +1777 -455
- ccxt/onetrading.py +132 -414
- ccxt/oxfun.py +2831 -0
- ccxt/p2b.py +79 -51
- ccxt/paradex.py +2017 -0
- ccxt/paymium.py +56 -32
- ccxt/phemex.py +572 -196
- ccxt/poloniex.py +218 -95
- ccxt/poloniexfutures.py +260 -92
- ccxt/pro/__init__.py +29 -5
- ccxt/pro/alpaca.py +32 -17
- ccxt/pro/ascendex.py +63 -15
- ccxt/pro/bequant.py +4 -0
- ccxt/pro/binance.py +1596 -329
- ccxt/pro/binancecoinm.py +1 -0
- ccxt/pro/binanceus.py +2 -9
- ccxt/pro/binanceusdm.py +2 -0
- ccxt/pro/bingx.py +527 -134
- ccxt/pro/bitcoincom.py +4 -1
- ccxt/pro/bitfinex.py +731 -266
- ccxt/pro/bitfinex1.py +635 -0
- ccxt/pro/bitget.py +726 -357
- ccxt/pro/bithumb.py +380 -0
- ccxt/pro/bitmart.py +138 -39
- ccxt/pro/bitmex.py +199 -40
- ccxt/pro/bitopro.py +25 -13
- ccxt/pro/bitrue.py +31 -32
- ccxt/pro/bitstamp.py +7 -6
- ccxt/pro/bitvavo.py +204 -82
- ccxt/pro/blockchaincom.py +30 -17
- ccxt/pro/blofin.py +692 -0
- ccxt/pro/bybit.py +791 -82
- ccxt/pro/cex.py +99 -51
- ccxt/pro/coinbase.py +220 -30
- ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
- ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
- ccxt/pro/coinbaseinternational.py +193 -30
- ccxt/pro/coincatch.py +1464 -0
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +967 -661
- ccxt/pro/coinone.py +17 -10
- ccxt/pro/cryptocom.py +446 -66
- ccxt/pro/currencycom.py +11 -10
- ccxt/pro/defx.py +832 -0
- ccxt/pro/deribit.py +168 -32
- ccxt/pro/exmo.py +253 -21
- ccxt/pro/gate.py +729 -64
- ccxt/pro/gemini.py +44 -26
- ccxt/pro/hashkey.py +802 -0
- ccxt/pro/hitbtc.py +208 -103
- ccxt/pro/hollaex.py +25 -9
- ccxt/pro/htx.py +83 -39
- ccxt/pro/huobijp.py +17 -16
- ccxt/pro/hyperliquid.py +502 -31
- ccxt/pro/idex.py +28 -13
- ccxt/pro/independentreserve.py +21 -16
- ccxt/pro/kraken.py +298 -51
- ccxt/pro/krakenfutures.py +166 -75
- ccxt/pro/kucoin.py +395 -77
- ccxt/pro/kucoinfutures.py +400 -99
- ccxt/pro/lbank.py +52 -31
- ccxt/pro/luno.py +12 -10
- ccxt/pro/mexc.py +400 -50
- ccxt/pro/myokx.py +28 -0
- ccxt/pro/ndax.py +25 -12
- ccxt/pro/okcoin.py +28 -9
- ccxt/pro/okx.py +935 -124
- ccxt/pro/onetrading.py +41 -24
- ccxt/pro/oxfun.py +1054 -0
- ccxt/pro/p2b.py +100 -24
- ccxt/pro/paradex.py +352 -0
- ccxt/pro/phemex.py +93 -34
- ccxt/pro/poloniex.py +129 -50
- ccxt/pro/poloniexfutures.py +53 -32
- ccxt/pro/probit.py +93 -86
- ccxt/pro/upbit.py +401 -8
- ccxt/pro/vertex.py +943 -0
- ccxt/pro/wazirx.py +46 -28
- ccxt/pro/whitebit.py +65 -12
- ccxt/pro/woo.py +486 -70
- ccxt/pro/woofipro.py +1271 -0
- ccxt/pro/xt.py +1067 -0
- ccxt/probit.py +143 -110
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/__init__.py +38 -0
- ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
- ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
- ccxt/static_dependencies/lark/ast_utils.py +59 -0
- ccxt/static_dependencies/lark/common.py +86 -0
- ccxt/static_dependencies/lark/exceptions.py +292 -0
- ccxt/static_dependencies/lark/grammar.py +130 -0
- ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
- ccxt/static_dependencies/lark/indenter.py +143 -0
- ccxt/static_dependencies/lark/lark.py +658 -0
- ccxt/static_dependencies/lark/lexer.py +678 -0
- ccxt/static_dependencies/lark/load_grammar.py +1428 -0
- ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
- ccxt/static_dependencies/lark/parser_frontends.py +257 -0
- ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
- ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
- ccxt/static_dependencies/lark/parsers/earley.py +314 -0
- ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
- ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
- ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
- ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
- ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
- ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/lark/reconstruct.py +107 -0
- ccxt/static_dependencies/lark/tools/__init__.py +70 -0
- ccxt/static_dependencies/lark/tools/nearley.py +202 -0
- ccxt/static_dependencies/lark/tools/serialize.py +32 -0
- ccxt/static_dependencies/lark/tools/standalone.py +196 -0
- ccxt/static_dependencies/lark/tree.py +267 -0
- ccxt/static_dependencies/lark/tree_matcher.py +186 -0
- ccxt/static_dependencies/lark/tree_templates.py +180 -0
- ccxt/static_dependencies/lark/utils.py +343 -0
- ccxt/static_dependencies/lark/visitors.py +596 -0
- ccxt/static_dependencies/marshmallow/__init__.py +81 -0
- ccxt/static_dependencies/marshmallow/base.py +65 -0
- ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
- ccxt/static_dependencies/marshmallow/decorators.py +231 -0
- ccxt/static_dependencies/marshmallow/error_store.py +60 -0
- ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
- ccxt/static_dependencies/marshmallow/fields.py +2114 -0
- ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/schema.py +1228 -0
- ccxt/static_dependencies/marshmallow/types.py +12 -0
- ccxt/static_dependencies/marshmallow/utils.py +378 -0
- ccxt/static_dependencies/marshmallow/validate.py +678 -0
- ccxt/static_dependencies/marshmallow/warnings.py +2 -0
- ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
- ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
- ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
- ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
- ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
- ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
- ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/static_dependencies/starknet/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
- ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
- ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
- ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
- ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
- ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
- ccxt/static_dependencies/starknet/common.py +15 -0
- ccxt/static_dependencies/starknet/constants.py +39 -0
- ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
- ccxt/static_dependencies/starknet/hash/address.py +79 -0
- ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
- ccxt/static_dependencies/starknet/hash/selector.py +16 -0
- ccxt/static_dependencies/starknet/hash/storage.py +12 -0
- ccxt/static_dependencies/starknet/hash/utils.py +78 -0
- ccxt/static_dependencies/starknet/models/__init__.py +0 -0
- ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
- ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
- ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
- ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
- ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
- ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
- ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
- ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
- ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
- ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
- ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
- ccxt/static_dependencies/starknet/utils/schema.py +13 -0
- ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
- ccxt/static_dependencies/starkware/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
- ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
- ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
- ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
- ccxt/static_dependencies/sympy/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
- ccxt/static_dependencies/sympy/external/__init__.py +0 -0
- ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
- ccxt/static_dependencies/sympy/external/importtools.py +187 -0
- ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
- ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
- ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
- ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
- ccxt/test/{test_async.py → tests_async.py} +465 -407
- ccxt/test/tests_helpers.py +285 -0
- ccxt/test/tests_init.py +39 -0
- ccxt/test/{test_sync.py → tests_sync.py} +465 -409
- ccxt/timex.py +123 -70
- ccxt/tokocrypto.py +129 -93
- ccxt/tradeogre.py +39 -25
- ccxt/upbit.py +322 -113
- ccxt/vertex.py +2983 -0
- ccxt/wavesexchange.py +227 -173
- ccxt/wazirx.py +145 -65
- ccxt/whitebit.py +533 -138
- ccxt/woo.py +1155 -295
- ccxt/woofipro.py +2716 -0
- ccxt/xt.py +4627 -0
- ccxt/yobit.py +159 -92
- ccxt/zaif.py +80 -33
- ccxt/zonda.py +140 -69
- ccxt-4.4.48.dist-info/LICENSE.txt +21 -0
- ccxt-4.4.48.dist-info/METADATA +646 -0
- ccxt-4.4.48.dist-info/RECORD +669 -0
- {ccxt-4.2.76.dist-info → ccxt-4.4.48.dist-info}/WHEEL +1 -1
- ccxt/abstract/bitbay.py +0 -47
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3496
- ccxt/async_support/flowbtc.py +0 -34
- ccxt/bitbay.py +0 -17
- ccxt/bitfinex2.py +0 -3496
- ccxt/flowbtc.py +0 -34
- ccxt/hitbtc3.py +0 -16
- ccxt/pro/bitfinex2.py +0 -1081
- ccxt/test/base/__init__.py +0 -28
- ccxt/test/base/test_account.py +0 -26
- ccxt/test/base/test_balance.py +0 -56
- ccxt/test/base/test_borrow_interest.py +0 -35
- ccxt/test/base/test_borrow_rate.py +0 -32
- ccxt/test/base/test_calculate_fee.py +0 -51
- ccxt/test/base/test_crypto.py +0 -127
- ccxt/test/base/test_currency.py +0 -76
- ccxt/test/base/test_datetime.py +0 -103
- ccxt/test/base/test_decimal_to_precision.py +0 -392
- ccxt/test/base/test_deep_extend.py +0 -68
- ccxt/test/base/test_deposit_withdrawal.py +0 -50
- ccxt/test/base/test_exchange_datetime_functions.py +0 -76
- ccxt/test/base/test_funding_rate_history.py +0 -29
- ccxt/test/base/test_last_price.py +0 -32
- ccxt/test/base/test_ledger_entry.py +0 -45
- ccxt/test/base/test_ledger_item.py +0 -48
- ccxt/test/base/test_leverage_tier.py +0 -33
- ccxt/test/base/test_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -190
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -32
- ccxt/test/base/test_open_interest.py +0 -32
- ccxt/test/base/test_order.py +0 -64
- ccxt/test/base/test_order_book.py +0 -63
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -345
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -86
- ccxt/test/base/test_trade.py +0 -47
- ccxt/test/base/test_trading_fee.py +0 -26
- ccxt/test/base/test_transaction.py +0 -39
- ccxt-4.2.76.dist-info/METADATA +0 -626
- ccxt-4.2.76.dist-info/RECORD +0 -534
- {ccxt-4.2.76.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
ccxt/pro/bybit.py
CHANGED
@@ -7,13 +7,14 @@ 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, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
|
10
|
+
from ccxt.base.types import Balances, 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
|
+
from typing import Any
|
13
14
|
from ccxt.base.errors import ExchangeError
|
15
|
+
from ccxt.base.errors import AuthenticationError
|
14
16
|
from ccxt.base.errors import ArgumentsRequired
|
15
17
|
from ccxt.base.errors import BadRequest
|
16
|
-
from ccxt.base.errors import AuthenticationError
|
17
18
|
|
18
19
|
|
19
20
|
class bybit(ccxt.async_support.bybit):
|
@@ -22,19 +23,24 @@ class bybit(ccxt.async_support.bybit):
|
|
22
23
|
return self.deep_extend(super(bybit, self).describe(), {
|
23
24
|
'has': {
|
24
25
|
'ws': True,
|
25
|
-
'createOrderWs':
|
26
|
-
'editOrderWs':
|
26
|
+
'createOrderWs': True,
|
27
|
+
'editOrderWs': True,
|
27
28
|
'fetchOpenOrdersWs': False,
|
28
29
|
'fetchOrderWs': False,
|
29
|
-
'cancelOrderWs':
|
30
|
+
'cancelOrderWs': True,
|
30
31
|
'cancelOrdersWs': False,
|
31
32
|
'cancelAllOrdersWs': False,
|
32
33
|
'fetchTradesWs': False,
|
33
34
|
'fetchBalanceWs': False,
|
34
35
|
'watchBalance': True,
|
36
|
+
'watchBidsAsks': True,
|
37
|
+
'watchLiquidations': True,
|
38
|
+
'watchLiquidationsForSymbols': False,
|
39
|
+
'watchMyLiquidations': False,
|
40
|
+
'watchMyLiquidationsForSymbols': False,
|
35
41
|
'watchMyTrades': True,
|
36
42
|
'watchOHLCV': True,
|
37
|
-
'watchOHLCVForSymbols':
|
43
|
+
'watchOHLCVForSymbols': True,
|
38
44
|
'watchOrderBook': True,
|
39
45
|
'watchOrderBookForSymbols': True,
|
40
46
|
'watchOrders': True,
|
@@ -60,6 +66,7 @@ class bybit(ccxt.async_support.bybit):
|
|
60
66
|
},
|
61
67
|
'contract': 'wss://stream.{hostname}/v5/private',
|
62
68
|
'usdc': 'wss://stream.{hostname}/trade/option/usdc/private/v1',
|
69
|
+
'trade': 'wss://stream.bybit.com/v5/trade',
|
63
70
|
},
|
64
71
|
},
|
65
72
|
},
|
@@ -78,6 +85,26 @@ class bybit(ccxt.async_support.bybit):
|
|
78
85
|
},
|
79
86
|
'contract': 'wss://stream-testnet.{hostname}/v5/private',
|
80
87
|
'usdc': 'wss://stream-testnet.{hostname}/trade/option/usdc/private/v1',
|
88
|
+
'trade': 'wss://stream-testnet.bybit.com/v5/trade',
|
89
|
+
},
|
90
|
+
},
|
91
|
+
},
|
92
|
+
'demotrading': {
|
93
|
+
'ws': {
|
94
|
+
'public': {
|
95
|
+
'spot': 'wss://stream.{hostname}/v5/public/spot',
|
96
|
+
'inverse': 'wss://stream.{hostname}/v5/public/inverse',
|
97
|
+
'option': 'wss://stream.{hostname}/v5/public/option',
|
98
|
+
'linear': 'wss://stream.{hostname}/v5/public/linear',
|
99
|
+
},
|
100
|
+
'private': {
|
101
|
+
'spot': {
|
102
|
+
'unified': 'wss://stream-demo.{hostname}/v5/private',
|
103
|
+
'nonUnified': 'wss://stream-demo.{hostname}/spot/private/v3',
|
104
|
+
},
|
105
|
+
'contract': 'wss://stream-demo.{hostname}/v5/private',
|
106
|
+
'usdc': 'wss://stream-demo.{hostname}/trade/option/usdc/private/v1',
|
107
|
+
'trade': 'wss://stream-demo.bybit.com/v5/trade',
|
81
108
|
},
|
82
109
|
},
|
83
110
|
},
|
@@ -90,6 +117,12 @@ class bybit(ccxt.async_support.bybit):
|
|
90
117
|
'fetchPositionsSnapshot': True, # or False
|
91
118
|
'awaitPositionsSnapshot': True, # whether to wait for the positions snapshot before providing updates
|
92
119
|
},
|
120
|
+
'watchMyTrades': {
|
121
|
+
# filter execType: https://bybit-exchange.github.io/docs/api-explorer/v5/position/execution
|
122
|
+
'filterExecTypes': [
|
123
|
+
'Trade', 'AdlTrade', 'BustTrade', 'Settle',
|
124
|
+
],
|
125
|
+
},
|
93
126
|
'spot': {
|
94
127
|
'timeframes': {
|
95
128
|
'1m': '1m',
|
@@ -127,7 +160,7 @@ class bybit(ccxt.async_support.bybit):
|
|
127
160
|
},
|
128
161
|
'streaming': {
|
129
162
|
'ping': self.ping,
|
130
|
-
'keepAlive':
|
163
|
+
'keepAlive': 18000,
|
131
164
|
},
|
132
165
|
})
|
133
166
|
|
@@ -136,7 +169,7 @@ class bybit(ccxt.async_support.bybit):
|
|
136
169
|
self.options['requestId'] = requestId
|
137
170
|
return requestId
|
138
171
|
|
139
|
-
def get_url_by_market_type(self, symbol: Str = None, isPrivate=False, method: Str = None, params={}):
|
172
|
+
async def get_url_by_market_type(self, symbol: Str = None, isPrivate=False, method: Str = None, params={}):
|
140
173
|
accessibility = 'private' if isPrivate else 'public'
|
141
174
|
isUsdcSettled = None
|
142
175
|
isSpot = None
|
@@ -154,11 +187,17 @@ class bybit(ccxt.async_support.bybit):
|
|
154
187
|
isUsdcSettled = (defaultSettle == 'USDC')
|
155
188
|
isSpot = (type == 'spot')
|
156
189
|
if isPrivate:
|
157
|
-
|
190
|
+
unified = await self.isUnifiedEnabled()
|
191
|
+
isUnifiedMargin = self.safe_bool(unified, 0, False)
|
192
|
+
isUnifiedAccount = self.safe_bool(unified, 1, False)
|
193
|
+
if isUsdcSettled and not isUnifiedMargin and not isUnifiedAccount:
|
194
|
+
url = url[accessibility]['usdc']
|
195
|
+
else:
|
196
|
+
url = url[accessibility]['contract']
|
158
197
|
else:
|
159
198
|
if isSpot:
|
160
199
|
url = url[accessibility]['spot']
|
161
|
-
elif type == 'swap':
|
200
|
+
elif (type == 'swap') or (type == 'future'):
|
162
201
|
subType = None
|
163
202
|
subType, params = self.handle_sub_type_and_params(method, market, params, 'linear')
|
164
203
|
url = url[accessibility][subType]
|
@@ -172,11 +211,141 @@ class bybit(ccxt.async_support.bybit):
|
|
172
211
|
params = self.omit(params, ['type', 'subType', 'settle', 'defaultSettle', 'unifiedMargin'])
|
173
212
|
return params
|
174
213
|
|
214
|
+
async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
215
|
+
"""
|
216
|
+
create a trade order
|
217
|
+
|
218
|
+
https://bybit-exchange.github.io/docs/v5/order/create-order
|
219
|
+
https://bybit-exchange.github.io/docs/v5/websocket/trade/guideline#createamendcancel-order
|
220
|
+
|
221
|
+
:param str symbol: unified symbol of the market to create an order in
|
222
|
+
:param str type: 'market' or 'limit'
|
223
|
+
:param str side: 'buy' or 'sell'
|
224
|
+
:param float amount: how much of currency you want to trade in units of base currency
|
225
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
226
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
227
|
+
:param str [params.timeInForce]: "GTC", "IOC", "FOK"
|
228
|
+
:param bool [params.postOnly]: True or False whether the order is post-only
|
229
|
+
:param bool [params.reduceOnly]: True or False whether the order is reduce-only
|
230
|
+
:param str [params.positionIdx]: *contracts only* 0 for one-way mode, 1 buy side of hedged mode, 2 sell side of hedged mode
|
231
|
+
:param boolean [params.isLeverage]: *unified spot only* False then spot trading True then margin trading
|
232
|
+
:param str [params.tpslMode]: *contract only* 'full' or 'partial'
|
233
|
+
:param str [params.mmp]: *option only* market maker protection
|
234
|
+
:param str [params.triggerDirection]: *contract only* the direction for trigger orders, 'above' or 'below'
|
235
|
+
:param float [params.triggerPrice]: The price at which a trigger order is triggered at
|
236
|
+
:param float [params.stopLossPrice]: The price at which a stop loss order is triggered at
|
237
|
+
:param float [params.takeProfitPrice]: The price at which a take profit order is triggered at
|
238
|
+
:param dict [params.takeProfit]: *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered
|
239
|
+
:param float [params.takeProfit.triggerPrice]: take profit trigger price
|
240
|
+
:param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
|
241
|
+
:param float [params.stopLoss.triggerPrice]: stop loss trigger price
|
242
|
+
:param str [params.trailingAmount]: the quote amount to trail away from the current market price
|
243
|
+
:param str [params.trailingTriggerPrice]: the price to trigger a trailing order, default uses the price argument
|
244
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
245
|
+
"""
|
246
|
+
await self.load_markets()
|
247
|
+
orderRequest = self.create_order_request(symbol, type, side, amount, price, params, True)
|
248
|
+
url = self.urls['api']['ws']['private']['trade']
|
249
|
+
await self.authenticate(url)
|
250
|
+
requestId = str(self.request_id())
|
251
|
+
request: dict = {
|
252
|
+
'op': 'order.create',
|
253
|
+
'reqId': requestId,
|
254
|
+
'args': [
|
255
|
+
orderRequest,
|
256
|
+
],
|
257
|
+
'header': {
|
258
|
+
'X-BAPI-TIMESTAMP': str(self.milliseconds()),
|
259
|
+
'X-BAPI-RECV-WINDOW': str(self.options['recvWindow']),
|
260
|
+
},
|
261
|
+
}
|
262
|
+
return await self.watch(url, requestId, request, requestId, True)
|
263
|
+
|
264
|
+
async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
265
|
+
"""
|
266
|
+
edit a trade order
|
267
|
+
|
268
|
+
https://bybit-exchange.github.io/docs/v5/order/amend-order
|
269
|
+
https://bybit-exchange.github.io/docs/v5/websocket/trade/guideline#createamendcancel-order
|
270
|
+
|
271
|
+
:param str id: cancel order id
|
272
|
+
:param str symbol: unified symbol of the market to create an order in
|
273
|
+
:param str type: 'market' or 'limit'
|
274
|
+
:param str side: 'buy' or 'sell'
|
275
|
+
:param float amount: how much of currency you want to trade in units of base currency
|
276
|
+
:param float price: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
277
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
278
|
+
:param float [params.triggerPrice]: The price that a trigger order is triggered at
|
279
|
+
:param float [params.stopLossPrice]: The price that a stop loss order is triggered at
|
280
|
+
:param float [params.takeProfitPrice]: The price that a take profit order is triggered at
|
281
|
+
:param dict [params.takeProfit]: *takeProfit object in params* containing the triggerPrice that the attached take profit order will be triggered
|
282
|
+
:param float [params.takeProfit.triggerPrice]: take profit trigger price
|
283
|
+
:param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice that the attached stop loss order will be triggered
|
284
|
+
:param float [params.stopLoss.triggerPrice]: stop loss trigger price
|
285
|
+
:param str [params.triggerBy]: 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for triggerPrice
|
286
|
+
:param str [params.slTriggerBy]: 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for stopLoss
|
287
|
+
:param str [params.tpTriggerby]: 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for takeProfit
|
288
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
289
|
+
"""
|
290
|
+
await self.load_markets()
|
291
|
+
orderRequest = self.edit_order_request(id, symbol, type, side, amount, price, params)
|
292
|
+
url = self.urls['api']['ws']['private']['trade']
|
293
|
+
await self.authenticate(url)
|
294
|
+
requestId = str(self.request_id())
|
295
|
+
request: dict = {
|
296
|
+
'op': 'order.amend',
|
297
|
+
'reqId': requestId,
|
298
|
+
'args': [
|
299
|
+
orderRequest,
|
300
|
+
],
|
301
|
+
'header': {
|
302
|
+
'X-BAPI-TIMESTAMP': str(self.milliseconds()),
|
303
|
+
'X-BAPI-RECV-WINDOW': str(self.options['recvWindow']),
|
304
|
+
},
|
305
|
+
}
|
306
|
+
return await self.watch(url, requestId, request, requestId, True)
|
307
|
+
|
308
|
+
async def cancel_order_ws(self, id: str, symbol: Str = None, params={}):
|
309
|
+
"""
|
310
|
+
cancels an open order
|
311
|
+
|
312
|
+
https://bybit-exchange.github.io/docs/v5/order/cancel-order
|
313
|
+
https://bybit-exchange.github.io/docs/v5/websocket/trade/guideline#createamendcancel-order
|
314
|
+
|
315
|
+
:param str id: order id
|
316
|
+
:param str symbol: unified symbol of the market the order was made in
|
317
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
318
|
+
:param boolean [params.trigger]: *spot only* whether the order is a trigger order
|
319
|
+
:param str [params.orderFilter]: *spot only* 'Order' or 'StopOrder' or 'tpslOrder'
|
320
|
+
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
321
|
+
"""
|
322
|
+
await self.load_markets()
|
323
|
+
orderRequest = self.cancel_order_request(id, symbol, params)
|
324
|
+
url = self.urls['api']['ws']['private']['trade']
|
325
|
+
await self.authenticate(url)
|
326
|
+
requestId = str(self.request_id())
|
327
|
+
if 'orderFilter' in orderRequest:
|
328
|
+
del orderRequest['orderFilter']
|
329
|
+
request: dict = {
|
330
|
+
'op': 'order.cancel',
|
331
|
+
'reqId': requestId,
|
332
|
+
'args': [
|
333
|
+
orderRequest,
|
334
|
+
],
|
335
|
+
'header': {
|
336
|
+
'X-BAPI-TIMESTAMP': str(self.milliseconds()),
|
337
|
+
'X-BAPI-RECV-WINDOW': str(self.options['recvWindow']),
|
338
|
+
},
|
339
|
+
}
|
340
|
+
return await self.watch(url, requestId, request, requestId, True)
|
341
|
+
|
175
342
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
176
343
|
"""
|
177
344
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
178
|
-
|
179
|
-
|
345
|
+
|
346
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/ticker
|
347
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-ticker
|
348
|
+
|
180
349
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
181
350
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
182
351
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -185,7 +354,7 @@ class bybit(ccxt.async_support.bybit):
|
|
185
354
|
market = self.market(symbol)
|
186
355
|
symbol = market['symbol']
|
187
356
|
messageHash = 'ticker:' + symbol
|
188
|
-
url = self.get_url_by_market_type(symbol, False, 'watchTicker', params)
|
357
|
+
url = await self.get_url_by_market_type(symbol, False, 'watchTicker', params)
|
189
358
|
params = self.clean_params(params)
|
190
359
|
options = self.safe_value(self.options, 'watchTicker', {})
|
191
360
|
topic = self.safe_string(options, 'name', 'tickers')
|
@@ -197,9 +366,11 @@ class bybit(ccxt.async_support.bybit):
|
|
197
366
|
|
198
367
|
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
199
368
|
"""
|
200
|
-
|
201
|
-
|
202
|
-
|
369
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
370
|
+
|
371
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/ticker
|
372
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-ticker
|
373
|
+
|
203
374
|
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
204
375
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
205
376
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -207,7 +378,7 @@ class bybit(ccxt.async_support.bybit):
|
|
207
378
|
await self.load_markets()
|
208
379
|
symbols = self.market_symbols(symbols, None, False)
|
209
380
|
messageHashes = []
|
210
|
-
url = self.get_url_by_market_type(symbols[0], False, 'watchTickers', params)
|
381
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'watchTickers', params)
|
211
382
|
params = self.clean_params(params)
|
212
383
|
options = self.safe_value(self.options, 'watchTickers', {})
|
213
384
|
topic = self.safe_string(options, 'name', 'tickers')
|
@@ -219,11 +390,53 @@ class bybit(ccxt.async_support.bybit):
|
|
219
390
|
messageHashes.append('ticker:' + symbols[i])
|
220
391
|
ticker = await self.watch_topics(url, messageHashes, topics, params)
|
221
392
|
if self.newUpdates:
|
222
|
-
result = {}
|
393
|
+
result: dict = {}
|
223
394
|
result[ticker['symbol']] = ticker
|
224
395
|
return result
|
225
396
|
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
226
397
|
|
398
|
+
async def un_watch_tickers(self, symbols: Strings = None, params={}) -> Any:
|
399
|
+
"""
|
400
|
+
unWatches a price ticker
|
401
|
+
|
402
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/ticker
|
403
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-ticker
|
404
|
+
|
405
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
406
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
407
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
408
|
+
"""
|
409
|
+
await self.load_markets()
|
410
|
+
symbols = self.market_symbols(symbols, None, False)
|
411
|
+
options = self.safe_value(self.options, 'watchTickers', {})
|
412
|
+
topic = self.safe_string(options, 'name', 'tickers')
|
413
|
+
messageHashes = []
|
414
|
+
subMessageHashes = []
|
415
|
+
marketIds = self.market_ids(symbols)
|
416
|
+
topics = []
|
417
|
+
for i in range(0, len(marketIds)):
|
418
|
+
marketId = marketIds[i]
|
419
|
+
symbol = symbols[i]
|
420
|
+
topics.append(topic + '.' + marketId)
|
421
|
+
subMessageHashes.append('ticker:' + symbol)
|
422
|
+
messageHashes.append('unsubscribe:ticker:' + symbol)
|
423
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'watchTickers', params)
|
424
|
+
return await self.un_watch_topics(url, 'ticker', symbols, messageHashes, subMessageHashes, topics, params)
|
425
|
+
|
426
|
+
async def un_watch_ticker(self, symbols: str, params={}) -> Any:
|
427
|
+
"""
|
428
|
+
unWatches a price ticker
|
429
|
+
|
430
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/ticker
|
431
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-ticker
|
432
|
+
|
433
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
434
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
435
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
436
|
+
"""
|
437
|
+
await self.load_markets()
|
438
|
+
return await self.un_watch_tickers([symbols], params)
|
439
|
+
|
227
440
|
def handle_ticker(self, client: Client, message):
|
228
441
|
#
|
229
442
|
# linear
|
@@ -367,11 +580,57 @@ class bybit(ccxt.async_support.bybit):
|
|
367
580
|
messageHash = 'ticker:' + symbol
|
368
581
|
client.resolve(self.tickers[symbol], messageHash)
|
369
582
|
|
583
|
+
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
584
|
+
"""
|
585
|
+
watches best bid & ask for symbols
|
586
|
+
|
587
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
|
588
|
+
|
589
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
590
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
591
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
592
|
+
"""
|
593
|
+
await self.load_markets()
|
594
|
+
symbols = self.market_symbols(symbols, None, False)
|
595
|
+
messageHashes = []
|
596
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'watchBidsAsks', params)
|
597
|
+
params = self.clean_params(params)
|
598
|
+
marketIds = self.market_ids(symbols)
|
599
|
+
topics = []
|
600
|
+
for i in range(0, len(marketIds)):
|
601
|
+
marketId = marketIds[i]
|
602
|
+
topic = 'orderbook.1.' + marketId
|
603
|
+
topics.append(topic)
|
604
|
+
messageHashes.append('bidask:' + symbols[i])
|
605
|
+
ticker = await self.watch_topics(url, messageHashes, topics, params)
|
606
|
+
if self.newUpdates:
|
607
|
+
return ticker
|
608
|
+
return self.filter_by_array(self.bidsasks, 'symbol', symbols)
|
609
|
+
|
610
|
+
def parse_ws_bid_ask(self, orderbook, market=None):
|
611
|
+
timestamp = self.safe_integer(orderbook, 'timestamp')
|
612
|
+
bids = self.sort_by(self.aggregate(orderbook['bids']), 0)
|
613
|
+
asks = self.sort_by(self.aggregate(orderbook['asks']), 0)
|
614
|
+
bestBid = self.safe_list(bids, 0, [])
|
615
|
+
bestAsk = self.safe_list(asks, 0, [])
|
616
|
+
return self.safe_ticker({
|
617
|
+
'symbol': market['symbol'],
|
618
|
+
'timestamp': timestamp,
|
619
|
+
'datetime': self.iso8601(timestamp),
|
620
|
+
'ask': self.safe_number(bestAsk, 0),
|
621
|
+
'askVolume': self.safe_number(bestAsk, 1),
|
622
|
+
'bid': self.safe_number(bestBid, 0),
|
623
|
+
'bidVolume': self.safe_number(bestBid, 1),
|
624
|
+
'info': orderbook,
|
625
|
+
}, market)
|
626
|
+
|
370
627
|
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
371
628
|
"""
|
372
629
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
373
|
-
|
374
|
-
|
630
|
+
|
631
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/kline
|
632
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
|
633
|
+
|
375
634
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
376
635
|
:param str timeframe: the length of time each candle represents
|
377
636
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
@@ -379,19 +638,93 @@ class bybit(ccxt.async_support.bybit):
|
|
379
638
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
380
639
|
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
381
640
|
"""
|
641
|
+
params['callerMethodName'] = 'watchOHLCV'
|
642
|
+
result = await self.watch_ohlcv_for_symbols([[symbol, timeframe]], since, limit, params)
|
643
|
+
return result[symbol][timeframe]
|
644
|
+
|
645
|
+
async def watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], since: Int = None, limit: Int = None, params={}):
|
646
|
+
"""
|
647
|
+
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
648
|
+
|
649
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/kline
|
650
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
|
651
|
+
|
652
|
+
:param str[][] symbolsAndTimeframes: array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
653
|
+
:param int [since]: timestamp in ms of the earliest candle to fetch
|
654
|
+
:param int [limit]: the maximum amount of candles to fetch
|
655
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
656
|
+
:returns dict: A list of candles ordered, open, high, low, close, volume
|
657
|
+
"""
|
382
658
|
await self.load_markets()
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
659
|
+
symbols = self.get_list_from_object_values(symbolsAndTimeframes, 0)
|
660
|
+
marketSymbols = self.market_symbols(symbols, None, False, True, True)
|
661
|
+
firstSymbol = marketSymbols[0]
|
662
|
+
url = await self.get_url_by_market_type(firstSymbol, False, 'watchOHLCVForSymbols', params)
|
663
|
+
rawHashes = []
|
664
|
+
messageHashes = []
|
665
|
+
for i in range(0, len(symbolsAndTimeframes)):
|
666
|
+
data = symbolsAndTimeframes[i]
|
667
|
+
symbolString = self.safe_string(data, 0)
|
668
|
+
market = self.market(symbolString)
|
669
|
+
symbolString = market['symbol']
|
670
|
+
unfiedTimeframe = self.safe_string(data, 1)
|
671
|
+
timeframeId = self.safe_string(self.timeframes, unfiedTimeframe, unfiedTimeframe)
|
672
|
+
rawHashes.append('kline.' + timeframeId + '.' + market['id'])
|
673
|
+
messageHashes.append('ohlcv::' + symbolString + '::' + unfiedTimeframe)
|
674
|
+
symbol, timeframe, stored = await self.watch_topics(url, messageHashes, rawHashes, params)
|
392
675
|
if self.newUpdates:
|
393
|
-
limit =
|
394
|
-
|
676
|
+
limit = stored.getLimit(symbol, limit)
|
677
|
+
filtered = self.filter_by_since_limit(stored, since, limit, 0, True)
|
678
|
+
return self.create_ohlcv_object(symbol, timeframe, filtered)
|
679
|
+
|
680
|
+
async def un_watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], params={}) -> Any:
|
681
|
+
"""
|
682
|
+
unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
683
|
+
|
684
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/kline
|
685
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
|
686
|
+
|
687
|
+
:param str[][] symbolsAndTimeframes: array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
688
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
689
|
+
:returns dict: A list of candles ordered, open, high, low, close, volume
|
690
|
+
"""
|
691
|
+
await self.load_markets()
|
692
|
+
symbols = self.get_list_from_object_values(symbolsAndTimeframes, 0)
|
693
|
+
marketSymbols = self.market_symbols(symbols, None, False, True, True)
|
694
|
+
firstSymbol = marketSymbols[0]
|
695
|
+
url = await self.get_url_by_market_type(firstSymbol, False, 'watchOHLCVForSymbols', params)
|
696
|
+
rawHashes = []
|
697
|
+
subMessageHashes = []
|
698
|
+
messageHashes = []
|
699
|
+
for i in range(0, len(symbolsAndTimeframes)):
|
700
|
+
data = symbolsAndTimeframes[i]
|
701
|
+
symbolString = self.safe_string(data, 0)
|
702
|
+
market = self.market(symbolString)
|
703
|
+
symbolString = market['symbol']
|
704
|
+
unfiedTimeframe = self.safe_string(data, 1)
|
705
|
+
timeframeId = self.safe_string(self.timeframes, unfiedTimeframe, unfiedTimeframe)
|
706
|
+
rawHashes.append('kline.' + timeframeId + '.' + market['id'])
|
707
|
+
subMessageHashes.append('ohlcv::' + symbolString + '::' + unfiedTimeframe)
|
708
|
+
messageHashes.append('unsubscribe::ohlcv::' + symbolString + '::' + unfiedTimeframe)
|
709
|
+
subExtension = {
|
710
|
+
'symbolsAndTimeframes': symbolsAndTimeframes,
|
711
|
+
}
|
712
|
+
return await self.un_watch_topics(url, 'ohlcv', symbols, messageHashes, subMessageHashes, rawHashes, params, subExtension)
|
713
|
+
|
714
|
+
async def un_watch_ohlcv(self, symbol: str, timeframe='1m', params={}) -> Any:
|
715
|
+
"""
|
716
|
+
unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
717
|
+
|
718
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/kline
|
719
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
|
720
|
+
|
721
|
+
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
722
|
+
:param str timeframe: the length of time each candle represents
|
723
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
724
|
+
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
725
|
+
"""
|
726
|
+
params['callerMethodName'] = 'watchOHLCV'
|
727
|
+
return await self.un_watch_ohlcv_for_symbols([[symbol, timeframe]], params)
|
395
728
|
|
396
729
|
def handle_ohlcv(self, client: Client, message):
|
397
730
|
#
|
@@ -430,16 +763,16 @@ class bybit(ccxt.async_support.bybit):
|
|
430
763
|
ohlcvsByTimeframe = self.safe_value(self.ohlcvs, symbol)
|
431
764
|
if ohlcvsByTimeframe is None:
|
432
765
|
self.ohlcvs[symbol] = {}
|
433
|
-
|
434
|
-
if stored is None:
|
766
|
+
if self.safe_value(ohlcvsByTimeframe, timeframe) is None:
|
435
767
|
limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
|
436
|
-
|
437
|
-
|
768
|
+
self.ohlcvs[symbol][timeframe] = ArrayCacheByTimestamp(limit)
|
769
|
+
stored = self.ohlcvs[symbol][timeframe]
|
438
770
|
for i in range(0, len(data)):
|
439
771
|
parsed = self.parse_ws_ohlcv(data[i])
|
440
772
|
stored.append(parsed)
|
441
|
-
messageHash = '
|
442
|
-
|
773
|
+
messageHash = 'ohlcv::' + symbol + '::' + timeframe
|
774
|
+
resolveData = [symbol, timeframe, stored]
|
775
|
+
client.resolve(resolveData, messageHash)
|
443
776
|
|
444
777
|
def parse_ws_ohlcv(self, ohlcv, market=None) -> list:
|
445
778
|
#
|
@@ -469,7 +802,9 @@ class bybit(ccxt.async_support.bybit):
|
|
469
802
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
470
803
|
"""
|
471
804
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
472
|
-
|
805
|
+
|
806
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
|
807
|
+
|
473
808
|
:param str symbol: unified symbol of the market to fetch the order book for
|
474
809
|
:param int [limit]: the maximum amount of order book entries to return.
|
475
810
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -480,7 +815,9 @@ class bybit(ccxt.async_support.bybit):
|
|
480
815
|
async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
|
481
816
|
"""
|
482
817
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
483
|
-
|
818
|
+
|
819
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
|
820
|
+
|
484
821
|
:param str[] symbols: unified array of symbols
|
485
822
|
:param int [limit]: the maximum amount of order book entries to return.
|
486
823
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -491,7 +828,7 @@ class bybit(ccxt.async_support.bybit):
|
|
491
828
|
if symbolsLength == 0:
|
492
829
|
raise ArgumentsRequired(self.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols')
|
493
830
|
symbols = self.market_symbols(symbols)
|
494
|
-
url = self.get_url_by_market_type(symbols[0], False, 'watchOrderBook', params)
|
831
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'watchOrderBook', params)
|
495
832
|
params = self.clean_params(params)
|
496
833
|
market = self.market(symbols[0])
|
497
834
|
if limit is None:
|
@@ -513,6 +850,55 @@ class bybit(ccxt.async_support.bybit):
|
|
513
850
|
orderbook = await self.watch_topics(url, messageHashes, topics, params)
|
514
851
|
return orderbook.limit()
|
515
852
|
|
853
|
+
async def un_watch_order_book_for_symbols(self, symbols: Strings, params={}) -> Any:
|
854
|
+
"""
|
855
|
+
unsubscribe from the orderbook channel
|
856
|
+
|
857
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
|
858
|
+
|
859
|
+
:param str[] symbols: unified symbol of the market to unwatch the trades for
|
860
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
861
|
+
:param int [params.limit]: orderbook limit, default is None
|
862
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
863
|
+
"""
|
864
|
+
await self.load_markets()
|
865
|
+
symbols = self.market_symbols(symbols, None, False)
|
866
|
+
channel = 'orderbook.'
|
867
|
+
limit = self.safe_integer(params, 'limit')
|
868
|
+
if limit is not None:
|
869
|
+
params = self.omit(params, 'limit')
|
870
|
+
else:
|
871
|
+
firstMarket = self.market(symbols[0])
|
872
|
+
limit = 50 if firstMarket['spot'] else 500
|
873
|
+
channel += str(limit)
|
874
|
+
subMessageHashes = []
|
875
|
+
messageHashes = []
|
876
|
+
topics = []
|
877
|
+
for i in range(0, len(symbols)):
|
878
|
+
symbol = symbols[i]
|
879
|
+
market = self.market(symbol)
|
880
|
+
marketId = market['id']
|
881
|
+
topic = channel + '.' + marketId
|
882
|
+
messageHashes.append('unsubscribe:orderbook:' + symbol)
|
883
|
+
subMessageHashes.append('orderbook:' + symbol)
|
884
|
+
topics.append(topic)
|
885
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'watchOrderBook', params)
|
886
|
+
return await self.un_watch_topics(url, 'orderbook', symbols, messageHashes, subMessageHashes, topics, params)
|
887
|
+
|
888
|
+
async def un_watch_order_book(self, symbol: str, params={}) -> Any:
|
889
|
+
"""
|
890
|
+
unsubscribe from the orderbook channel
|
891
|
+
|
892
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
|
893
|
+
|
894
|
+
:param str symbol: symbol of the market to unwatch the trades for
|
895
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
896
|
+
:param int [params.limit]: orderbook limit, default is None
|
897
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
898
|
+
"""
|
899
|
+
await self.load_markets()
|
900
|
+
return await self.un_watch_order_book_for_symbols([symbol], params)
|
901
|
+
|
516
902
|
def handle_order_book(self, client: Client, message):
|
517
903
|
#
|
518
904
|
# {
|
@@ -547,24 +933,26 @@ class bybit(ccxt.async_support.bybit):
|
|
547
933
|
# }
|
548
934
|
# }
|
549
935
|
#
|
936
|
+
topic = self.safe_string(message, 'topic')
|
937
|
+
limit = topic.split('.')[1]
|
550
938
|
isSpot = client.url.find('spot') >= 0
|
551
939
|
type = self.safe_string(message, 'type')
|
552
940
|
isSnapshot = (type == 'snapshot')
|
553
|
-
data = self.
|
941
|
+
data = self.safe_dict(message, 'data', {})
|
554
942
|
marketId = self.safe_string(data, 's')
|
555
943
|
marketType = 'spot' if isSpot else 'contract'
|
556
944
|
market = self.safe_market(marketId, None, None, marketType)
|
557
945
|
symbol = market['symbol']
|
558
946
|
timestamp = self.safe_integer(message, 'ts')
|
559
|
-
|
560
|
-
|
561
|
-
|
947
|
+
if not (symbol in self.orderbooks):
|
948
|
+
self.orderbooks[symbol] = self.order_book()
|
949
|
+
orderbook = self.orderbooks[symbol]
|
562
950
|
if isSnapshot:
|
563
951
|
snapshot = self.parse_order_book(data, symbol, timestamp, 'b', 'a')
|
564
952
|
orderbook.reset(snapshot)
|
565
953
|
else:
|
566
|
-
asks = self.
|
567
|
-
bids = self.
|
954
|
+
asks = self.safe_list(data, 'a', [])
|
955
|
+
bids = self.safe_list(data, 'b', [])
|
568
956
|
self.handle_deltas(orderbook['asks'], asks)
|
569
957
|
self.handle_deltas(orderbook['bids'], bids)
|
570
958
|
orderbook['timestamp'] = timestamp
|
@@ -572,6 +960,12 @@ class bybit(ccxt.async_support.bybit):
|
|
572
960
|
messageHash = 'orderbook' + ':' + symbol
|
573
961
|
self.orderbooks[symbol] = orderbook
|
574
962
|
client.resolve(orderbook, messageHash)
|
963
|
+
if limit == '1':
|
964
|
+
bidask = self.parse_ws_bid_ask(self.orderbooks[symbol], market)
|
965
|
+
newBidsAsks: dict = {}
|
966
|
+
newBidsAsks[symbol] = bidask
|
967
|
+
self.bidsasks[symbol] = bidask
|
968
|
+
client.resolve(newBidsAsks, 'bidask:' + symbol)
|
575
969
|
|
576
970
|
def handle_delta(self, bookside, delta):
|
577
971
|
bidAsk = self.parse_bid_ask(delta, 0, 1)
|
@@ -584,19 +978,23 @@ class bybit(ccxt.async_support.bybit):
|
|
584
978
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
585
979
|
"""
|
586
980
|
watches information on multiple trades made in a market
|
587
|
-
|
981
|
+
|
982
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/trade
|
983
|
+
|
588
984
|
:param str symbol: unified market symbol of the market trades were made in
|
589
985
|
:param int [since]: the earliest time in ms to fetch trades for
|
590
986
|
:param int [limit]: the maximum number of trade structures to retrieve
|
591
987
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
592
|
-
:returns dict[]: a list of
|
988
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
593
989
|
"""
|
594
990
|
return await self.watch_trades_for_symbols([symbol], since, limit, params)
|
595
991
|
|
596
992
|
async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
597
993
|
"""
|
598
994
|
get the list of most recent trades for a list of symbols
|
599
|
-
|
995
|
+
|
996
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/trade
|
997
|
+
|
600
998
|
:param str[] symbols: unified symbol of the market to fetch trades for
|
601
999
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
602
1000
|
:param int [limit]: the maximum amount of trades to fetch
|
@@ -609,7 +1007,7 @@ class bybit(ccxt.async_support.bybit):
|
|
609
1007
|
if symbolsLength == 0:
|
610
1008
|
raise ArgumentsRequired(self.id + ' watchTradesForSymbols() requires a non-empty array of symbols')
|
611
1009
|
params = self.clean_params(params)
|
612
|
-
url = self.get_url_by_market_type(symbols[0], False, 'watchTrades', params)
|
1010
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'watchTrades', params)
|
613
1011
|
topics = []
|
614
1012
|
messageHashes = []
|
615
1013
|
for i in range(0, len(symbols)):
|
@@ -626,6 +1024,45 @@ class bybit(ccxt.async_support.bybit):
|
|
626
1024
|
limit = trades.getLimit(tradeSymbol, limit)
|
627
1025
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
628
1026
|
|
1027
|
+
async def un_watch_trades_for_symbols(self, symbols: Strings, params={}) -> Any:
|
1028
|
+
"""
|
1029
|
+
unsubscribe from the trades channel
|
1030
|
+
|
1031
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/trade
|
1032
|
+
|
1033
|
+
:param str[] symbols: unified symbol of the market to unwatch the trades for
|
1034
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1035
|
+
:returns any: status of the unwatch request
|
1036
|
+
"""
|
1037
|
+
await self.load_markets()
|
1038
|
+
symbols = self.market_symbols(symbols, None, False, True)
|
1039
|
+
url = await self.get_url_by_market_type(symbols[0], False, 'unWatchTradesForSymbols', params)
|
1040
|
+
messageHashes = []
|
1041
|
+
topics = []
|
1042
|
+
subMessageHashes = []
|
1043
|
+
for i in range(0, len(symbols)):
|
1044
|
+
symbol = symbols[i]
|
1045
|
+
market = self.market(symbol)
|
1046
|
+
topic = 'publicTrade.' + market['id']
|
1047
|
+
topics.append(topic)
|
1048
|
+
messageHash = 'unsubscribe:trade:' + symbol
|
1049
|
+
messageHashes.append(messageHash)
|
1050
|
+
subMessageHashes.append('trade:' + symbol)
|
1051
|
+
return await self.un_watch_topics(url, 'trades', symbols, messageHashes, subMessageHashes, topics, params)
|
1052
|
+
|
1053
|
+
async def un_watch_trades(self, symbol: str, params={}) -> Any:
|
1054
|
+
"""
|
1055
|
+
unsubscribe from the trades channel
|
1056
|
+
|
1057
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/trade
|
1058
|
+
|
1059
|
+
:param str symbol: unified symbol of the market to unwatch the trades for
|
1060
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1061
|
+
:returns any: status of the unwatch request
|
1062
|
+
"""
|
1063
|
+
await self.load_markets()
|
1064
|
+
return await self.un_watch_trades_for_symbols([symbol], params)
|
1065
|
+
|
629
1066
|
def handle_trades(self, client: Client, message):
|
630
1067
|
#
|
631
1068
|
# {
|
@@ -745,13 +1182,15 @@ class bybit(ccxt.async_support.bybit):
|
|
745
1182
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
746
1183
|
"""
|
747
1184
|
watches information on multiple trades made by the user
|
748
|
-
|
1185
|
+
|
1186
|
+
https://bybit-exchange.github.io/docs/v5/websocket/private/execution
|
1187
|
+
|
749
1188
|
:param str symbol: unified market symbol of the market orders were made in
|
750
1189
|
:param int [since]: the earliest time in ms to fetch orders for
|
751
1190
|
:param int [limit]: the maximum number of order structures to retrieve
|
752
1191
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
753
1192
|
:param boolean [params.unifiedMargin]: use unified margin account
|
754
|
-
:returns dict[]: a list of
|
1193
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
755
1194
|
"""
|
756
1195
|
method = 'watchMyTrades'
|
757
1196
|
messageHash = 'myTrades'
|
@@ -759,9 +1198,9 @@ class bybit(ccxt.async_support.bybit):
|
|
759
1198
|
if symbol is not None:
|
760
1199
|
symbol = self.symbol(symbol)
|
761
1200
|
messageHash += ':' + symbol
|
762
|
-
url = self.get_url_by_market_type(symbol, True, method, params)
|
1201
|
+
url = await self.get_url_by_market_type(symbol, True, method, params)
|
763
1202
|
await self.authenticate(url)
|
764
|
-
topicByMarket = {
|
1203
|
+
topicByMarket: dict = {
|
765
1204
|
'spot': 'ticketInfo',
|
766
1205
|
'unified': 'execution',
|
767
1206
|
'usdc': 'user.openapi.perp.trade',
|
@@ -772,6 +1211,34 @@ class bybit(ccxt.async_support.bybit):
|
|
772
1211
|
limit = trades.getLimit(symbol, limit)
|
773
1212
|
return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
|
774
1213
|
|
1214
|
+
async def un_watch_my_trades(self, symbol: Str = None, params={}) -> Any:
|
1215
|
+
"""
|
1216
|
+
unWatches information on multiple trades made by the user
|
1217
|
+
|
1218
|
+
https://bybit-exchange.github.io/docs/v5/websocket/private/execution
|
1219
|
+
|
1220
|
+
:param str symbol: unified market symbol of the market orders were made in
|
1221
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1222
|
+
:param boolean [params.unifiedMargin]: use unified margin account
|
1223
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1224
|
+
"""
|
1225
|
+
method = 'watchMyTrades'
|
1226
|
+
messageHash = 'unsubscribe:myTrades'
|
1227
|
+
subHash = 'myTrades'
|
1228
|
+
await self.load_markets()
|
1229
|
+
if symbol is not None:
|
1230
|
+
symbol = self.symbol(symbol)
|
1231
|
+
subHash += ':' + symbol
|
1232
|
+
url = await self.get_url_by_market_type(symbol, True, method, params)
|
1233
|
+
await self.authenticate(url)
|
1234
|
+
topicByMarket: dict = {
|
1235
|
+
'spot': 'ticketInfo',
|
1236
|
+
'unified': 'execution',
|
1237
|
+
'usdc': 'user.openapi.perp.trade',
|
1238
|
+
}
|
1239
|
+
topic = self.safe_value(topicByMarket, self.get_private_type(url))
|
1240
|
+
return await self.un_watch_topics(url, 'myTrades', [], [messageHash], [subHash], [topic], params)
|
1241
|
+
|
775
1242
|
def handle_my_trades(self, client: Client, message):
|
776
1243
|
#
|
777
1244
|
# spot
|
@@ -844,13 +1311,18 @@ class bybit(ccxt.async_support.bybit):
|
|
844
1311
|
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
845
1312
|
self.myTrades = ArrayCacheBySymbolById(limit)
|
846
1313
|
trades = self.myTrades
|
847
|
-
symbols = {}
|
1314
|
+
symbols: dict = {}
|
1315
|
+
filterExecTypes = self.handle_option('watchMyTrades', 'filterExecTypes', [])
|
848
1316
|
for i in range(0, len(data)):
|
849
1317
|
rawTrade = data[i]
|
850
1318
|
parsed = None
|
851
1319
|
if spot:
|
852
1320
|
parsed = self.parse_ws_trade(rawTrade)
|
853
1321
|
else:
|
1322
|
+
# filter unified trades
|
1323
|
+
execType = self.safe_string(rawTrade, 'execType', '')
|
1324
|
+
if not self.in_array(execType, filterExecTypes):
|
1325
|
+
continue
|
854
1326
|
parsed = self.parse_trade(rawTrade)
|
855
1327
|
symbol = parsed['symbol']
|
856
1328
|
symbols[symbol] = True
|
@@ -865,9 +1337,13 @@ class bybit(ccxt.async_support.bybit):
|
|
865
1337
|
|
866
1338
|
async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
|
867
1339
|
"""
|
868
|
-
|
1340
|
+
|
1341
|
+
https://bybit-exchange.github.io/docs/v5/websocket/private/position
|
1342
|
+
|
869
1343
|
watch all open positions
|
870
1344
|
:param str[] [symbols]: list of unified market symbols
|
1345
|
+
:param int [since]: the earliest time in ms to fetch positions for
|
1346
|
+
:param int [limit]: the maximum number of positions to retrieve
|
871
1347
|
:param dict params: extra parameters specific to the exchange API endpoint
|
872
1348
|
:returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
|
873
1349
|
"""
|
@@ -878,14 +1354,14 @@ class bybit(ccxt.async_support.bybit):
|
|
878
1354
|
symbols = self.market_symbols(symbols)
|
879
1355
|
messageHash = '::' + ','.join(symbols)
|
880
1356
|
firstSymbol = self.safe_string(symbols, 0)
|
881
|
-
url = self.get_url_by_market_type(firstSymbol, True, method, params)
|
1357
|
+
url = await self.get_url_by_market_type(firstSymbol, True, method, params)
|
882
1358
|
messageHash = 'positions' + messageHash
|
883
1359
|
client = self.client(url)
|
884
1360
|
await self.authenticate(url)
|
885
1361
|
self.set_positions_cache(client, symbols)
|
886
1362
|
cache = self.positions
|
887
1363
|
fetchPositionsSnapshot = self.handle_option('watchPositions', 'fetchPositionsSnapshot', True)
|
888
|
-
awaitPositionsSnapshot = self.
|
1364
|
+
awaitPositionsSnapshot = self.handle_option('watchPositions', 'awaitPositionsSnapshot', True)
|
889
1365
|
if fetchPositionsSnapshot and awaitPositionsSnapshot and cache is None:
|
890
1366
|
snapshot = await client.future('fetchPositionsSnapshot')
|
891
1367
|
return self.filter_by_symbols_since_limit(snapshot, symbols, since, limit, True)
|
@@ -974,8 +1450,21 @@ class bybit(ccxt.async_support.bybit):
|
|
974
1450
|
for i in range(0, len(rawPositions)):
|
975
1451
|
rawPosition = rawPositions[i]
|
976
1452
|
position = self.parse_position(rawPosition)
|
1453
|
+
side = self.safe_string(position, 'side')
|
1454
|
+
# hacky solution to handle closing positions
|
1455
|
+
# without crashing, we should handle self properly later
|
977
1456
|
newPositions.append(position)
|
978
|
-
|
1457
|
+
if side is None or side == '':
|
1458
|
+
# closing update, adding both sides to "reset" both sides
|
1459
|
+
# since we don't know which side is being closed
|
1460
|
+
position['side'] = 'long'
|
1461
|
+
cache.append(position)
|
1462
|
+
position['side'] = 'short'
|
1463
|
+
cache.append(position)
|
1464
|
+
position['side'] = None
|
1465
|
+
else:
|
1466
|
+
# regular update
|
1467
|
+
cache.append(position)
|
979
1468
|
messageHashes = self.find_message_hashes(client, 'positions::')
|
980
1469
|
for i in range(0, len(messageHashes)):
|
981
1470
|
messageHash = messageHashes[i]
|
@@ -987,15 +1476,95 @@ class bybit(ccxt.async_support.bybit):
|
|
987
1476
|
client.resolve(positions, messageHash)
|
988
1477
|
client.resolve(newPositions, 'positions')
|
989
1478
|
|
1479
|
+
async def watch_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
1480
|
+
"""
|
1481
|
+
watch the public liquidations of a trading pair
|
1482
|
+
|
1483
|
+
https://bybit-exchange.github.io/docs/v5/websocket/public/liquidation
|
1484
|
+
|
1485
|
+
:param str symbol: unified CCXT market symbol
|
1486
|
+
:param int [since]: the earliest time in ms to fetch liquidations for
|
1487
|
+
:param int [limit]: the maximum number of liquidation structures to retrieve
|
1488
|
+
:param dict [params]: exchange specific parameters for the bitmex api endpoint
|
1489
|
+
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
1490
|
+
"""
|
1491
|
+
await self.load_markets()
|
1492
|
+
market = self.market(symbol)
|
1493
|
+
symbol = market['symbol']
|
1494
|
+
url = await self.get_url_by_market_type(symbol, False, 'watchLiquidations', params)
|
1495
|
+
params = self.clean_params(params)
|
1496
|
+
messageHash = 'liquidations::' + symbol
|
1497
|
+
topic = 'liquidation.' + market['id']
|
1498
|
+
newLiquidation = await self.watch_topics(url, [messageHash], [topic], params)
|
1499
|
+
if self.newUpdates:
|
1500
|
+
return newLiquidation
|
1501
|
+
return self.filter_by_symbols_since_limit(self.liquidations, [symbol], since, limit, True)
|
1502
|
+
|
1503
|
+
def handle_liquidation(self, client: Client, message):
|
1504
|
+
#
|
1505
|
+
# {
|
1506
|
+
# "data": {
|
1507
|
+
# "price": "0.03803",
|
1508
|
+
# "side": "Buy",
|
1509
|
+
# "size": "1637",
|
1510
|
+
# "symbol": "GALAUSDT",
|
1511
|
+
# "updatedTime": 1673251091822
|
1512
|
+
# },
|
1513
|
+
# "topic": "liquidation.GALAUSDT",
|
1514
|
+
# "ts": 1673251091822,
|
1515
|
+
# "type": "snapshot"
|
1516
|
+
# }
|
1517
|
+
#
|
1518
|
+
rawLiquidation = self.safe_dict(message, 'data', {})
|
1519
|
+
marketId = self.safe_string(rawLiquidation, 'symbol')
|
1520
|
+
market = self.safe_market(marketId, None, '', 'contract')
|
1521
|
+
symbol = market['symbol']
|
1522
|
+
liquidation = self.parse_ws_liquidation(rawLiquidation, market)
|
1523
|
+
liquidations = self.safe_value(self.liquidations, symbol)
|
1524
|
+
if liquidations is None:
|
1525
|
+
limit = self.safe_integer(self.options, 'liquidationsLimit', 1000)
|
1526
|
+
liquidations = ArrayCache(limit)
|
1527
|
+
liquidations.append(liquidation)
|
1528
|
+
self.liquidations[symbol] = liquidations
|
1529
|
+
client.resolve([liquidation], 'liquidations')
|
1530
|
+
client.resolve([liquidation], 'liquidations::' + symbol)
|
1531
|
+
|
1532
|
+
def parse_ws_liquidation(self, liquidation, market=None):
|
1533
|
+
#
|
1534
|
+
# {
|
1535
|
+
# "price": "0.03803",
|
1536
|
+
# "side": "Buy",
|
1537
|
+
# "size": "1637",
|
1538
|
+
# "symbol": "GALAUSDT",
|
1539
|
+
# "updatedTime": 1673251091822
|
1540
|
+
# }
|
1541
|
+
#
|
1542
|
+
marketId = self.safe_string(liquidation, 'symbol')
|
1543
|
+
market = self.safe_market(marketId, market, '', 'contract')
|
1544
|
+
timestamp = self.safe_integer(liquidation, 'updatedTime')
|
1545
|
+
return self.safe_liquidation({
|
1546
|
+
'info': liquidation,
|
1547
|
+
'symbol': market['symbol'],
|
1548
|
+
'contracts': self.safe_number(liquidation, 'size'),
|
1549
|
+
'contractSize': self.safe_number(market, 'contractSize'),
|
1550
|
+
'price': self.safe_number(liquidation, 'price'),
|
1551
|
+
'baseValue': None,
|
1552
|
+
'quoteValue': None,
|
1553
|
+
'timestamp': timestamp,
|
1554
|
+
'datetime': self.iso8601(timestamp),
|
1555
|
+
})
|
1556
|
+
|
990
1557
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
991
1558
|
"""
|
992
1559
|
watches information on multiple orders made by the user
|
993
|
-
|
1560
|
+
|
1561
|
+
https://bybit-exchange.github.io/docs/v5/websocket/private/order
|
1562
|
+
|
994
1563
|
:param str symbol: unified market symbol of the market orders were made in
|
995
1564
|
:param int [since]: the earliest time in ms to fetch orders for
|
996
1565
|
:param int [limit]: the maximum number of order structures to retrieve
|
997
1566
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
998
|
-
:returns dict[]: a list of
|
1567
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
999
1568
|
"""
|
1000
1569
|
await self.load_markets()
|
1001
1570
|
method = 'watchOrders'
|
@@ -1003,9 +1572,9 @@ class bybit(ccxt.async_support.bybit):
|
|
1003
1572
|
if symbol is not None:
|
1004
1573
|
symbol = self.symbol(symbol)
|
1005
1574
|
messageHash += ':' + symbol
|
1006
|
-
url = self.get_url_by_market_type(symbol, True, method, params)
|
1575
|
+
url = await self.get_url_by_market_type(symbol, True, method, params)
|
1007
1576
|
await self.authenticate(url)
|
1008
|
-
topicsByMarket = {
|
1577
|
+
topicsByMarket: dict = {
|
1009
1578
|
'spot': ['order', 'stopOrder'],
|
1010
1579
|
'unified': ['order'],
|
1011
1580
|
'usdc': ['user.openapi.perp.order'],
|
@@ -1016,6 +1585,60 @@ class bybit(ccxt.async_support.bybit):
|
|
1016
1585
|
limit = orders.getLimit(symbol, limit)
|
1017
1586
|
return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
|
1018
1587
|
|
1588
|
+
async def un_watch_orders(self, symbol: Str = None, params={}) -> Any:
|
1589
|
+
"""
|
1590
|
+
unWatches information on multiple orders made by the user
|
1591
|
+
|
1592
|
+
https://bybit-exchange.github.io/docs/v5/websocket/private/order
|
1593
|
+
|
1594
|
+
:param str symbol: unified market symbol of the market orders were made in
|
1595
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1596
|
+
:param boolean [params.unifiedMargin]: use unified margin account
|
1597
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1598
|
+
"""
|
1599
|
+
await self.load_markets()
|
1600
|
+
method = 'watchOrders'
|
1601
|
+
messageHash = 'unsubscribe:orders'
|
1602
|
+
subHash = 'orders'
|
1603
|
+
if symbol is not None:
|
1604
|
+
symbol = self.symbol(symbol)
|
1605
|
+
subHash += ':' + symbol
|
1606
|
+
url = await self.get_url_by_market_type(symbol, True, method, params)
|
1607
|
+
await self.authenticate(url)
|
1608
|
+
topicsByMarket: dict = {
|
1609
|
+
'spot': ['order', 'stopOrder'],
|
1610
|
+
'unified': ['order'],
|
1611
|
+
'usdc': ['user.openapi.perp.order'],
|
1612
|
+
}
|
1613
|
+
topics = self.safe_value(topicsByMarket, self.get_private_type(url))
|
1614
|
+
return await self.un_watch_topics(url, 'orders', [], [messageHash], [subHash], topics, params)
|
1615
|
+
|
1616
|
+
def handle_order_ws(self, client: Client, message):
|
1617
|
+
#
|
1618
|
+
# {
|
1619
|
+
# "reqId":"1",
|
1620
|
+
# "retCode":0,
|
1621
|
+
# "retMsg":"OK",
|
1622
|
+
# "op":"order.create",
|
1623
|
+
# "data":{
|
1624
|
+
# "orderId":"1673523595617593600",
|
1625
|
+
# "orderLinkId":"1673523595617593601"
|
1626
|
+
# },
|
1627
|
+
# "header":{
|
1628
|
+
# "X-Bapi-Limit":"20",
|
1629
|
+
# "X-Bapi-Limit-Status":"19",
|
1630
|
+
# "X-Bapi-Limit-Reset-Timestamp":"1714235558880",
|
1631
|
+
# "Traceid":"584a06d373f2fdcb3a4dfdd81d27df11",
|
1632
|
+
# "Timenow":"1714235558881"
|
1633
|
+
# },
|
1634
|
+
# "connId":"cojidqec0hv9fgvhtbt0-40e"
|
1635
|
+
# }
|
1636
|
+
#
|
1637
|
+
messageHash = self.safe_string(message, 'reqId')
|
1638
|
+
data = self.safe_dict(message, 'data')
|
1639
|
+
order = self.parse_order(data)
|
1640
|
+
client.resolve(order, messageHash)
|
1641
|
+
|
1019
1642
|
def handle_order(self, client: Client, message):
|
1020
1643
|
#
|
1021
1644
|
# spot
|
@@ -1110,7 +1733,7 @@ class bybit(ccxt.async_support.bybit):
|
|
1110
1733
|
isSpot = category == 'spot'
|
1111
1734
|
if not isSpot:
|
1112
1735
|
rawOrders = self.safe_value(rawOrders, 'result', rawOrders)
|
1113
|
-
symbols = {}
|
1736
|
+
symbols: dict = {}
|
1114
1737
|
for i in range(0, len(rawOrders)):
|
1115
1738
|
parsed = None
|
1116
1739
|
if isSpot:
|
@@ -1261,7 +1884,9 @@ class bybit(ccxt.async_support.bybit):
|
|
1261
1884
|
async def watch_balance(self, params={}) -> Balances:
|
1262
1885
|
"""
|
1263
1886
|
watch balance and get the amount of funds available for trading or funds locked in orders
|
1264
|
-
|
1887
|
+
|
1888
|
+
https://bybit-exchange.github.io/docs/v5/websocket/private/wallet
|
1889
|
+
|
1265
1890
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1266
1891
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
1267
1892
|
"""
|
@@ -1275,9 +1900,9 @@ class bybit(ccxt.async_support.bybit):
|
|
1275
1900
|
unified = await self.isUnifiedEnabled()
|
1276
1901
|
isUnifiedMargin = self.safe_bool(unified, 0, False)
|
1277
1902
|
isUnifiedAccount = self.safe_bool(unified, 1, False)
|
1278
|
-
url = self.get_url_by_market_type(None, True, method, params)
|
1903
|
+
url = await self.get_url_by_market_type(None, True, method, params)
|
1279
1904
|
await self.authenticate(url)
|
1280
|
-
topicByMarket = {
|
1905
|
+
topicByMarket: dict = {
|
1281
1906
|
'spot': 'outboundAccountInfo',
|
1282
1907
|
'unified': 'wallet',
|
1283
1908
|
}
|
@@ -1530,13 +2155,30 @@ class bybit(ccxt.async_support.bybit):
|
|
1530
2155
|
self.balance[code] = account
|
1531
2156
|
|
1532
2157
|
async def watch_topics(self, url, messageHashes, topics, params={}):
|
1533
|
-
request = {
|
2158
|
+
request: dict = {
|
1534
2159
|
'op': 'subscribe',
|
1535
2160
|
'req_id': self.request_id(),
|
1536
2161
|
'args': topics,
|
1537
2162
|
}
|
1538
2163
|
message = self.extend(request, params)
|
1539
|
-
return await self.watch_multiple(url, messageHashes, message,
|
2164
|
+
return await self.watch_multiple(url, messageHashes, message, messageHashes)
|
2165
|
+
|
2166
|
+
async def un_watch_topics(self, url: str, topic: str, symbols: List[str], messageHashes: List[str], subMessageHashes: List[str], topics, params={}, subExtension={}):
|
2167
|
+
reqId = self.request_id()
|
2168
|
+
request: dict = {
|
2169
|
+
'op': 'unsubscribe',
|
2170
|
+
'req_id': reqId,
|
2171
|
+
'args': topics,
|
2172
|
+
}
|
2173
|
+
subscription = {
|
2174
|
+
'id': reqId,
|
2175
|
+
'topic': topic,
|
2176
|
+
'messageHashes': messageHashes,
|
2177
|
+
'subMessageHashes': subMessageHashes,
|
2178
|
+
'symbols': symbols,
|
2179
|
+
}
|
2180
|
+
message = self.extend(request, params)
|
2181
|
+
return await self.watch_multiple(url, messageHashes, message, messageHashes, self.extend(subscription, subExtension))
|
1540
2182
|
|
1541
2183
|
async def authenticate(self, url, params={}):
|
1542
2184
|
self.check_required_credentials()
|
@@ -1550,7 +2192,7 @@ class bybit(ccxt.async_support.bybit):
|
|
1550
2192
|
path = 'GET/realtime'
|
1551
2193
|
auth = path + expires
|
1552
2194
|
signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256, 'hex')
|
1553
|
-
request = {
|
2195
|
+
request: dict = {
|
1554
2196
|
'op': 'auth',
|
1555
2197
|
'args': [
|
1556
2198
|
self.apiKey, expires, signature,
|
@@ -1586,11 +2228,32 @@ class bybit(ccxt.async_support.bybit):
|
|
1586
2228
|
#
|
1587
2229
|
# {code: '-10009', desc: "Invalid period!"}
|
1588
2230
|
#
|
1589
|
-
|
2231
|
+
# {
|
2232
|
+
# "reqId":"1",
|
2233
|
+
# "retCode":170131,
|
2234
|
+
# "retMsg":"Insufficient balance.",
|
2235
|
+
# "op":"order.create",
|
2236
|
+
# "data":{
|
2237
|
+
#
|
2238
|
+
# },
|
2239
|
+
# "header":{
|
2240
|
+
# "X-Bapi-Limit":"20",
|
2241
|
+
# "X-Bapi-Limit-Status":"19",
|
2242
|
+
# "X-Bapi-Limit-Reset-Timestamp":"1714236608944",
|
2243
|
+
# "Traceid":"3d7168a137bf32a947b7e5e6a575ac7f",
|
2244
|
+
# "Timenow":"1714236608946"
|
2245
|
+
# },
|
2246
|
+
# "connId":"cojifin88smerbj9t560-406"
|
2247
|
+
# }
|
2248
|
+
#
|
2249
|
+
code = self.safe_string_n(message, ['code', 'ret_code', 'retCode'])
|
1590
2250
|
try:
|
1591
|
-
if code is not None:
|
2251
|
+
if code is not None and code != '0':
|
1592
2252
|
feedback = self.id + ' ' + self.json(message)
|
1593
2253
|
self.throw_exactly_matched_exception(self.exceptions['exact'], code, feedback)
|
2254
|
+
msg = self.safe_string_2(message, 'retMsg', 'ret_msg')
|
2255
|
+
self.throw_broadly_matched_exception(self.exceptions['broad'], msg, feedback)
|
2256
|
+
raise ExchangeError(feedback)
|
1594
2257
|
success = self.safe_value(message, 'success')
|
1595
2258
|
if success is not None and not success:
|
1596
2259
|
ret_msg = self.safe_string(message, 'ret_msg')
|
@@ -1608,7 +2271,8 @@ class bybit(ccxt.async_support.bybit):
|
|
1608
2271
|
if messageHash in client.subscriptions:
|
1609
2272
|
del client.subscriptions[messageHash]
|
1610
2273
|
else:
|
1611
|
-
|
2274
|
+
messageHash = self.safe_string(message, 'reqId')
|
2275
|
+
client.reject(error, messageHash)
|
1612
2276
|
return True
|
1613
2277
|
|
1614
2278
|
def handle_message(self, client: Client, message):
|
@@ -1625,16 +2289,12 @@ class bybit(ccxt.async_support.bybit):
|
|
1625
2289
|
self.handle_pong(client, message)
|
1626
2290
|
return
|
1627
2291
|
# pong
|
1628
|
-
op = self.safe_string(message, 'op')
|
1629
|
-
if op == 'pong':
|
1630
|
-
self.handle_pong(client, message)
|
1631
|
-
return
|
1632
2292
|
event = self.safe_string(message, 'event')
|
1633
2293
|
if event == 'sub':
|
1634
2294
|
self.handle_subscription_status(client, message)
|
1635
2295
|
return
|
1636
|
-
topic = self.
|
1637
|
-
methods = {
|
2296
|
+
topic = self.safe_string_2(message, 'topic', 'op', '')
|
2297
|
+
methods: dict = {
|
1638
2298
|
'orderbook': self.handle_order_book,
|
1639
2299
|
'kline': self.handle_ohlcv,
|
1640
2300
|
'order': self.handle_order,
|
@@ -1649,6 +2309,13 @@ class bybit(ccxt.async_support.bybit):
|
|
1649
2309
|
'ticketInfo': self.handle_my_trades,
|
1650
2310
|
'user.openapi.perp.trade': self.handle_my_trades,
|
1651
2311
|
'position': self.handle_positions,
|
2312
|
+
'liquidation': self.handle_liquidation,
|
2313
|
+
'pong': self.handle_pong,
|
2314
|
+
'order.create': self.handle_order_ws,
|
2315
|
+
'order.amend': self.handle_order_ws,
|
2316
|
+
'order.cancel': self.handle_order_ws,
|
2317
|
+
'auth': self.handle_authenticate,
|
2318
|
+
'unsubscribe': self.handle_un_subscribe,
|
1652
2319
|
}
|
1653
2320
|
exacMethod = self.safe_value(methods, topic)
|
1654
2321
|
if exacMethod is not None:
|
@@ -1663,10 +2330,10 @@ class bybit(ccxt.async_support.bybit):
|
|
1663
2330
|
return
|
1664
2331
|
# unified auth acknowledgement
|
1665
2332
|
type = self.safe_string(message, 'type')
|
1666
|
-
if
|
2333
|
+
if type == 'AUTH_RESP':
|
1667
2334
|
self.handle_authenticate(client, message)
|
1668
2335
|
|
1669
|
-
def ping(self, client):
|
2336
|
+
def ping(self, client: Client):
|
1670
2337
|
return {
|
1671
2338
|
'req_id': self.request_id(),
|
1672
2339
|
'op': 'ping',
|
@@ -1695,9 +2362,17 @@ class bybit(ccxt.async_support.bybit):
|
|
1695
2362
|
# "conn_id": "ce3dpomvha7dha97tvp0-2xh"
|
1696
2363
|
# }
|
1697
2364
|
#
|
2365
|
+
# {
|
2366
|
+
# "retCode":0,
|
2367
|
+
# "retMsg":"OK",
|
2368
|
+
# "op":"auth",
|
2369
|
+
# "connId":"cojifin88smerbj9t560-404"
|
2370
|
+
# }
|
2371
|
+
#
|
1698
2372
|
success = self.safe_value(message, 'success')
|
2373
|
+
code = self.safe_integer(message, 'retCode')
|
1699
2374
|
messageHash = 'authenticated'
|
1700
|
-
if success:
|
2375
|
+
if success or code == 0:
|
1701
2376
|
future = self.safe_value(client.futures, messageHash)
|
1702
2377
|
future.resolve(True)
|
1703
2378
|
else:
|
@@ -1723,3 +2398,37 @@ class bybit(ccxt.async_support.bybit):
|
|
1723
2398
|
# }
|
1724
2399
|
#
|
1725
2400
|
return message
|
2401
|
+
|
2402
|
+
def handle_un_subscribe(self, client: Client, message):
|
2403
|
+
#
|
2404
|
+
# {"success":true,"ret_msg":"","conn_id":"7188110e-6908-41e9-b863-6365127e92ad","req_id":"3","op":"unsubscribe"}
|
2405
|
+
#
|
2406
|
+
# client.subscription will be something like:
|
2407
|
+
# {
|
2408
|
+
# "publicTrade.LTCUSDT":true,
|
2409
|
+
# "publicTrade.ADAUSDT":true,
|
2410
|
+
# "unsubscribe:trade:LTC/USDT:USDT": {
|
2411
|
+
# "id":4,
|
2412
|
+
# "subHash": "trade:LTC/USDT"
|
2413
|
+
# },
|
2414
|
+
# }
|
2415
|
+
reqId = self.safe_string(message, 'req_id')
|
2416
|
+
keys = list(client.subscriptions.keys())
|
2417
|
+
for i in range(0, len(keys)):
|
2418
|
+
messageHash = keys[i]
|
2419
|
+
if not (messageHash in client.subscriptions):
|
2420
|
+
continue
|
2421
|
+
# the previous iteration can have deleted the messageHash from the subscriptions
|
2422
|
+
if messageHash.startswith('unsubscribe'):
|
2423
|
+
subscription = client.subscriptions[messageHash]
|
2424
|
+
subId = self.safe_string(subscription, 'id')
|
2425
|
+
if reqId != subId:
|
2426
|
+
continue
|
2427
|
+
messageHashes = self.safe_list(subscription, 'messageHashes', [])
|
2428
|
+
subMessageHashes = self.safe_list(subscription, 'subMessageHashes', [])
|
2429
|
+
for j in range(0, len(messageHashes)):
|
2430
|
+
unsubHash = messageHashes[j]
|
2431
|
+
subHash = subMessageHashes[j]
|
2432
|
+
self.clean_unsubscription(client, subHash, unsubHash)
|
2433
|
+
self.clean_cache(subscription)
|
2434
|
+
return message
|