ccxt 4.2.77__py2.py3-none-any.whl → 4.4.49__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +36 -14
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +112 -48
- ccxt/abstract/binancecoinm.py +112 -48
- ccxt/abstract/binanceus.py +147 -83
- ccxt/abstract/binanceusdm.py +112 -48
- ccxt/abstract/bingx.py +133 -78
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitfinex1.py +69 -0
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +8 -1
- ccxt/abstract/bitmart.py +13 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitpanda.py +0 -12
- ccxt/abstract/bitrue.py +3 -3
- ccxt/abstract/bitstamp.py +26 -3
- ccxt/abstract/blofin.py +24 -0
- ccxt/abstract/btcbox.py +1 -0
- ccxt/abstract/bybit.py +29 -14
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbase.py +6 -0
- ccxt/abstract/coinbaseadvanced.py +94 -0
- ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/coincatch.py +94 -0
- ccxt/abstract/coinex.py +233 -123
- ccxt/abstract/coinmetro.py +1 -0
- ccxt/abstract/cryptocom.py +14 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/gate.py +20 -0
- ccxt/abstract/gateio.py +20 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hashkey.py +67 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +4 -3
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +24 -0
- ccxt/abstract/kucoinfutures.py +34 -0
- ccxt/abstract/luno.py +2 -0
- ccxt/abstract/mexc.py +4 -0
- ccxt/abstract/myokx.py +340 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +30 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/oxfun.py +34 -0
- ccxt/abstract/paradex.py +40 -0
- ccxt/abstract/phemex.py +1 -0
- ccxt/abstract/upbit.py +4 -0
- ccxt/abstract/vertex.py +19 -0
- ccxt/abstract/whitebit.py +31 -1
- ccxt/abstract/woo.py +6 -2
- ccxt/abstract/woofipro.py +119 -0
- ccxt/abstract/xt.py +153 -0
- ccxt/abstract/zonda.py +6 -0
- ccxt/ace.py +164 -60
- ccxt/alpaca.py +727 -63
- ccxt/ascendex.py +395 -249
- ccxt/async_support/__init__.py +36 -14
- ccxt/async_support/ace.py +164 -60
- ccxt/async_support/alpaca.py +727 -63
- ccxt/async_support/ascendex.py +396 -249
- ccxt/async_support/base/exchange.py +531 -155
- ccxt/async_support/base/ws/aiohttp_client.py +28 -5
- ccxt/async_support/base/ws/cache.py +3 -2
- ccxt/async_support/base/ws/client.py +26 -5
- ccxt/async_support/base/ws/fast_client.py +4 -3
- ccxt/async_support/base/ws/functions.py +1 -1
- ccxt/async_support/base/ws/future.py +40 -31
- ccxt/async_support/base/ws/order_book_side.py +3 -0
- ccxt/async_support/bequant.py +1 -1
- ccxt/async_support/bigone.py +329 -202
- ccxt/async_support/binance.py +3030 -1087
- ccxt/async_support/binancecoinm.py +2 -1
- ccxt/async_support/binanceus.py +12 -1
- ccxt/async_support/binanceusdm.py +3 -1
- ccxt/async_support/bingx.py +3205 -937
- ccxt/async_support/bit2c.py +119 -38
- ccxt/async_support/bitbank.py +215 -76
- ccxt/async_support/bitbns.py +124 -53
- ccxt/async_support/bitfinex.py +3236 -1078
- ccxt/async_support/bitfinex1.py +1711 -0
- ccxt/async_support/bitflyer.py +238 -49
- ccxt/async_support/bitget.py +1525 -573
- ccxt/async_support/bithumb.py +199 -65
- ccxt/async_support/bitmart.py +1320 -435
- ccxt/async_support/bitmex.py +308 -111
- ccxt/async_support/bitopro.py +256 -96
- ccxt/async_support/bitrue.py +365 -233
- ccxt/async_support/bitso.py +201 -89
- ccxt/async_support/bitstamp.py +438 -269
- ccxt/async_support/bitteam.py +179 -73
- ccxt/async_support/bitvavo.py +180 -70
- ccxt/async_support/bl3p.py +92 -25
- ccxt/async_support/blockchaincom.py +193 -79
- ccxt/async_support/blofin.py +392 -148
- ccxt/async_support/btcalpha.py +161 -55
- ccxt/async_support/btcbox.py +250 -34
- ccxt/async_support/btcmarkets.py +232 -85
- ccxt/async_support/btcturk.py +159 -60
- ccxt/async_support/bybit.py +2231 -1193
- ccxt/async_support/cex.py +1409 -1329
- ccxt/async_support/coinbase.py +1454 -287
- ccxt/async_support/coinbaseadvanced.py +17 -0
- ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/async_support/coinbaseinternational.py +428 -88
- ccxt/async_support/coincatch.py +5152 -0
- ccxt/async_support/coincheck.py +121 -38
- ccxt/async_support/coinex.py +4020 -3339
- ccxt/async_support/coinlist.py +273 -116
- ccxt/async_support/coinmate.py +204 -97
- ccxt/async_support/coinmetro.py +203 -110
- ccxt/async_support/coinone.py +142 -68
- ccxt/async_support/coinsph.py +223 -97
- ccxt/async_support/coinspot.py +137 -62
- ccxt/async_support/cryptocom.py +515 -185
- ccxt/async_support/currencycom.py +203 -85
- ccxt/async_support/defx.py +2066 -0
- ccxt/async_support/delta.py +404 -109
- ccxt/async_support/deribit.py +639 -323
- ccxt/async_support/digifinex.py +465 -233
- ccxt/async_support/ellipx.py +1887 -0
- ccxt/async_support/exmo.py +317 -128
- ccxt/async_support/gate.py +1472 -463
- ccxt/async_support/gemini.py +206 -84
- ccxt/async_support/hashkey.py +4164 -0
- ccxt/async_support/hitbtc.py +433 -178
- ccxt/async_support/hollaex.py +207 -83
- ccxt/async_support/htx.py +1095 -563
- ccxt/async_support/huobijp.py +178 -56
- ccxt/async_support/hyperliquid.py +1678 -292
- ccxt/async_support/idex.py +219 -95
- ccxt/async_support/independentreserve.py +300 -31
- ccxt/async_support/indodax.py +226 -62
- ccxt/async_support/kraken.py +871 -354
- ccxt/async_support/krakenfutures.py +324 -100
- ccxt/async_support/kucoin.py +917 -357
- ccxt/async_support/kucoinfutures.py +1004 -149
- ccxt/async_support/kuna.py +198 -107
- ccxt/async_support/latoken.py +199 -79
- ccxt/async_support/lbank.py +360 -113
- ccxt/async_support/luno.py +185 -62
- ccxt/async_support/lykke.py +168 -55
- ccxt/async_support/mercado.py +101 -29
- ccxt/async_support/mexc.py +995 -429
- ccxt/async_support/myokx.py +53 -0
- ccxt/async_support/ndax.py +234 -82
- ccxt/async_support/novadax.py +195 -75
- ccxt/async_support/oceanex.py +244 -59
- ccxt/async_support/okcoin.py +301 -165
- ccxt/async_support/okx.py +1776 -454
- ccxt/async_support/onetrading.py +198 -414
- ccxt/async_support/oxfun.py +2898 -0
- ccxt/async_support/p2b.py +142 -52
- ccxt/async_support/paradex.py +2085 -0
- ccxt/async_support/paymium.py +56 -32
- ccxt/async_support/phemex.py +572 -196
- ccxt/async_support/poloniex.py +218 -95
- ccxt/async_support/poloniexfutures.py +260 -92
- ccxt/async_support/probit.py +143 -110
- ccxt/async_support/timex.py +123 -70
- ccxt/async_support/tokocrypto.py +129 -93
- ccxt/async_support/tradeogre.py +39 -25
- ccxt/async_support/upbit.py +322 -113
- ccxt/async_support/vertex.py +2983 -0
- ccxt/async_support/wavesexchange.py +227 -173
- ccxt/async_support/wazirx.py +145 -65
- ccxt/async_support/whitebit.py +533 -138
- ccxt/async_support/woo.py +1137 -296
- ccxt/async_support/woofipro.py +2716 -0
- ccxt/async_support/xt.py +4628 -0
- ccxt/async_support/yobit.py +160 -92
- ccxt/async_support/zaif.py +80 -33
- ccxt/async_support/zonda.py +140 -69
- ccxt/base/errors.py +51 -20
- ccxt/base/exchange.py +1722 -480
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +223 -4
- ccxt/bequant.py +1 -1
- ccxt/bigone.py +329 -202
- ccxt/binance.py +3030 -1087
- ccxt/binancecoinm.py +2 -1
- ccxt/binanceus.py +12 -1
- ccxt/binanceusdm.py +3 -1
- ccxt/bingx.py +3205 -937
- ccxt/bit2c.py +119 -38
- ccxt/bitbank.py +215 -76
- ccxt/bitbns.py +124 -53
- ccxt/bitfinex.py +3235 -1078
- ccxt/bitfinex1.py +1710 -0
- ccxt/bitflyer.py +238 -49
- ccxt/bitget.py +1525 -573
- ccxt/bithumb.py +198 -65
- ccxt/bitmart.py +1320 -435
- ccxt/bitmex.py +308 -111
- ccxt/bitopro.py +256 -96
- ccxt/bitrue.py +365 -233
- ccxt/bitso.py +201 -89
- ccxt/bitstamp.py +438 -269
- ccxt/bitteam.py +179 -73
- ccxt/bitvavo.py +180 -70
- ccxt/bl3p.py +92 -25
- ccxt/blockchaincom.py +193 -79
- ccxt/blofin.py +392 -148
- ccxt/btcalpha.py +161 -55
- ccxt/btcbox.py +250 -34
- ccxt/btcmarkets.py +232 -85
- ccxt/btcturk.py +159 -60
- ccxt/bybit.py +2231 -1193
- ccxt/cex.py +1408 -1329
- ccxt/coinbase.py +1454 -287
- ccxt/coinbaseadvanced.py +17 -0
- ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/coinbaseinternational.py +428 -88
- ccxt/coincatch.py +5152 -0
- ccxt/coincheck.py +121 -38
- ccxt/coinex.py +4020 -3339
- ccxt/coinlist.py +273 -116
- ccxt/coinmate.py +204 -97
- ccxt/coinmetro.py +203 -110
- ccxt/coinone.py +142 -68
- ccxt/coinsph.py +223 -97
- ccxt/coinspot.py +137 -62
- ccxt/cryptocom.py +515 -185
- ccxt/currencycom.py +203 -85
- ccxt/defx.py +2065 -0
- ccxt/delta.py +404 -109
- ccxt/deribit.py +639 -323
- ccxt/digifinex.py +465 -233
- ccxt/ellipx.py +1887 -0
- ccxt/exmo.py +317 -128
- ccxt/gate.py +1472 -463
- ccxt/gemini.py +206 -84
- ccxt/hashkey.py +4164 -0
- ccxt/hitbtc.py +433 -178
- ccxt/hollaex.py +207 -83
- ccxt/htx.py +1095 -563
- ccxt/huobijp.py +178 -56
- ccxt/hyperliquid.py +1677 -292
- ccxt/idex.py +219 -95
- ccxt/independentreserve.py +299 -31
- ccxt/indodax.py +226 -62
- ccxt/kraken.py +871 -354
- ccxt/krakenfutures.py +324 -100
- ccxt/kucoin.py +917 -357
- ccxt/kucoinfutures.py +1004 -149
- ccxt/kuna.py +198 -107
- ccxt/latoken.py +199 -79
- ccxt/lbank.py +360 -113
- ccxt/luno.py +185 -62
- ccxt/lykke.py +168 -55
- ccxt/mercado.py +101 -29
- ccxt/mexc.py +994 -429
- ccxt/myokx.py +53 -0
- ccxt/ndax.py +234 -82
- ccxt/novadax.py +195 -75
- ccxt/oceanex.py +244 -59
- ccxt/okcoin.py +301 -165
- ccxt/okx.py +1776 -454
- ccxt/onetrading.py +198 -414
- ccxt/oxfun.py +2897 -0
- ccxt/p2b.py +142 -52
- ccxt/paradex.py +2085 -0
- ccxt/paymium.py +56 -32
- ccxt/phemex.py +572 -196
- ccxt/poloniex.py +218 -95
- ccxt/poloniexfutures.py +260 -92
- ccxt/pro/__init__.py +29 -5
- ccxt/pro/alpaca.py +32 -17
- ccxt/pro/ascendex.py +62 -14
- ccxt/pro/bequant.py +4 -0
- ccxt/pro/binance.py +1596 -329
- ccxt/pro/binancecoinm.py +1 -0
- ccxt/pro/binanceus.py +2 -9
- ccxt/pro/binanceusdm.py +2 -0
- ccxt/pro/bingx.py +527 -134
- ccxt/pro/bitcoincom.py +4 -1
- ccxt/pro/bitfinex.py +731 -266
- ccxt/pro/bitfinex1.py +635 -0
- ccxt/pro/bitget.py +726 -357
- ccxt/pro/bithumb.py +380 -0
- ccxt/pro/bitmart.py +143 -39
- ccxt/pro/bitmex.py +199 -40
- ccxt/pro/bitopro.py +25 -13
- ccxt/pro/bitrue.py +31 -32
- ccxt/pro/bitstamp.py +7 -6
- ccxt/pro/bitvavo.py +203 -81
- ccxt/pro/blockchaincom.py +30 -17
- ccxt/pro/blofin.py +692 -0
- ccxt/pro/bybit.py +791 -82
- ccxt/pro/cex.py +99 -51
- ccxt/pro/coinbase.py +220 -30
- ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
- ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
- ccxt/pro/coinbaseinternational.py +193 -30
- ccxt/pro/coincatch.py +1464 -0
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +965 -665
- ccxt/pro/coinone.py +17 -10
- ccxt/pro/cryptocom.py +446 -66
- ccxt/pro/currencycom.py +11 -10
- ccxt/pro/defx.py +832 -0
- ccxt/pro/deribit.py +167 -31
- ccxt/pro/exmo.py +252 -20
- ccxt/pro/gate.py +729 -64
- ccxt/pro/gemini.py +44 -26
- ccxt/pro/hashkey.py +802 -0
- ccxt/pro/hitbtc.py +208 -103
- ccxt/pro/hollaex.py +25 -9
- ccxt/pro/htx.py +83 -39
- ccxt/pro/huobijp.py +17 -16
- ccxt/pro/hyperliquid.py +502 -31
- ccxt/pro/idex.py +28 -13
- ccxt/pro/independentreserve.py +21 -16
- ccxt/pro/kraken.py +298 -51
- ccxt/pro/krakenfutures.py +166 -75
- ccxt/pro/kucoin.py +395 -77
- ccxt/pro/kucoinfutures.py +400 -99
- ccxt/pro/lbank.py +52 -31
- ccxt/pro/luno.py +12 -10
- ccxt/pro/mexc.py +400 -50
- ccxt/pro/myokx.py +28 -0
- ccxt/pro/ndax.py +25 -12
- ccxt/pro/okcoin.py +28 -9
- ccxt/pro/okx.py +935 -124
- ccxt/pro/onetrading.py +41 -24
- ccxt/pro/oxfun.py +1054 -0
- ccxt/pro/p2b.py +100 -24
- ccxt/pro/paradex.py +352 -0
- ccxt/pro/phemex.py +92 -33
- ccxt/pro/poloniex.py +128 -49
- ccxt/pro/poloniexfutures.py +53 -32
- ccxt/pro/probit.py +92 -85
- ccxt/pro/upbit.py +401 -8
- ccxt/pro/vertex.py +943 -0
- ccxt/pro/wazirx.py +46 -28
- ccxt/pro/whitebit.py +65 -12
- ccxt/pro/woo.py +437 -65
- ccxt/pro/woofipro.py +1271 -0
- ccxt/pro/xt.py +1067 -0
- ccxt/probit.py +143 -110
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/__init__.py +38 -0
- ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
- ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
- ccxt/static_dependencies/lark/ast_utils.py +59 -0
- ccxt/static_dependencies/lark/common.py +86 -0
- ccxt/static_dependencies/lark/exceptions.py +292 -0
- ccxt/static_dependencies/lark/grammar.py +130 -0
- ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
- ccxt/static_dependencies/lark/indenter.py +143 -0
- ccxt/static_dependencies/lark/lark.py +658 -0
- ccxt/static_dependencies/lark/lexer.py +678 -0
- ccxt/static_dependencies/lark/load_grammar.py +1428 -0
- ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
- ccxt/static_dependencies/lark/parser_frontends.py +257 -0
- ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
- ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
- ccxt/static_dependencies/lark/parsers/earley.py +314 -0
- ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
- ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
- ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
- ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
- ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
- ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/lark/reconstruct.py +107 -0
- ccxt/static_dependencies/lark/tools/__init__.py +70 -0
- ccxt/static_dependencies/lark/tools/nearley.py +202 -0
- ccxt/static_dependencies/lark/tools/serialize.py +32 -0
- ccxt/static_dependencies/lark/tools/standalone.py +196 -0
- ccxt/static_dependencies/lark/tree.py +267 -0
- ccxt/static_dependencies/lark/tree_matcher.py +186 -0
- ccxt/static_dependencies/lark/tree_templates.py +180 -0
- ccxt/static_dependencies/lark/utils.py +343 -0
- ccxt/static_dependencies/lark/visitors.py +596 -0
- ccxt/static_dependencies/marshmallow/__init__.py +81 -0
- ccxt/static_dependencies/marshmallow/base.py +65 -0
- ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
- ccxt/static_dependencies/marshmallow/decorators.py +231 -0
- ccxt/static_dependencies/marshmallow/error_store.py +60 -0
- ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
- ccxt/static_dependencies/marshmallow/fields.py +2114 -0
- ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/schema.py +1228 -0
- ccxt/static_dependencies/marshmallow/types.py +12 -0
- ccxt/static_dependencies/marshmallow/utils.py +378 -0
- ccxt/static_dependencies/marshmallow/validate.py +678 -0
- ccxt/static_dependencies/marshmallow/warnings.py +2 -0
- ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
- ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
- ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
- ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
- ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
- ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
- ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/static_dependencies/starknet/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
- ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
- ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
- ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
- ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
- ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
- ccxt/static_dependencies/starknet/common.py +15 -0
- ccxt/static_dependencies/starknet/constants.py +39 -0
- ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
- ccxt/static_dependencies/starknet/hash/address.py +79 -0
- ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
- ccxt/static_dependencies/starknet/hash/selector.py +16 -0
- ccxt/static_dependencies/starknet/hash/storage.py +12 -0
- ccxt/static_dependencies/starknet/hash/utils.py +78 -0
- ccxt/static_dependencies/starknet/models/__init__.py +0 -0
- ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
- ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
- ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
- ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
- ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
- ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
- ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
- ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
- ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
- ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
- ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
- ccxt/static_dependencies/starknet/utils/schema.py +13 -0
- ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
- ccxt/static_dependencies/starkware/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
- ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
- ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
- ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
- ccxt/static_dependencies/sympy/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
- ccxt/static_dependencies/sympy/external/__init__.py +0 -0
- ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
- ccxt/static_dependencies/sympy/external/importtools.py +187 -0
- ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
- ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
- ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
- ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
- ccxt/test/{test_async.py → tests_async.py} +456 -391
- ccxt/test/tests_helpers.py +285 -0
- ccxt/test/tests_init.py +39 -0
- ccxt/test/{test_sync.py → tests_sync.py} +456 -393
- ccxt/timex.py +123 -70
- ccxt/tokocrypto.py +129 -93
- ccxt/tradeogre.py +39 -25
- ccxt/upbit.py +322 -113
- ccxt/vertex.py +2983 -0
- ccxt/wavesexchange.py +227 -173
- ccxt/wazirx.py +145 -65
- ccxt/whitebit.py +533 -138
- ccxt/woo.py +1137 -296
- ccxt/woofipro.py +2716 -0
- ccxt/xt.py +4627 -0
- ccxt/yobit.py +159 -92
- ccxt/zaif.py +80 -33
- ccxt/zonda.py +140 -69
- ccxt-4.4.49.dist-info/LICENSE.txt +21 -0
- ccxt-4.4.49.dist-info/METADATA +646 -0
- ccxt-4.4.49.dist-info/RECORD +669 -0
- {ccxt-4.2.77.dist-info → ccxt-4.4.49.dist-info}/WHEEL +1 -1
- ccxt/abstract/bitbay.py +0 -47
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3496
- ccxt/async_support/flowbtc.py +0 -34
- ccxt/bitbay.py +0 -17
- ccxt/bitfinex2.py +0 -3496
- ccxt/flowbtc.py +0 -34
- ccxt/hitbtc3.py +0 -16
- ccxt/pro/bitfinex2.py +0 -1081
- ccxt/test/base/__init__.py +0 -28
- ccxt/test/base/test_account.py +0 -26
- ccxt/test/base/test_balance.py +0 -56
- ccxt/test/base/test_borrow_interest.py +0 -35
- ccxt/test/base/test_borrow_rate.py +0 -32
- ccxt/test/base/test_calculate_fee.py +0 -51
- ccxt/test/base/test_crypto.py +0 -127
- ccxt/test/base/test_currency.py +0 -76
- ccxt/test/base/test_datetime.py +0 -103
- ccxt/test/base/test_decimal_to_precision.py +0 -392
- ccxt/test/base/test_deep_extend.py +0 -68
- ccxt/test/base/test_deposit_withdrawal.py +0 -50
- ccxt/test/base/test_exchange_datetime_functions.py +0 -76
- ccxt/test/base/test_funding_rate_history.py +0 -29
- ccxt/test/base/test_last_price.py +0 -32
- ccxt/test/base/test_ledger_entry.py +0 -45
- ccxt/test/base/test_ledger_item.py +0 -48
- ccxt/test/base/test_leverage_tier.py +0 -33
- ccxt/test/base/test_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -190
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -32
- ccxt/test/base/test_open_interest.py +0 -32
- ccxt/test/base/test_order.py +0 -64
- ccxt/test/base/test_order_book.py +0 -63
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -345
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -86
- ccxt/test/base/test_trade.py +0 -47
- ccxt/test/base/test_trading_fee.py +0 -26
- ccxt/test/base/test_transaction.py +0 -39
- ccxt-4.2.77.dist-info/METADATA +0 -626
- ccxt-4.2.77.dist-info/RECORD +0 -534
- {ccxt-4.2.77.dist-info → ccxt-4.4.49.dist-info}/top_level.txt +0 -0
ccxt/pro/bingx.py
CHANGED
@@ -5,12 +5,13 @@
|
|
5
5
|
|
6
6
|
import ccxt.async_support
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
|
8
|
-
from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Ticker, Trade
|
8
|
+
from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Strings, Ticker, Tickers, Trade
|
9
9
|
from ccxt.async_support.base.ws.client import Client
|
10
10
|
from typing import List
|
11
|
+
from ccxt.base.errors import ArgumentsRequired
|
11
12
|
from ccxt.base.errors import BadRequest
|
13
|
+
from ccxt.base.errors import NotSupported
|
12
14
|
from ccxt.base.errors import NetworkError
|
13
|
-
from ccxt.base.precise import Precise
|
14
15
|
|
15
16
|
|
16
17
|
class bingx(ccxt.async_support.bingx):
|
@@ -20,19 +21,23 @@ class bingx(ccxt.async_support.bingx):
|
|
20
21
|
'has': {
|
21
22
|
'ws': True,
|
22
23
|
'watchTrades': True,
|
24
|
+
'watchTradesForSymbols': False,
|
23
25
|
'watchOrderBook': True,
|
26
|
+
'watchOrderBookForSymbols': True,
|
24
27
|
'watchOHLCV': True,
|
28
|
+
'watchOHLCVForSymbols': True,
|
25
29
|
'watchOrders': True,
|
26
30
|
'watchMyTrades': True,
|
27
31
|
'watchTicker': True,
|
28
|
-
'watchTickers':
|
32
|
+
'watchTickers': True,
|
29
33
|
'watchBalance': True,
|
30
34
|
},
|
31
35
|
'urls': {
|
32
36
|
'api': {
|
33
37
|
'ws': {
|
34
38
|
'spot': 'wss://open-api-ws.bingx.com/market',
|
35
|
-
'
|
39
|
+
'linear': 'wss://open-api-swap.bingx.com/swap-market',
|
40
|
+
'inverse': 'wss://open-api-cswap-ws.bingx.com/market',
|
36
41
|
},
|
37
42
|
},
|
38
43
|
},
|
@@ -73,6 +78,14 @@ class bingx(ccxt.async_support.bingx):
|
|
73
78
|
'fetchBalanceSnapshot': True, # needed to be True to keep track of used and free balance
|
74
79
|
'awaitBalanceSnapshot': False, # whether to wait for the balance snapshot before providing updates
|
75
80
|
},
|
81
|
+
'watchOrderBook': {
|
82
|
+
'depth': 100, # 5, 10, 20, 50, 100
|
83
|
+
'interval': 500, # 100, 200, 500, 1000
|
84
|
+
},
|
85
|
+
'watchOrderBookForSymbols': {
|
86
|
+
'depth': 100, # 5, 10, 20, 50, 100
|
87
|
+
'interval': 500, # 100, 200, 500, 1000
|
88
|
+
},
|
76
89
|
},
|
77
90
|
'streaming': {
|
78
91
|
'keepAlive': 1800000, # 30 minutes
|
@@ -82,26 +95,36 @@ class bingx(ccxt.async_support.bingx):
|
|
82
95
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
83
96
|
"""
|
84
97
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
85
|
-
|
98
|
+
|
99
|
+
https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#Subscribe%20to%2024-hour%20Price%20Change
|
100
|
+
https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20to%2024-hour%20price%20changes
|
101
|
+
https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%2024-Hour%20Price%20Change
|
102
|
+
|
86
103
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
87
104
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
88
105
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
89
106
|
"""
|
90
107
|
await self.load_markets()
|
91
108
|
market = self.market(symbol)
|
92
|
-
marketType
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
109
|
+
marketType = None
|
110
|
+
subType = None
|
111
|
+
url = None
|
112
|
+
marketType, params = self.handle_market_type_and_params('watchTicker', market, params)
|
113
|
+
subType, params = self.handle_sub_type_and_params('watchTicker', market, params, 'linear')
|
114
|
+
if marketType == 'swap':
|
115
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
116
|
+
else:
|
117
|
+
url = self.safe_string(self.urls['api']['ws'], marketType)
|
118
|
+
subscriptionHash = market['id'] + '@ticker'
|
119
|
+
messageHash = self.get_message_hash('ticker', market['symbol'])
|
97
120
|
uuid = self.uuid()
|
98
|
-
request = {
|
121
|
+
request: dict = {
|
99
122
|
'id': uuid,
|
100
|
-
'dataType':
|
123
|
+
'dataType': subscriptionHash,
|
101
124
|
}
|
102
125
|
if marketType == 'swap':
|
103
126
|
request['reqType'] = 'sub'
|
104
|
-
return await self.watch(url, messageHash, self.extend(request,
|
127
|
+
return await self.watch(url, messageHash, self.extend(request, params), subscriptionHash)
|
105
128
|
|
106
129
|
def handle_ticker(self, client: Client, message):
|
107
130
|
#
|
@@ -167,8 +190,9 @@ class bingx(ccxt.async_support.bingx):
|
|
167
190
|
symbol = market['symbol']
|
168
191
|
ticker = self.parse_ws_ticker(data, market)
|
169
192
|
self.tickers[symbol] = ticker
|
170
|
-
|
171
|
-
|
193
|
+
client.resolve(ticker, self.get_message_hash('ticker', symbol))
|
194
|
+
if self.safe_string(message, 'dataType') == 'all@ticker':
|
195
|
+
client.resolve(ticker, self.get_message_hash('ticker'))
|
172
196
|
|
173
197
|
def parse_ws_ticker(self, message, market=None):
|
174
198
|
#
|
@@ -193,7 +217,7 @@ class bingx(ccxt.async_support.bingx):
|
|
193
217
|
# "b": "2.5747"
|
194
218
|
# }
|
195
219
|
#
|
196
|
-
timestamp = self.safe_integer(message, '
|
220
|
+
timestamp = self.safe_integer(message, 'C')
|
197
221
|
marketId = self.safe_string(message, 's')
|
198
222
|
market = self.safe_market(marketId, market)
|
199
223
|
close = self.safe_string(message, 'c')
|
@@ -220,40 +244,235 @@ class bingx(ccxt.async_support.bingx):
|
|
220
244
|
'info': message,
|
221
245
|
}, market)
|
222
246
|
|
247
|
+
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
248
|
+
"""
|
249
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
250
|
+
|
251
|
+
https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20to%2024-hour%20price%20changes%20of%20all%20trading%20pairs
|
252
|
+
|
253
|
+
:param str[] symbols: unified symbol of the market to watch the tickers for
|
254
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
255
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
256
|
+
"""
|
257
|
+
await self.load_markets()
|
258
|
+
symbols = self.market_symbols(symbols, None, True, True, False)
|
259
|
+
firstMarket = None
|
260
|
+
marketType = None
|
261
|
+
subType = None
|
262
|
+
symbolsDefined = (symbols is not None)
|
263
|
+
if symbolsDefined:
|
264
|
+
firstMarket = self.market(symbols[0])
|
265
|
+
marketType, params = self.handle_market_type_and_params('watchTickers', firstMarket, params)
|
266
|
+
subType, params = self.handle_sub_type_and_params('watchTickers', firstMarket, params, 'linear')
|
267
|
+
if marketType == 'spot':
|
268
|
+
raise NotSupported(self.id + ' watchTickers is not supported for spot markets yet')
|
269
|
+
if subType == 'inverse':
|
270
|
+
raise NotSupported(self.id + ' watchTickers is not supported for inverse markets yet')
|
271
|
+
messageHashes = []
|
272
|
+
subscriptionHashes = ['all@ticker']
|
273
|
+
if symbolsDefined:
|
274
|
+
for i in range(0, len(symbols)):
|
275
|
+
symbol = symbols[i]
|
276
|
+
market = self.market(symbol)
|
277
|
+
messageHashes.append(self.get_message_hash('ticker', market['symbol']))
|
278
|
+
else:
|
279
|
+
messageHashes.append(self.get_message_hash('ticker'))
|
280
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
281
|
+
uuid = self.uuid()
|
282
|
+
request: dict = {
|
283
|
+
'id': uuid,
|
284
|
+
'dataType': 'all@ticker',
|
285
|
+
}
|
286
|
+
if marketType == 'swap':
|
287
|
+
request['reqType'] = 'sub'
|
288
|
+
result = await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), subscriptionHashes)
|
289
|
+
if self.newUpdates:
|
290
|
+
newDict: dict = {}
|
291
|
+
newDict[result['symbol']] = result
|
292
|
+
return newDict
|
293
|
+
return self.tickers
|
294
|
+
|
295
|
+
async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
|
296
|
+
"""
|
297
|
+
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
298
|
+
|
299
|
+
https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20Market%20Depth%20Data%20of%20all%20trading%20pairs
|
300
|
+
|
301
|
+
:param str[] symbols: unified array of symbols
|
302
|
+
:param int [limit]: the maximum amount of order book entries to return
|
303
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
304
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
305
|
+
"""
|
306
|
+
symbols = self.market_symbols(symbols, None, True, True, False)
|
307
|
+
firstMarket = None
|
308
|
+
marketType = None
|
309
|
+
subType = None
|
310
|
+
symbolsDefined = (symbols is not None)
|
311
|
+
if symbolsDefined:
|
312
|
+
firstMarket = self.market(symbols[0])
|
313
|
+
marketType, params = self.handle_market_type_and_params('watchOrderBookForSymbols', firstMarket, params)
|
314
|
+
subType, params = self.handle_sub_type_and_params('watchOrderBookForSymbols', firstMarket, params, 'linear')
|
315
|
+
if marketType == 'spot':
|
316
|
+
raise NotSupported(self.id + ' watchOrderBookForSymbols is not supported for spot markets yet')
|
317
|
+
if subType == 'inverse':
|
318
|
+
raise NotSupported(self.id + ' watchOrderBookForSymbols is not supported for inverse markets yet')
|
319
|
+
limit = self.get_order_book_limit_by_market_type(marketType, limit)
|
320
|
+
interval = None
|
321
|
+
interval, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'interval', 500)
|
322
|
+
self.check_required_argument('watchOrderBookForSymbols', interval, 'interval', [100, 200, 500, 1000])
|
323
|
+
channelName = 'depth' + str(limit) + '@' + str(interval) + 'ms'
|
324
|
+
subscriptionHash = 'all@' + channelName
|
325
|
+
messageHashes = []
|
326
|
+
if symbolsDefined:
|
327
|
+
for i in range(0, len(symbols)):
|
328
|
+
symbol = symbols[i]
|
329
|
+
market = self.market(symbol)
|
330
|
+
messageHashes.append(self.get_message_hash('orderbook', market['symbol']))
|
331
|
+
else:
|
332
|
+
messageHashes.append(self.get_message_hash('orderbook'))
|
333
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
334
|
+
uuid = self.uuid()
|
335
|
+
request: dict = {
|
336
|
+
'id': uuid,
|
337
|
+
'dataType': subscriptionHash,
|
338
|
+
}
|
339
|
+
if marketType == 'swap':
|
340
|
+
request['reqType'] = 'sub'
|
341
|
+
subscriptionArgs: dict = {
|
342
|
+
'symbols': symbols,
|
343
|
+
'limit': limit,
|
344
|
+
'interval': interval,
|
345
|
+
'params': params,
|
346
|
+
}
|
347
|
+
orderbook = await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), [subscriptionHash], subscriptionArgs)
|
348
|
+
return orderbook.limit()
|
349
|
+
|
350
|
+
async def watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], since: Int = None, limit: Int = None, params={}):
|
351
|
+
"""
|
352
|
+
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
353
|
+
|
354
|
+
https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20K-Line%20Data%20of%20all%20trading%20pairs
|
355
|
+
|
356
|
+
:param str[][] symbolsAndTimeframes: array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
357
|
+
:param int [since]: timestamp in ms of the earliest candle to fetch
|
358
|
+
:param int [limit]: the maximum amount of candles to fetch
|
359
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
360
|
+
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
361
|
+
"""
|
362
|
+
symbolsLength = len(symbolsAndTimeframes)
|
363
|
+
if symbolsLength != 0 and not isinstance(symbolsAndTimeframes[0], list):
|
364
|
+
raise ArgumentsRequired(self.id + " watchOHLCVForSymbols() requires a an array like [['BTC/USDT:USDT', '1m'], ['LTC/USDT:USDT', '5m']]")
|
365
|
+
await self.load_markets()
|
366
|
+
messageHashes = []
|
367
|
+
marketType = None
|
368
|
+
subType = None
|
369
|
+
chosenTimeframe = None
|
370
|
+
firstMarket = None
|
371
|
+
if symbolsLength != 0:
|
372
|
+
symbols = self.get_list_from_object_values(symbolsAndTimeframes, 0)
|
373
|
+
symbols = self.market_symbols(symbols, None, True, True, False)
|
374
|
+
firstMarket = self.market(symbols[0])
|
375
|
+
marketType, params = self.handle_market_type_and_params('watchOHLCVForSymbols', firstMarket, params)
|
376
|
+
subType, params = self.handle_sub_type_and_params('watchOHLCVForSymbols', firstMarket, params, 'linear')
|
377
|
+
if marketType == 'spot':
|
378
|
+
raise NotSupported(self.id + ' watchOHLCVForSymbols is not supported for spot markets yet')
|
379
|
+
if subType == 'inverse':
|
380
|
+
raise NotSupported(self.id + ' watchOHLCVForSymbols is not supported for inverse markets yet')
|
381
|
+
marketOptions = self.safe_dict(self.options, marketType)
|
382
|
+
timeframes = self.safe_dict(marketOptions, 'timeframes', {})
|
383
|
+
for i in range(0, len(symbolsAndTimeframes)):
|
384
|
+
symbolAndTimeframe = symbolsAndTimeframes[i]
|
385
|
+
sym = symbolAndTimeframe[0]
|
386
|
+
tf = symbolAndTimeframe[1]
|
387
|
+
market = self.market(sym)
|
388
|
+
rawTimeframe = self.safe_string(timeframes, tf, tf)
|
389
|
+
if chosenTimeframe is None:
|
390
|
+
chosenTimeframe = rawTimeframe
|
391
|
+
elif chosenTimeframe != rawTimeframe:
|
392
|
+
raise BadRequest(self.id + ' watchOHLCVForSymbols requires all timeframes to be the same')
|
393
|
+
messageHashes.append(self.get_message_hash('ohlcv', market['symbol'], chosenTimeframe))
|
394
|
+
subscriptionHash = 'all@kline_' + chosenTimeframe
|
395
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
396
|
+
uuid = self.uuid()
|
397
|
+
request: dict = {
|
398
|
+
'id': uuid,
|
399
|
+
'dataType': subscriptionHash,
|
400
|
+
}
|
401
|
+
if marketType == 'swap':
|
402
|
+
request['reqType'] = 'sub'
|
403
|
+
subscriptionArgs: dict = {
|
404
|
+
'limit': limit,
|
405
|
+
'params': params,
|
406
|
+
}
|
407
|
+
symbol, timeframe, candles = await self.watch_multiple(url, messageHashes, request, [subscriptionHash], subscriptionArgs)
|
408
|
+
if self.newUpdates:
|
409
|
+
limit = candles.getLimit(symbol, limit)
|
410
|
+
filtered = self.filter_by_since_limit(candles, since, limit, 0, True)
|
411
|
+
return self.create_ohlcv_object(symbol, timeframe, filtered)
|
412
|
+
|
413
|
+
def get_order_book_limit_by_market_type(self, marketType: str, limit: Int = None):
|
414
|
+
if limit is None:
|
415
|
+
limit = 100
|
416
|
+
else:
|
417
|
+
if marketType == 'swap' or marketType == 'future':
|
418
|
+
limit = self.find_nearest_ceiling([5, 10, 20, 50, 100], limit)
|
419
|
+
elif marketType == 'spot':
|
420
|
+
limit = self.find_nearest_ceiling([20, 100], limit)
|
421
|
+
return limit
|
422
|
+
|
423
|
+
def get_message_hash(self, unifiedChannel: str, symbol: Str = None, extra: Str = None):
|
424
|
+
hash = unifiedChannel
|
425
|
+
if symbol is not None:
|
426
|
+
hash += '::' + symbol
|
427
|
+
else:
|
428
|
+
hash += 's' # tickers, orderbooks, ohlcvs ...
|
429
|
+
if extra is not None:
|
430
|
+
hash += '::' + extra
|
431
|
+
return hash
|
432
|
+
|
223
433
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
224
434
|
"""
|
225
435
|
watches information on multiple trades made in a market
|
226
|
-
|
227
|
-
|
436
|
+
|
437
|
+
https://bingx-api.github.io/docs/#/spot/socket/market.html#Subscribe%20to%20tick-by-tick
|
438
|
+
https://bingx-api.github.io/docs/#/swapV2/socket/market.html#Subscribe%20the%20Latest%20Trade%20Detail
|
439
|
+
https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscription%20transaction%20by%20transaction
|
440
|
+
|
228
441
|
:param str symbol: unified market symbol of the market orders were made in
|
229
442
|
:param int [since]: the earliest time in ms to fetch orders for
|
230
443
|
:param int [limit]: the maximum number of order structures to retrieve
|
231
444
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
232
|
-
:returns dict[]: a list of
|
445
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
233
446
|
"""
|
234
447
|
await self.load_markets()
|
235
448
|
market = self.market(symbol)
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
449
|
+
symbol = market['symbol']
|
450
|
+
marketType = None
|
451
|
+
subType = None
|
452
|
+
url = None
|
453
|
+
marketType, params = self.handle_market_type_and_params('watchTrades', market, params)
|
454
|
+
subType, params = self.handle_sub_type_and_params('watchTrades', market, params, 'linear')
|
455
|
+
if marketType == 'swap':
|
456
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
457
|
+
else:
|
458
|
+
url = self.safe_string(self.urls['api']['ws'], marketType)
|
459
|
+
rawHash = market['id'] + '@trade'
|
460
|
+
messageHash = 'trade::' + symbol
|
241
461
|
uuid = self.uuid()
|
242
|
-
request = {
|
462
|
+
request: dict = {
|
243
463
|
'id': uuid,
|
244
|
-
'dataType':
|
464
|
+
'dataType': rawHash,
|
245
465
|
}
|
246
466
|
if marketType == 'swap':
|
247
467
|
request['reqType'] = 'sub'
|
248
|
-
trades = await self.watch(url, messageHash, self.extend(request,
|
468
|
+
trades = await self.watch(url, messageHash, self.extend(request, params), messageHash)
|
249
469
|
if self.newUpdates:
|
250
470
|
limit = trades.getLimit(symbol, limit)
|
251
471
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
252
472
|
|
253
473
|
def handle_trades(self, client: Client, message):
|
254
474
|
#
|
255
|
-
# spot
|
256
|
-
# first snapshot
|
475
|
+
# spot: first snapshot
|
257
476
|
#
|
258
477
|
# {
|
259
478
|
# "id": "d83b78ce-98be-4dc2-b847-12fe471b5bc5",
|
@@ -262,7 +481,7 @@ class bingx(ccxt.async_support.bingx):
|
|
262
481
|
# "timestamp": 1690214699854
|
263
482
|
# }
|
264
483
|
#
|
265
|
-
# subsequent updates
|
484
|
+
# spot: subsequent updates
|
266
485
|
#
|
267
486
|
# {
|
268
487
|
# "code": 0,
|
@@ -280,9 +499,7 @@ class bingx(ccxt.async_support.bingx):
|
|
280
499
|
# "success": True
|
281
500
|
# }
|
282
501
|
#
|
283
|
-
#
|
284
|
-
# swap
|
285
|
-
# first snapshot
|
502
|
+
# linear swap: first snapshot
|
286
503
|
#
|
287
504
|
# {
|
288
505
|
# "id": "2aed93b1-6e1e-4038-aeba-f5eeaec2ca48",
|
@@ -292,8 +509,7 @@ class bingx(ccxt.async_support.bingx):
|
|
292
509
|
# "data": null
|
293
510
|
# }
|
294
511
|
#
|
295
|
-
# subsequent updates
|
296
|
-
#
|
512
|
+
# linear swap: subsequent updates
|
297
513
|
#
|
298
514
|
# {
|
299
515
|
# "code": 0,
|
@@ -310,13 +526,40 @@ class bingx(ccxt.async_support.bingx):
|
|
310
526
|
# ]
|
311
527
|
# }
|
312
528
|
#
|
529
|
+
# inverse swap: first snapshot
|
530
|
+
#
|
531
|
+
# {
|
532
|
+
# "code": 0,
|
533
|
+
# "id": "a2e482ca-f71b-42f8-a83a-8ff85a713e64",
|
534
|
+
# "msg": "SUCCESS",
|
535
|
+
# "timestamp": 1722920589426
|
536
|
+
# }
|
537
|
+
#
|
538
|
+
# inverse swap: subsequent updates
|
539
|
+
#
|
540
|
+
# {
|
541
|
+
# "code": 0,
|
542
|
+
# "dataType": "BTC-USD@trade",
|
543
|
+
# "data": {
|
544
|
+
# "e": "trade",
|
545
|
+
# "E": 1722920589665,
|
546
|
+
# "s": "BTC-USD",
|
547
|
+
# "t": "39125001",
|
548
|
+
# "p": "55360.0",
|
549
|
+
# "q": "1",
|
550
|
+
# "T": 1722920589582,
|
551
|
+
# "m": False
|
552
|
+
# }
|
553
|
+
# }
|
554
|
+
#
|
313
555
|
data = self.safe_value(message, 'data', [])
|
314
|
-
|
315
|
-
marketId =
|
556
|
+
rawHash = self.safe_string(message, 'dataType')
|
557
|
+
marketId = rawHash.split('@')[0]
|
316
558
|
isSwap = client.url.find('swap') >= 0
|
317
559
|
marketType = 'swap' if isSwap else 'spot'
|
318
560
|
market = self.safe_market(marketId, None, None, marketType)
|
319
561
|
symbol = market['symbol']
|
562
|
+
messageHash = 'trade::' + symbol
|
320
563
|
trades = None
|
321
564
|
if isinstance(data, list):
|
322
565
|
trades = self.parse_trades(data, market)
|
@@ -334,8 +577,11 @@ class bingx(ccxt.async_support.bingx):
|
|
334
577
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
335
578
|
"""
|
336
579
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
337
|
-
|
338
|
-
|
580
|
+
|
581
|
+
https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#Subscribe%20Market%20Depth%20Data
|
582
|
+
https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20Market%20Depth%20Data
|
583
|
+
https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%20Limited%20Depth
|
584
|
+
|
339
585
|
:param str symbol: unified symbol of the market to fetch the order book for
|
340
586
|
:param int [limit]: the maximum amount of order book entries to return
|
341
587
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -343,40 +589,56 @@ class bingx(ccxt.async_support.bingx):
|
|
343
589
|
"""
|
344
590
|
await self.load_markets()
|
345
591
|
market = self.market(symbol)
|
346
|
-
marketType
|
347
|
-
|
348
|
-
|
592
|
+
marketType = None
|
593
|
+
subType = None
|
594
|
+
url = None
|
595
|
+
marketType, params = self.handle_market_type_and_params('watchOrderBook', market, params)
|
596
|
+
subType, params = self.handle_sub_type_and_params('watchOrderBook', market, params, 'linear')
|
597
|
+
if marketType == 'swap':
|
598
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
349
599
|
else:
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
600
|
+
url = self.safe_string(self.urls['api']['ws'], marketType)
|
601
|
+
limit = self.get_order_book_limit_by_market_type(marketType, limit)
|
602
|
+
channelName = 'depth' + str(limit)
|
603
|
+
interval = None
|
604
|
+
if marketType != 'spot':
|
605
|
+
if not market['inverse']:
|
606
|
+
interval, params = self.handle_option_and_params(params, 'watchOrderBook', 'interval', 500)
|
607
|
+
self.check_required_argument('watchOrderBook', interval, 'interval', [100, 200, 500, 1000])
|
608
|
+
channelName = channelName + '@' + str(interval) + 'ms'
|
609
|
+
subscriptionHash = market['id'] + '@' + channelName
|
610
|
+
messageHash = self.get_message_hash('orderbook', market['symbol'])
|
360
611
|
uuid = self.uuid()
|
361
|
-
request = {
|
612
|
+
request: dict = {
|
362
613
|
'id': uuid,
|
363
|
-
'dataType':
|
614
|
+
'dataType': subscriptionHash,
|
364
615
|
}
|
365
616
|
if marketType == 'swap':
|
366
617
|
request['reqType'] = 'sub'
|
367
|
-
|
618
|
+
subscriptionArgs: dict = {}
|
619
|
+
if market['inverse']:
|
620
|
+
subscriptionArgs = {
|
621
|
+
'count': limit,
|
622
|
+
'params': params,
|
623
|
+
}
|
624
|
+
else:
|
625
|
+
subscriptionArgs = {
|
626
|
+
'level': limit,
|
627
|
+
'interval': interval,
|
628
|
+
'params': params,
|
629
|
+
}
|
630
|
+
orderbook = await self.watch(url, messageHash, self.deep_extend(request, params), subscriptionHash, subscriptionArgs)
|
368
631
|
return orderbook.limit()
|
369
632
|
|
370
633
|
def handle_delta(self, bookside, delta):
|
371
|
-
price = self.
|
372
|
-
amount = self.
|
634
|
+
price = self.safe_float_2(delta, 0, 'p')
|
635
|
+
amount = self.safe_float_2(delta, 1, 'a')
|
373
636
|
bookside.store(price, amount)
|
374
637
|
|
375
638
|
def handle_order_book(self, client: Client, message):
|
376
639
|
#
|
377
640
|
# spot
|
378
641
|
#
|
379
|
-
#
|
380
642
|
# {
|
381
643
|
# "code": 0,
|
382
644
|
# "dataType": "BTC-USDT@depth20",
|
@@ -394,12 +656,11 @@ class bingx(ccxt.async_support.bingx):
|
|
394
656
|
# "success": True
|
395
657
|
# }
|
396
658
|
#
|
397
|
-
# swap
|
398
|
-
#
|
659
|
+
# linear swap
|
399
660
|
#
|
400
661
|
# {
|
401
662
|
# "code": 0,
|
402
|
-
# "dataType": "BTC-USDT@depth20",
|
663
|
+
# "dataType": "BTC-USDT@depth20@100ms", #or "all@depth20@100ms"
|
403
664
|
# "data": {
|
404
665
|
# "bids": [
|
405
666
|
# ['28852.9', "34.2621"],
|
@@ -408,24 +669,63 @@ class bingx(ccxt.async_support.bingx):
|
|
408
669
|
# "asks": [
|
409
670
|
# ['28864.9', "23.4079"],
|
410
671
|
# ...
|
411
|
-
# ]
|
672
|
+
# ],
|
673
|
+
# "symbol": "BTC-USDT", # self key exists only in "all" subscription
|
412
674
|
# }
|
413
675
|
# }
|
414
676
|
#
|
415
|
-
|
416
|
-
|
417
|
-
|
677
|
+
# inverse swap
|
678
|
+
#
|
679
|
+
# {
|
680
|
+
# "code": 0,
|
681
|
+
# "dataType": "BTC-USD@depth100",
|
682
|
+
# "data": {
|
683
|
+
# {
|
684
|
+
# "symbol": "BTC-USD",
|
685
|
+
# "bids": [
|
686
|
+
# {"p": "58074.2", "a": "1.422318", "v": "826.0"},
|
687
|
+
# ...
|
688
|
+
# ],
|
689
|
+
# "asks": [
|
690
|
+
# {"p": "62878.0", "a": "0.001590", "v": "1.0"},
|
691
|
+
# ...
|
692
|
+
# ],
|
693
|
+
# "aggPrecision": "0.1",
|
694
|
+
# "timestamp": 1723705093529
|
695
|
+
# }
|
696
|
+
# }
|
697
|
+
# }
|
698
|
+
#
|
699
|
+
data = self.safe_dict(message, 'data', {})
|
700
|
+
dataType = self.safe_string(message, 'dataType')
|
701
|
+
parts = dataType.split('@')
|
702
|
+
firstPart = parts[0]
|
703
|
+
isAllEndpoint = (firstPart == 'all')
|
704
|
+
marketId = self.safe_string(data, 'symbol', firstPart)
|
418
705
|
isSwap = client.url.find('swap') >= 0
|
419
706
|
marketType = 'swap' if isSwap else 'spot'
|
420
707
|
market = self.safe_market(marketId, None, None, marketType)
|
421
708
|
symbol = market['symbol']
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
709
|
+
if self.safe_value(self.orderbooks, symbol) is None:
|
710
|
+
# limit = [5, 10, 20, 50, 100]
|
711
|
+
subscriptionHash = dataType
|
712
|
+
subscription = client.subscriptions[subscriptionHash]
|
713
|
+
limit = self.safe_integer(subscription, 'limit')
|
714
|
+
self.orderbooks[symbol] = self.order_book({}, limit)
|
715
|
+
orderbook = self.orderbooks[symbol]
|
716
|
+
snapshot = None
|
717
|
+
if market['inverse']:
|
718
|
+
snapshot = self.parse_order_book(data, symbol, None, 'bids', 'asks', 'p', 'a')
|
719
|
+
else:
|
720
|
+
snapshot = self.parse_order_book(data, symbol, None, 'bids', 'asks', 0, 1)
|
426
721
|
orderbook.reset(snapshot)
|
427
722
|
self.orderbooks[symbol] = orderbook
|
723
|
+
messageHash = self.get_message_hash('orderbook', symbol)
|
428
724
|
client.resolve(orderbook, messageHash)
|
725
|
+
# resolve for "all"
|
726
|
+
if isAllEndpoint:
|
727
|
+
messageHashForAll = self.get_message_hash('orderbook')
|
728
|
+
client.resolve(orderbook, messageHashForAll)
|
429
729
|
|
430
730
|
def parse_ws_ohlcv(self, ohlcv, market=None) -> list:
|
431
731
|
#
|
@@ -440,8 +740,10 @@ class bingx(ccxt.async_support.bingx):
|
|
440
740
|
# }
|
441
741
|
#
|
442
742
|
# for spot, opening-time(t) is used instead of closing-time(T), to be compatible with fetchOHLCV
|
443
|
-
# for swap,(T) is the opening time
|
743
|
+
# for linear swap,(T) is the opening time
|
444
744
|
timestamp = 't' if (market['spot']) else 'T'
|
745
|
+
if market['swap']:
|
746
|
+
timestamp = 't' if (market['inverse']) else 'T'
|
445
747
|
return [
|
446
748
|
self.safe_integer(ohlcv, timestamp),
|
447
749
|
self.safe_number(ohlcv, 'o'),
|
@@ -453,7 +755,7 @@ class bingx(ccxt.async_support.bingx):
|
|
453
755
|
|
454
756
|
def handle_ohlcv(self, client: Client, message):
|
455
757
|
#
|
456
|
-
# spot
|
758
|
+
# spot:
|
457
759
|
#
|
458
760
|
# {
|
459
761
|
# "code": 0,
|
@@ -479,7 +781,8 @@ class bingx(ccxt.async_support.bingx):
|
|
479
781
|
# "success": True
|
480
782
|
# }
|
481
783
|
#
|
482
|
-
# swap
|
784
|
+
# linear swap:
|
785
|
+
#
|
483
786
|
# {
|
484
787
|
# "code": 0,
|
485
788
|
# "dataType": "BTC-USDT@kline_1m",
|
@@ -496,36 +799,74 @@ class bingx(ccxt.async_support.bingx):
|
|
496
799
|
# ]
|
497
800
|
# }
|
498
801
|
#
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
802
|
+
# inverse swap:
|
803
|
+
#
|
804
|
+
# {
|
805
|
+
# "code": 0,
|
806
|
+
# "timestamp": 1723769354547,
|
807
|
+
# "dataType": "BTC-USD@kline_1m",
|
808
|
+
# "data": {
|
809
|
+
# "t": 1723769340000,
|
810
|
+
# "o": 57485.1,
|
811
|
+
# "c": 57468,
|
812
|
+
# "l": 57464.9,
|
813
|
+
# "h": 57485.1,
|
814
|
+
# "a": 0.189663,
|
815
|
+
# "v": 109,
|
816
|
+
# "u": 92,
|
817
|
+
# "s": "BTC-USD"
|
818
|
+
# }
|
819
|
+
# }
|
820
|
+
#
|
508
821
|
isSwap = client.url.find('swap') >= 0
|
822
|
+
dataType = self.safe_string(message, 'dataType')
|
823
|
+
parts = dataType.split('@')
|
824
|
+
firstPart = parts[0]
|
825
|
+
isAllEndpoint = (firstPart == 'all')
|
826
|
+
marketId = self.safe_string(message, 's', firstPart)
|
509
827
|
marketType = 'swap' if isSwap else 'spot'
|
510
828
|
market = self.safe_market(marketId, None, None, marketType)
|
829
|
+
candles = None
|
830
|
+
if isSwap:
|
831
|
+
if market['inverse']:
|
832
|
+
candles = [self.safe_dict(message, 'data', {})]
|
833
|
+
else:
|
834
|
+
candles = self.safe_list(message, 'data', [])
|
835
|
+
else:
|
836
|
+
data = self.safe_dict(message, 'data', {})
|
837
|
+
candles = [self.safe_dict(data, 'K', {})]
|
511
838
|
symbol = market['symbol']
|
512
839
|
self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
840
|
+
rawTimeframe = dataType.split('_')[1]
|
841
|
+
marketOptions = self.safe_dict(self.options, marketType)
|
842
|
+
timeframes = self.safe_dict(marketOptions, 'timeframes', {})
|
843
|
+
unifiedTimeframe = self.find_timeframe(rawTimeframe, timeframes)
|
844
|
+
if self.safe_value(self.ohlcvs[symbol], rawTimeframe) is None:
|
845
|
+
subscriptionHash = dataType
|
846
|
+
subscription = client.subscriptions[subscriptionHash]
|
847
|
+
limit = self.safe_integer(subscription, 'limit')
|
848
|
+
self.ohlcvs[symbol][unifiedTimeframe] = ArrayCacheByTimestamp(limit)
|
849
|
+
stored = self.ohlcvs[symbol][unifiedTimeframe]
|
518
850
|
for i in range(0, len(candles)):
|
519
851
|
candle = candles[i]
|
520
852
|
parsed = self.parse_ws_ohlcv(candle, market)
|
521
853
|
stored.append(parsed)
|
522
|
-
|
854
|
+
resolveData = [symbol, unifiedTimeframe, stored]
|
855
|
+
messageHash = self.get_message_hash('ohlcv', symbol, unifiedTimeframe)
|
856
|
+
client.resolve(resolveData, messageHash)
|
857
|
+
# resolve for "all"
|
858
|
+
if isAllEndpoint:
|
859
|
+
messageHashForAll = self.get_message_hash('ohlcv', None, unifiedTimeframe)
|
860
|
+
client.resolve(resolveData, messageHashForAll)
|
523
861
|
|
524
862
|
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
525
863
|
"""
|
526
864
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
527
|
-
|
528
|
-
|
865
|
+
|
866
|
+
https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#K-line%20Streams
|
867
|
+
https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20K-Line%20Data
|
868
|
+
https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%20Latest%20Trading%20Pair%20K-Line
|
869
|
+
|
529
870
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
530
871
|
:param str timeframe: the length of time each candle represents
|
531
872
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
@@ -535,33 +876,49 @@ class bingx(ccxt.async_support.bingx):
|
|
535
876
|
"""
|
536
877
|
await self.load_markets()
|
537
878
|
market = self.market(symbol)
|
538
|
-
marketType
|
539
|
-
|
879
|
+
marketType = None
|
880
|
+
subType = None
|
881
|
+
url = None
|
882
|
+
marketType, params = self.handle_market_type_and_params('watchOHLCV', market, params)
|
883
|
+
subType, params = self.handle_sub_type_and_params('watchOHLCV', market, params, 'linear')
|
884
|
+
if marketType == 'swap':
|
885
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
886
|
+
else:
|
887
|
+
url = self.safe_string(self.urls['api']['ws'], marketType)
|
540
888
|
if url is None:
|
541
889
|
raise BadRequest(self.id + ' watchOHLCV is not supported for ' + marketType + ' markets.')
|
542
890
|
options = self.safe_value(self.options, marketType, {})
|
543
891
|
timeframes = self.safe_value(options, 'timeframes', {})
|
544
|
-
|
545
|
-
messageHash = market['
|
892
|
+
rawTimeframe = self.safe_string(timeframes, timeframe, timeframe)
|
893
|
+
messageHash = self.get_message_hash('ohlcv', market['symbol'], timeframe)
|
894
|
+
subscriptionHash = market['id'] + '@kline_' + rawTimeframe
|
546
895
|
uuid = self.uuid()
|
547
|
-
request = {
|
896
|
+
request: dict = {
|
548
897
|
'id': uuid,
|
549
|
-
'dataType':
|
898
|
+
'dataType': subscriptionHash,
|
550
899
|
}
|
551
900
|
if marketType == 'swap':
|
552
901
|
request['reqType'] = 'sub'
|
553
|
-
|
902
|
+
subscriptionArgs: dict = {
|
903
|
+
'interval': rawTimeframe,
|
904
|
+
'params': params,
|
905
|
+
}
|
906
|
+
result = await self.watch(url, messageHash, self.extend(request, params), subscriptionHash, subscriptionArgs)
|
907
|
+
ohlcv = result[2]
|
554
908
|
if self.newUpdates:
|
555
909
|
limit = ohlcv.getLimit(symbol, limit)
|
556
910
|
return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
|
557
911
|
|
558
912
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
559
913
|
"""
|
560
|
-
:see: https://bingx-api.github.io/docs/#/spot/socket/account.html#Subscription%20order%20update%20data
|
561
|
-
:see: https://bingx-api.github.io/docs/#/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
|
562
914
|
watches information on multiple orders made by the user
|
563
|
-
|
564
|
-
|
915
|
+
|
916
|
+
https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20order%20update%20data
|
917
|
+
https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Order%20update%20push
|
918
|
+
https://bingx-api.github.io/docs/#/en-us/cswap/socket/account.html#Order%20update%20push
|
919
|
+
|
920
|
+
:param str [symbol]: unified market symbol of the market orders are made in
|
921
|
+
:param int [since]: the earliest time in ms to watch orders for
|
565
922
|
:param int [limit]: the maximum number of order structures to retrieve
|
566
923
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
567
924
|
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
@@ -569,11 +926,13 @@ class bingx(ccxt.async_support.bingx):
|
|
569
926
|
await self.load_markets()
|
570
927
|
await self.authenticate()
|
571
928
|
type = None
|
929
|
+
subType = None
|
572
930
|
market = None
|
573
931
|
if symbol is not None:
|
574
932
|
market = self.market(symbol)
|
575
933
|
symbol = market['symbol']
|
576
934
|
type, params = self.handle_market_type_and_params('watchOrders', market, params)
|
935
|
+
subType, params = self.handle_sub_type_and_params('watchOrders', market, params, 'linear')
|
577
936
|
isSpot = (type == 'spot')
|
578
937
|
spotHash = 'spot:private'
|
579
938
|
swapHash = 'swap:private'
|
@@ -583,14 +942,21 @@ class bingx(ccxt.async_support.bingx):
|
|
583
942
|
messageHash = spotMessageHash if isSpot else swapMessageHash
|
584
943
|
if market is not None:
|
585
944
|
messageHash += ':' + symbol
|
586
|
-
url = self.urls['api']['ws'][type] + '?listenKey=' + self.options['listenKey']
|
587
|
-
request = None
|
588
945
|
uuid = self.uuid()
|
589
|
-
|
946
|
+
baseUrl = None
|
947
|
+
request = None
|
948
|
+
if type == 'swap':
|
949
|
+
if subType == 'inverse':
|
950
|
+
raise NotSupported(self.id + ' watchOrders is not supported for inverse swap markets yet')
|
951
|
+
baseUrl = self.safe_string(self.urls['api']['ws'], subType)
|
952
|
+
else:
|
953
|
+
baseUrl = self.safe_string(self.urls['api']['ws'], type)
|
590
954
|
request = {
|
591
955
|
'id': uuid,
|
956
|
+
'reqType': 'sub',
|
592
957
|
'dataType': 'spot.executionReport',
|
593
958
|
}
|
959
|
+
url = baseUrl + '?listenKey=' + self.options['listenKey']
|
594
960
|
orders = await self.watch(url, messageHash, request, subscriptionHash)
|
595
961
|
if self.newUpdates:
|
596
962
|
limit = orders.getLimit(symbol, limit)
|
@@ -598,40 +964,52 @@ class bingx(ccxt.async_support.bingx):
|
|
598
964
|
|
599
965
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
600
966
|
"""
|
601
|
-
:see: https://bingx-api.github.io/docs/#/spot/socket/account.html#Subscription%20order%20update%20data
|
602
|
-
:see: https://bingx-api.github.io/docs/#/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
|
603
967
|
watches information on multiple trades made by the user
|
604
|
-
|
605
|
-
|
606
|
-
|
968
|
+
|
969
|
+
https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20order%20update%20data
|
970
|
+
https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Order%20update%20push
|
971
|
+
https://bingx-api.github.io/docs/#/en-us/cswap/socket/account.html#Order%20update%20push
|
972
|
+
|
973
|
+
:param str [symbol]: unified market symbol of the market the trades are made in
|
974
|
+
:param int [since]: the earliest time in ms to watch trades for
|
975
|
+
:param int [limit]: the maximum number of trade structures to retrieve
|
607
976
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
608
|
-
:returns dict[]: a list of
|
977
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
609
978
|
"""
|
610
979
|
await self.load_markets()
|
611
980
|
await self.authenticate()
|
612
981
|
type = None
|
982
|
+
subType = None
|
613
983
|
market = None
|
614
984
|
if symbol is not None:
|
615
985
|
market = self.market(symbol)
|
616
986
|
symbol = market['symbol']
|
617
|
-
type, params = self.handle_market_type_and_params('
|
987
|
+
type, params = self.handle_market_type_and_params('watchMyTrades', market, params)
|
988
|
+
subType, params = self.handle_sub_type_and_params('watchMyTrades', market, params, 'linear')
|
618
989
|
isSpot = (type == 'spot')
|
619
|
-
|
620
|
-
|
621
|
-
subscriptionHash =
|
990
|
+
spotHash = 'spot:private'
|
991
|
+
swapHash = 'swap:private'
|
992
|
+
subscriptionHash = spotHash if isSpot else swapHash
|
622
993
|
spotMessageHash = 'spot:mytrades'
|
623
994
|
swapMessageHash = 'swap:mytrades'
|
624
995
|
messageHash = spotMessageHash if isSpot else swapMessageHash
|
625
996
|
if market is not None:
|
626
997
|
messageHash += ':' + symbol
|
627
|
-
url = self.urls['api']['ws'][type] + '?listenKey=' + self.options['listenKey']
|
628
|
-
request = None
|
629
998
|
uuid = self.uuid()
|
630
|
-
|
999
|
+
baseUrl = None
|
1000
|
+
request = None
|
1001
|
+
if type == 'swap':
|
1002
|
+
if subType == 'inverse':
|
1003
|
+
raise NotSupported(self.id + ' watchMyTrades is not supported for inverse swap markets yet')
|
1004
|
+
baseUrl = self.safe_string(self.urls['api']['ws'], subType)
|
1005
|
+
else:
|
1006
|
+
baseUrl = self.safe_string(self.urls['api']['ws'], type)
|
631
1007
|
request = {
|
632
1008
|
'id': uuid,
|
1009
|
+
'reqType': 'sub',
|
633
1010
|
'dataType': 'spot.executionReport',
|
634
1011
|
}
|
1012
|
+
url = baseUrl + '?listenKey=' + self.options['listenKey']
|
635
1013
|
trades = await self.watch(url, messageHash, request, subscriptionHash)
|
636
1014
|
if self.newUpdates:
|
637
1015
|
limit = trades.getLimit(symbol, limit)
|
@@ -639,16 +1017,21 @@ class bingx(ccxt.async_support.bingx):
|
|
639
1017
|
|
640
1018
|
async def watch_balance(self, params={}) -> Balances:
|
641
1019
|
"""
|
642
|
-
:see: https://bingx-api.github.io/docs/#/spot/socket/account.html#Subscription%20order%20update%20data
|
643
|
-
:see: https://bingx-api.github.io/docs/#/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
|
644
1020
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
1021
|
+
|
1022
|
+
https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20account%20balance%20push
|
1023
|
+
https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
|
1024
|
+
https://bingx-api.github.io/docs/#/en-us/cswap/socket/account.html#Account%20balance%20and%20position%20update%20push
|
1025
|
+
|
645
1026
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
646
1027
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
647
1028
|
"""
|
648
1029
|
await self.load_markets()
|
649
1030
|
await self.authenticate()
|
650
1031
|
type = None
|
1032
|
+
subType = None
|
651
1033
|
type, params = self.handle_market_type_and_params('watchBalance', None, params)
|
1034
|
+
subType, params = self.handle_sub_type_and_params('watchBalance', None, params, 'linear')
|
652
1035
|
isSpot = (type == 'spot')
|
653
1036
|
spotSubHash = 'spot:balance'
|
654
1037
|
swapSubHash = 'swap:private'
|
@@ -656,16 +1039,22 @@ class bingx(ccxt.async_support.bingx):
|
|
656
1039
|
swapMessageHash = 'swap:balance'
|
657
1040
|
messageHash = spotMessageHash if isSpot else swapMessageHash
|
658
1041
|
subscriptionHash = spotSubHash if isSpot else swapSubHash
|
659
|
-
url = self.urls['api']['ws'][type] + '?listenKey=' + self.options['listenKey']
|
660
1042
|
request = None
|
1043
|
+
baseUrl = None
|
661
1044
|
uuid = self.uuid()
|
662
|
-
if type == '
|
1045
|
+
if type == 'swap':
|
1046
|
+
if subType == 'inverse':
|
1047
|
+
raise NotSupported(self.id + ' watchBalance is not supported for inverse swap markets yet')
|
1048
|
+
baseUrl = self.safe_string(self.urls['api']['ws'], subType)
|
1049
|
+
else:
|
1050
|
+
baseUrl = self.safe_string(self.urls['api']['ws'], type)
|
663
1051
|
request = {
|
664
1052
|
'id': uuid,
|
665
1053
|
'dataType': 'ACCOUNT_UPDATE',
|
666
1054
|
}
|
1055
|
+
url = baseUrl + '?listenKey=' + self.options['listenKey']
|
667
1056
|
client = self.client(url)
|
668
|
-
self.set_balance_cache(client, type, subscriptionHash, params)
|
1057
|
+
self.set_balance_cache(client, type, subType, subscriptionHash, params)
|
669
1058
|
fetchBalanceSnapshot = None
|
670
1059
|
awaitBalanceSnapshot = None
|
671
1060
|
fetchBalanceSnapshot, params = self.handle_option_and_params(params, 'watchBalance', 'fetchBalanceSnapshot', True)
|
@@ -674,7 +1063,7 @@ class bingx(ccxt.async_support.bingx):
|
|
674
1063
|
await client.future(type + ':fetchBalanceSnapshot')
|
675
1064
|
return await self.watch(url, messageHash, request, subscriptionHash)
|
676
1065
|
|
677
|
-
def set_balance_cache(self, client: Client, type, subscriptionHash, params):
|
1066
|
+
def set_balance_cache(self, client: Client, type, subType, subscriptionHash, params):
|
678
1067
|
if subscriptionHash in client.subscriptions:
|
679
1068
|
return
|
680
1069
|
fetchBalanceSnapshot = self.handle_option_and_params(params, 'watchBalance', 'fetchBalanceSnapshot', True)
|
@@ -682,12 +1071,12 @@ class bingx(ccxt.async_support.bingx):
|
|
682
1071
|
messageHash = type + ':fetchBalanceSnapshot'
|
683
1072
|
if not (messageHash in client.futures):
|
684
1073
|
client.future(messageHash)
|
685
|
-
self.spawn(self.load_balance_snapshot, client, messageHash, type)
|
1074
|
+
self.spawn(self.load_balance_snapshot, client, messageHash, type, subType)
|
686
1075
|
else:
|
687
1076
|
self.balance[type] = {}
|
688
1077
|
|
689
|
-
async def load_balance_snapshot(self, client, messageHash, type):
|
690
|
-
response = await self.fetch_balance({'type': type})
|
1078
|
+
async def load_balance_snapshot(self, client, messageHash, type, subType):
|
1079
|
+
response = await self.fetch_balance({'type': type, 'subType': subType})
|
691
1080
|
self.balance[type] = self.extend(response, self.safe_value(self.balance, type, {}))
|
692
1081
|
# don't remove the future from the .futures cache
|
693
1082
|
future = client.futures[messageHash]
|
@@ -721,7 +1110,7 @@ class bingx(ccxt.async_support.bingx):
|
|
721
1110
|
try:
|
722
1111
|
await self.userAuthPrivatePutUserDataStream({'listenKey': listenKey}) # self.extend the expiry
|
723
1112
|
except Exception as error:
|
724
|
-
types = ['spot', '
|
1113
|
+
types = ['spot', 'linear', 'inverse']
|
725
1114
|
for i in range(0, len(types)):
|
726
1115
|
type = types[i]
|
727
1116
|
url = self.urls['api']['ws'][type] + '?listenKey=' + listenKey
|
@@ -928,13 +1317,16 @@ class bingx(ccxt.async_support.bingx):
|
|
928
1317
|
# }
|
929
1318
|
#
|
930
1319
|
isSpot = ('dataType' in message)
|
931
|
-
result = self.
|
1320
|
+
result = self.safe_dict_2(message, 'data', 'o', {})
|
932
1321
|
cachedTrades = self.myTrades
|
933
1322
|
if cachedTrades is None:
|
934
1323
|
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
935
1324
|
cachedTrades = ArrayCacheBySymbolById(limit)
|
936
1325
|
self.myTrades = cachedTrades
|
937
|
-
|
1326
|
+
type = 'spot' if isSpot else 'swap'
|
1327
|
+
marketId = self.safe_string(result, 's')
|
1328
|
+
market = self.safe_market(marketId, None, '-', type)
|
1329
|
+
parsed = self.parse_trade(result, market)
|
938
1330
|
symbol = parsed['symbol']
|
939
1331
|
spotHash = 'spot:mytrades'
|
940
1332
|
swapHash = 'swap:mytrades'
|
@@ -980,10 +1372,12 @@ class bingx(ccxt.async_support.bingx):
|
|
980
1372
|
# }
|
981
1373
|
# }
|
982
1374
|
#
|
983
|
-
a = self.
|
984
|
-
data = self.
|
1375
|
+
a = self.safe_dict(message, 'a', {})
|
1376
|
+
data = self.safe_list(a, 'B', [])
|
985
1377
|
timestamp = self.safe_integer_2(message, 'T', 'E')
|
986
1378
|
type = 'swap' if ('P' in a) else 'spot'
|
1379
|
+
if not (type in self.balance):
|
1380
|
+
self.balance[type] = {}
|
987
1381
|
self.balance[type]['info'] = data
|
988
1382
|
self.balance[type]['timestamp'] = timestamp
|
989
1383
|
self.balance[type]['datetime'] = self.iso8601(timestamp)
|
@@ -991,11 +1385,10 @@ class bingx(ccxt.async_support.bingx):
|
|
991
1385
|
balance = data[i]
|
992
1386
|
currencyId = self.safe_string(balance, 'a')
|
993
1387
|
code = self.safe_currency_code(currencyId)
|
994
|
-
account = self.
|
1388
|
+
account = self.account()
|
1389
|
+
account['info'] = balance
|
1390
|
+
account['used'] = self.safe_string(balance, 'lk')
|
995
1391
|
account['free'] = self.safe_string(balance, 'wb')
|
996
|
-
balanceChange = self.safe_string(balance, 'bc')
|
997
|
-
if account['used'] is not None:
|
998
|
-
account['used'] = Precise.string_sub(self.safe_string(account, 'used'), balanceChange)
|
999
1392
|
self.balance[type][code] = account
|
1000
1393
|
self.balance[type] = self.safe_balance(self.balance[type])
|
1001
1394
|
client.resolve(self.balance[type], type + ':balance')
|