ccxt 4.2.77__py2.py3-none-any.whl → 4.4.48__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +36 -14
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +112 -48
- ccxt/abstract/binancecoinm.py +112 -48
- ccxt/abstract/binanceus.py +147 -83
- ccxt/abstract/binanceusdm.py +112 -48
- ccxt/abstract/bingx.py +133 -78
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitfinex1.py +69 -0
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +8 -1
- ccxt/abstract/bitmart.py +13 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitpanda.py +0 -12
- ccxt/abstract/bitrue.py +3 -3
- ccxt/abstract/bitstamp.py +26 -3
- ccxt/abstract/blofin.py +24 -0
- ccxt/abstract/btcbox.py +1 -0
- ccxt/abstract/bybit.py +29 -14
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbase.py +6 -0
- ccxt/abstract/coinbaseadvanced.py +94 -0
- ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/coincatch.py +94 -0
- ccxt/abstract/coinex.py +233 -123
- ccxt/abstract/coinmetro.py +1 -0
- ccxt/abstract/cryptocom.py +14 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/gate.py +20 -0
- ccxt/abstract/gateio.py +20 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hashkey.py +67 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +4 -3
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +24 -0
- ccxt/abstract/kucoinfutures.py +34 -0
- ccxt/abstract/luno.py +2 -0
- ccxt/abstract/mexc.py +4 -0
- ccxt/abstract/myokx.py +340 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +30 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/oxfun.py +34 -0
- ccxt/abstract/paradex.py +40 -0
- ccxt/abstract/phemex.py +1 -0
- ccxt/abstract/upbit.py +4 -0
- ccxt/abstract/vertex.py +19 -0
- ccxt/abstract/whitebit.py +31 -1
- ccxt/abstract/woo.py +6 -2
- ccxt/abstract/woofipro.py +119 -0
- ccxt/abstract/xt.py +153 -0
- ccxt/abstract/zonda.py +6 -0
- ccxt/ace.py +164 -60
- ccxt/alpaca.py +727 -63
- ccxt/ascendex.py +395 -249
- ccxt/async_support/__init__.py +36 -14
- ccxt/async_support/ace.py +164 -60
- ccxt/async_support/alpaca.py +727 -63
- ccxt/async_support/ascendex.py +396 -249
- ccxt/async_support/base/exchange.py +531 -155
- ccxt/async_support/base/ws/aiohttp_client.py +28 -5
- ccxt/async_support/base/ws/cache.py +3 -2
- ccxt/async_support/base/ws/client.py +26 -5
- ccxt/async_support/base/ws/fast_client.py +4 -3
- ccxt/async_support/base/ws/functions.py +1 -1
- ccxt/async_support/base/ws/future.py +40 -31
- ccxt/async_support/base/ws/order_book_side.py +3 -0
- ccxt/async_support/bequant.py +1 -1
- ccxt/async_support/bigone.py +329 -202
- ccxt/async_support/binance.py +3030 -1087
- ccxt/async_support/binancecoinm.py +2 -1
- ccxt/async_support/binanceus.py +12 -1
- ccxt/async_support/binanceusdm.py +3 -1
- ccxt/async_support/bingx.py +3104 -880
- ccxt/async_support/bit2c.py +119 -38
- ccxt/async_support/bitbank.py +215 -76
- ccxt/async_support/bitbns.py +124 -53
- ccxt/async_support/bitfinex.py +3236 -1078
- ccxt/async_support/bitfinex1.py +1711 -0
- ccxt/async_support/bitflyer.py +238 -49
- ccxt/async_support/bitget.py +1513 -563
- ccxt/async_support/bithumb.py +199 -65
- ccxt/async_support/bitmart.py +1320 -435
- ccxt/async_support/bitmex.py +308 -111
- ccxt/async_support/bitopro.py +256 -96
- ccxt/async_support/bitrue.py +365 -233
- ccxt/async_support/bitso.py +201 -89
- ccxt/async_support/bitstamp.py +438 -269
- ccxt/async_support/bitteam.py +179 -73
- ccxt/async_support/bitvavo.py +180 -70
- ccxt/async_support/bl3p.py +92 -25
- ccxt/async_support/blockchaincom.py +193 -79
- ccxt/async_support/blofin.py +392 -148
- ccxt/async_support/btcalpha.py +161 -55
- ccxt/async_support/btcbox.py +250 -34
- ccxt/async_support/btcmarkets.py +232 -85
- ccxt/async_support/btcturk.py +159 -60
- ccxt/async_support/bybit.py +2231 -1193
- ccxt/async_support/cex.py +1409 -1329
- ccxt/async_support/coinbase.py +1454 -287
- ccxt/async_support/coinbaseadvanced.py +17 -0
- ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/async_support/coinbaseinternational.py +428 -88
- ccxt/async_support/coincatch.py +5152 -0
- ccxt/async_support/coincheck.py +121 -38
- ccxt/async_support/coinex.py +4020 -3339
- ccxt/async_support/coinlist.py +273 -116
- ccxt/async_support/coinmate.py +204 -97
- ccxt/async_support/coinmetro.py +203 -110
- ccxt/async_support/coinone.py +142 -68
- ccxt/async_support/coinsph.py +206 -89
- ccxt/async_support/coinspot.py +137 -62
- ccxt/async_support/cryptocom.py +515 -185
- ccxt/async_support/currencycom.py +203 -85
- ccxt/async_support/defx.py +2066 -0
- ccxt/async_support/delta.py +404 -109
- ccxt/async_support/deribit.py +557 -323
- ccxt/async_support/digifinex.py +340 -223
- ccxt/async_support/ellipx.py +1826 -0
- ccxt/async_support/exmo.py +259 -128
- ccxt/async_support/gate.py +1472 -463
- ccxt/async_support/gemini.py +206 -84
- ccxt/async_support/hashkey.py +4164 -0
- ccxt/async_support/hitbtc.py +334 -178
- ccxt/async_support/hollaex.py +134 -83
- ccxt/async_support/htx.py +1095 -563
- ccxt/async_support/huobijp.py +105 -56
- ccxt/async_support/hyperliquid.py +1633 -268
- ccxt/async_support/idex.py +148 -95
- ccxt/async_support/independentreserve.py +236 -31
- ccxt/async_support/indodax.py +165 -62
- ccxt/async_support/kraken.py +871 -354
- ccxt/async_support/krakenfutures.py +324 -100
- ccxt/async_support/kucoin.py +917 -357
- ccxt/async_support/kucoinfutures.py +1004 -149
- ccxt/async_support/kuna.py +138 -106
- ccxt/async_support/latoken.py +135 -79
- ccxt/async_support/lbank.py +290 -113
- ccxt/async_support/luno.py +112 -62
- ccxt/async_support/lykke.py +104 -55
- ccxt/async_support/mercado.py +36 -29
- ccxt/async_support/mexc.py +995 -429
- ccxt/async_support/myokx.py +43 -0
- ccxt/async_support/ndax.py +163 -82
- ccxt/async_support/novadax.py +121 -75
- ccxt/async_support/oceanex.py +175 -59
- ccxt/async_support/okcoin.py +222 -163
- ccxt/async_support/okx.py +1776 -454
- ccxt/async_support/onetrading.py +132 -414
- ccxt/async_support/oxfun.py +2832 -0
- ccxt/async_support/p2b.py +79 -51
- ccxt/async_support/paradex.py +2017 -0
- ccxt/async_support/paymium.py +56 -32
- ccxt/async_support/phemex.py +572 -196
- ccxt/async_support/poloniex.py +218 -95
- ccxt/async_support/poloniexfutures.py +260 -92
- ccxt/async_support/probit.py +143 -110
- ccxt/async_support/timex.py +123 -70
- ccxt/async_support/tokocrypto.py +129 -93
- ccxt/async_support/tradeogre.py +39 -25
- ccxt/async_support/upbit.py +322 -113
- ccxt/async_support/vertex.py +2983 -0
- ccxt/async_support/wavesexchange.py +227 -173
- ccxt/async_support/wazirx.py +145 -65
- ccxt/async_support/whitebit.py +533 -138
- ccxt/async_support/woo.py +1137 -296
- ccxt/async_support/woofipro.py +2716 -0
- ccxt/async_support/xt.py +4628 -0
- ccxt/async_support/yobit.py +160 -92
- ccxt/async_support/zaif.py +80 -33
- ccxt/async_support/zonda.py +140 -69
- ccxt/base/errors.py +51 -20
- ccxt/base/exchange.py +1722 -480
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +223 -4
- ccxt/bequant.py +1 -1
- ccxt/bigone.py +329 -202
- ccxt/binance.py +3030 -1087
- ccxt/binancecoinm.py +2 -1
- ccxt/binanceus.py +12 -1
- ccxt/binanceusdm.py +3 -1
- ccxt/bingx.py +3104 -880
- ccxt/bit2c.py +119 -38
- ccxt/bitbank.py +215 -76
- ccxt/bitbns.py +124 -53
- ccxt/bitfinex.py +3235 -1078
- ccxt/bitfinex1.py +1710 -0
- ccxt/bitflyer.py +238 -49
- ccxt/bitget.py +1513 -563
- ccxt/bithumb.py +198 -65
- ccxt/bitmart.py +1320 -435
- ccxt/bitmex.py +308 -111
- ccxt/bitopro.py +256 -96
- ccxt/bitrue.py +365 -233
- ccxt/bitso.py +201 -89
- ccxt/bitstamp.py +438 -269
- ccxt/bitteam.py +179 -73
- ccxt/bitvavo.py +180 -70
- ccxt/bl3p.py +92 -25
- ccxt/blockchaincom.py +193 -79
- ccxt/blofin.py +392 -148
- ccxt/btcalpha.py +161 -55
- ccxt/btcbox.py +250 -34
- ccxt/btcmarkets.py +232 -85
- ccxt/btcturk.py +159 -60
- ccxt/bybit.py +2231 -1193
- ccxt/cex.py +1408 -1329
- ccxt/coinbase.py +1454 -287
- ccxt/coinbaseadvanced.py +17 -0
- ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/coinbaseinternational.py +428 -88
- ccxt/coincatch.py +5152 -0
- ccxt/coincheck.py +121 -38
- ccxt/coinex.py +4020 -3339
- ccxt/coinlist.py +273 -116
- ccxt/coinmate.py +204 -97
- ccxt/coinmetro.py +203 -110
- ccxt/coinone.py +142 -68
- ccxt/coinsph.py +206 -89
- ccxt/coinspot.py +137 -62
- ccxt/cryptocom.py +515 -185
- ccxt/currencycom.py +203 -85
- ccxt/defx.py +2065 -0
- ccxt/delta.py +404 -109
- ccxt/deribit.py +557 -323
- ccxt/digifinex.py +340 -223
- ccxt/ellipx.py +1826 -0
- ccxt/exmo.py +259 -128
- ccxt/gate.py +1472 -463
- ccxt/gemini.py +206 -84
- ccxt/hashkey.py +4164 -0
- ccxt/hitbtc.py +334 -178
- ccxt/hollaex.py +134 -83
- ccxt/htx.py +1095 -563
- ccxt/huobijp.py +105 -56
- ccxt/hyperliquid.py +1632 -268
- ccxt/idex.py +148 -95
- ccxt/independentreserve.py +235 -31
- ccxt/indodax.py +165 -62
- ccxt/kraken.py +871 -354
- ccxt/krakenfutures.py +324 -100
- ccxt/kucoin.py +917 -357
- ccxt/kucoinfutures.py +1004 -149
- ccxt/kuna.py +138 -106
- ccxt/latoken.py +135 -79
- ccxt/lbank.py +290 -113
- ccxt/luno.py +112 -62
- ccxt/lykke.py +104 -55
- ccxt/mercado.py +36 -29
- ccxt/mexc.py +994 -429
- ccxt/myokx.py +43 -0
- ccxt/ndax.py +163 -82
- ccxt/novadax.py +121 -75
- ccxt/oceanex.py +175 -59
- ccxt/okcoin.py +222 -163
- ccxt/okx.py +1776 -454
- ccxt/onetrading.py +132 -414
- ccxt/oxfun.py +2831 -0
- ccxt/p2b.py +79 -51
- ccxt/paradex.py +2017 -0
- ccxt/paymium.py +56 -32
- ccxt/phemex.py +572 -196
- ccxt/poloniex.py +218 -95
- ccxt/poloniexfutures.py +260 -92
- ccxt/pro/__init__.py +29 -5
- ccxt/pro/alpaca.py +32 -17
- ccxt/pro/ascendex.py +62 -14
- ccxt/pro/bequant.py +4 -0
- ccxt/pro/binance.py +1596 -329
- ccxt/pro/binancecoinm.py +1 -0
- ccxt/pro/binanceus.py +2 -9
- ccxt/pro/binanceusdm.py +2 -0
- ccxt/pro/bingx.py +527 -134
- ccxt/pro/bitcoincom.py +4 -1
- ccxt/pro/bitfinex.py +731 -266
- ccxt/pro/bitfinex1.py +635 -0
- ccxt/pro/bitget.py +726 -357
- ccxt/pro/bithumb.py +380 -0
- ccxt/pro/bitmart.py +138 -39
- ccxt/pro/bitmex.py +199 -40
- ccxt/pro/bitopro.py +25 -13
- ccxt/pro/bitrue.py +31 -32
- ccxt/pro/bitstamp.py +7 -6
- ccxt/pro/bitvavo.py +203 -81
- ccxt/pro/blockchaincom.py +30 -17
- ccxt/pro/blofin.py +692 -0
- ccxt/pro/bybit.py +791 -82
- ccxt/pro/cex.py +99 -51
- ccxt/pro/coinbase.py +220 -30
- ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
- ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
- ccxt/pro/coinbaseinternational.py +193 -30
- ccxt/pro/coincatch.py +1464 -0
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +965 -665
- ccxt/pro/coinone.py +17 -10
- ccxt/pro/cryptocom.py +446 -66
- ccxt/pro/currencycom.py +11 -10
- ccxt/pro/defx.py +832 -0
- ccxt/pro/deribit.py +167 -31
- ccxt/pro/exmo.py +252 -20
- ccxt/pro/gate.py +729 -64
- ccxt/pro/gemini.py +44 -26
- ccxt/pro/hashkey.py +802 -0
- ccxt/pro/hitbtc.py +208 -103
- ccxt/pro/hollaex.py +25 -9
- ccxt/pro/htx.py +83 -39
- ccxt/pro/huobijp.py +17 -16
- ccxt/pro/hyperliquid.py +502 -31
- ccxt/pro/idex.py +28 -13
- ccxt/pro/independentreserve.py +21 -16
- ccxt/pro/kraken.py +298 -51
- ccxt/pro/krakenfutures.py +166 -75
- ccxt/pro/kucoin.py +395 -77
- ccxt/pro/kucoinfutures.py +400 -99
- ccxt/pro/lbank.py +52 -31
- ccxt/pro/luno.py +12 -10
- ccxt/pro/mexc.py +400 -50
- ccxt/pro/myokx.py +28 -0
- ccxt/pro/ndax.py +25 -12
- ccxt/pro/okcoin.py +28 -9
- ccxt/pro/okx.py +935 -124
- ccxt/pro/onetrading.py +41 -24
- ccxt/pro/oxfun.py +1054 -0
- ccxt/pro/p2b.py +100 -24
- ccxt/pro/paradex.py +352 -0
- ccxt/pro/phemex.py +92 -33
- ccxt/pro/poloniex.py +128 -49
- ccxt/pro/poloniexfutures.py +53 -32
- ccxt/pro/probit.py +92 -85
- ccxt/pro/upbit.py +401 -8
- ccxt/pro/vertex.py +943 -0
- ccxt/pro/wazirx.py +46 -28
- ccxt/pro/whitebit.py +65 -12
- ccxt/pro/woo.py +437 -65
- ccxt/pro/woofipro.py +1271 -0
- ccxt/pro/xt.py +1067 -0
- ccxt/probit.py +143 -110
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/__init__.py +38 -0
- ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
- ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
- ccxt/static_dependencies/lark/ast_utils.py +59 -0
- ccxt/static_dependencies/lark/common.py +86 -0
- ccxt/static_dependencies/lark/exceptions.py +292 -0
- ccxt/static_dependencies/lark/grammar.py +130 -0
- ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
- ccxt/static_dependencies/lark/indenter.py +143 -0
- ccxt/static_dependencies/lark/lark.py +658 -0
- ccxt/static_dependencies/lark/lexer.py +678 -0
- ccxt/static_dependencies/lark/load_grammar.py +1428 -0
- ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
- ccxt/static_dependencies/lark/parser_frontends.py +257 -0
- ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
- ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
- ccxt/static_dependencies/lark/parsers/earley.py +314 -0
- ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
- ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
- ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
- ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
- ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
- ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/lark/reconstruct.py +107 -0
- ccxt/static_dependencies/lark/tools/__init__.py +70 -0
- ccxt/static_dependencies/lark/tools/nearley.py +202 -0
- ccxt/static_dependencies/lark/tools/serialize.py +32 -0
- ccxt/static_dependencies/lark/tools/standalone.py +196 -0
- ccxt/static_dependencies/lark/tree.py +267 -0
- ccxt/static_dependencies/lark/tree_matcher.py +186 -0
- ccxt/static_dependencies/lark/tree_templates.py +180 -0
- ccxt/static_dependencies/lark/utils.py +343 -0
- ccxt/static_dependencies/lark/visitors.py +596 -0
- ccxt/static_dependencies/marshmallow/__init__.py +81 -0
- ccxt/static_dependencies/marshmallow/base.py +65 -0
- ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
- ccxt/static_dependencies/marshmallow/decorators.py +231 -0
- ccxt/static_dependencies/marshmallow/error_store.py +60 -0
- ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
- ccxt/static_dependencies/marshmallow/fields.py +2114 -0
- ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/schema.py +1228 -0
- ccxt/static_dependencies/marshmallow/types.py +12 -0
- ccxt/static_dependencies/marshmallow/utils.py +378 -0
- ccxt/static_dependencies/marshmallow/validate.py +678 -0
- ccxt/static_dependencies/marshmallow/warnings.py +2 -0
- ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
- ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
- ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
- ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
- ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
- ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
- ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/static_dependencies/starknet/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
- ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
- ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
- ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
- ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
- ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
- ccxt/static_dependencies/starknet/common.py +15 -0
- ccxt/static_dependencies/starknet/constants.py +39 -0
- ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
- ccxt/static_dependencies/starknet/hash/address.py +79 -0
- ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
- ccxt/static_dependencies/starknet/hash/selector.py +16 -0
- ccxt/static_dependencies/starknet/hash/storage.py +12 -0
- ccxt/static_dependencies/starknet/hash/utils.py +78 -0
- ccxt/static_dependencies/starknet/models/__init__.py +0 -0
- ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
- ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
- ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
- ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
- ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
- ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
- ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
- ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
- ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
- ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
- ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
- ccxt/static_dependencies/starknet/utils/schema.py +13 -0
- ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
- ccxt/static_dependencies/starkware/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
- ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
- ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
- ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
- ccxt/static_dependencies/sympy/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
- ccxt/static_dependencies/sympy/external/__init__.py +0 -0
- ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
- ccxt/static_dependencies/sympy/external/importtools.py +187 -0
- ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
- ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
- ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
- ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
- ccxt/test/{test_async.py → tests_async.py} +456 -391
- ccxt/test/tests_helpers.py +285 -0
- ccxt/test/tests_init.py +39 -0
- ccxt/test/{test_sync.py → tests_sync.py} +456 -393
- ccxt/timex.py +123 -70
- ccxt/tokocrypto.py +129 -93
- ccxt/tradeogre.py +39 -25
- ccxt/upbit.py +322 -113
- ccxt/vertex.py +2983 -0
- ccxt/wavesexchange.py +227 -173
- ccxt/wazirx.py +145 -65
- ccxt/whitebit.py +533 -138
- ccxt/woo.py +1137 -296
- ccxt/woofipro.py +2716 -0
- ccxt/xt.py +4627 -0
- ccxt/yobit.py +159 -92
- ccxt/zaif.py +80 -33
- ccxt/zonda.py +140 -69
- ccxt-4.4.48.dist-info/LICENSE.txt +21 -0
- ccxt-4.4.48.dist-info/METADATA +646 -0
- ccxt-4.4.48.dist-info/RECORD +669 -0
- {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/WHEEL +1 -1
- ccxt/abstract/bitbay.py +0 -47
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3496
- ccxt/async_support/flowbtc.py +0 -34
- ccxt/bitbay.py +0 -17
- ccxt/bitfinex2.py +0 -3496
- ccxt/flowbtc.py +0 -34
- ccxt/hitbtc3.py +0 -16
- ccxt/pro/bitfinex2.py +0 -1081
- ccxt/test/base/__init__.py +0 -28
- ccxt/test/base/test_account.py +0 -26
- ccxt/test/base/test_balance.py +0 -56
- ccxt/test/base/test_borrow_interest.py +0 -35
- ccxt/test/base/test_borrow_rate.py +0 -32
- ccxt/test/base/test_calculate_fee.py +0 -51
- ccxt/test/base/test_crypto.py +0 -127
- ccxt/test/base/test_currency.py +0 -76
- ccxt/test/base/test_datetime.py +0 -103
- ccxt/test/base/test_decimal_to_precision.py +0 -392
- ccxt/test/base/test_deep_extend.py +0 -68
- ccxt/test/base/test_deposit_withdrawal.py +0 -50
- ccxt/test/base/test_exchange_datetime_functions.py +0 -76
- ccxt/test/base/test_funding_rate_history.py +0 -29
- ccxt/test/base/test_last_price.py +0 -32
- ccxt/test/base/test_ledger_entry.py +0 -45
- ccxt/test/base/test_ledger_item.py +0 -48
- ccxt/test/base/test_leverage_tier.py +0 -33
- ccxt/test/base/test_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -190
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -32
- ccxt/test/base/test_open_interest.py +0 -32
- ccxt/test/base/test_order.py +0 -64
- ccxt/test/base/test_order_book.py +0 -63
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -345
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -86
- ccxt/test/base/test_trade.py +0 -47
- ccxt/test/base/test_trading_fee.py +0 -26
- ccxt/test/base/test_transaction.py +0 -39
- ccxt-4.2.77.dist-info/METADATA +0 -626
- ccxt-4.2.77.dist-info/RECORD +0 -534
- {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
ccxt/pro/bitfinex2.py
DELETED
@@ -1,1081 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
|
3
|
-
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
4
|
-
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
5
|
-
|
6
|
-
import ccxt.async_support
|
7
|
-
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
|
8
|
-
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Ticker, Trade
|
10
|
-
from ccxt.async_support.base.ws.client import Client
|
11
|
-
from typing import List
|
12
|
-
from ccxt.base.errors import ExchangeError
|
13
|
-
from ccxt.base.errors import InvalidNonce
|
14
|
-
from ccxt.base.errors import AuthenticationError
|
15
|
-
from ccxt.base.precise import Precise
|
16
|
-
|
17
|
-
|
18
|
-
class bitfinex2(ccxt.async_support.bitfinex2):
|
19
|
-
|
20
|
-
def describe(self):
|
21
|
-
return self.deep_extend(super(bitfinex2, self).describe(), {
|
22
|
-
'has': {
|
23
|
-
'ws': True,
|
24
|
-
'watchTicker': True,
|
25
|
-
'watchTickers': False,
|
26
|
-
'watchOrderBook': True,
|
27
|
-
'watchTrades': True,
|
28
|
-
'watchMyTrades': True,
|
29
|
-
'watchBalance': True,
|
30
|
-
'watchOHLCV': True,
|
31
|
-
'watchOrders': True,
|
32
|
-
},
|
33
|
-
'urls': {
|
34
|
-
'api': {
|
35
|
-
'ws': {
|
36
|
-
'public': 'wss://api-pub.bitfinex.com/ws/2',
|
37
|
-
'private': 'wss://api.bitfinex.com/ws/2',
|
38
|
-
},
|
39
|
-
},
|
40
|
-
},
|
41
|
-
'options': {
|
42
|
-
'watchOrderBook': {
|
43
|
-
'prec': 'P0',
|
44
|
-
'freq': 'F0',
|
45
|
-
},
|
46
|
-
'ordersLimit': 1000,
|
47
|
-
'checksum': True,
|
48
|
-
},
|
49
|
-
})
|
50
|
-
|
51
|
-
async def subscribe(self, channel, symbol, params={}):
|
52
|
-
await self.load_markets()
|
53
|
-
market = self.market(symbol)
|
54
|
-
marketId = market['id']
|
55
|
-
url = self.urls['api']['ws']['public']
|
56
|
-
client = self.client(url)
|
57
|
-
messageHash = channel + ':' + marketId
|
58
|
-
request = {
|
59
|
-
'event': 'subscribe',
|
60
|
-
'channel': channel,
|
61
|
-
'symbol': marketId,
|
62
|
-
}
|
63
|
-
result = await self.watch(url, messageHash, self.deep_extend(request, params), messageHash, {'checksum': False})
|
64
|
-
checksum = self.safe_bool(self.options, 'checksum', True)
|
65
|
-
if checksum and not client.subscriptions[messageHash]['checksum'] and (channel == 'book'):
|
66
|
-
client.subscriptions[messageHash]['checksum'] = True
|
67
|
-
await client.send({
|
68
|
-
'event': 'conf',
|
69
|
-
'flags': 131072,
|
70
|
-
})
|
71
|
-
return result
|
72
|
-
|
73
|
-
async def subscribe_private(self, messageHash):
|
74
|
-
await self.load_markets()
|
75
|
-
await self.authenticate()
|
76
|
-
url = self.urls['api']['ws']['private']
|
77
|
-
return await self.watch(url, messageHash, None, 1)
|
78
|
-
|
79
|
-
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
80
|
-
"""
|
81
|
-
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
82
|
-
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
83
|
-
:param str timeframe: the length of time each candle represents
|
84
|
-
:param int [since]: timestamp in ms of the earliest candle to fetch
|
85
|
-
:param int [limit]: the maximum amount of candles to fetch
|
86
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
87
|
-
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
88
|
-
"""
|
89
|
-
await self.load_markets()
|
90
|
-
market = self.market(symbol)
|
91
|
-
symbol = market['symbol']
|
92
|
-
interval = self.safe_string(self.timeframes, timeframe, timeframe)
|
93
|
-
channel = 'candles'
|
94
|
-
key = 'trade:' + interval + ':' + market['id']
|
95
|
-
messageHash = channel + ':' + interval + ':' + market['id']
|
96
|
-
request = {
|
97
|
-
'event': 'subscribe',
|
98
|
-
'channel': channel,
|
99
|
-
'key': key,
|
100
|
-
}
|
101
|
-
url = self.urls['api']['ws']['public']
|
102
|
-
# not using subscribe here because self message has a different format
|
103
|
-
ohlcv = await self.watch(url, messageHash, self.deep_extend(request, params), messageHash)
|
104
|
-
if self.newUpdates:
|
105
|
-
limit = ohlcv.getLimit(symbol, limit)
|
106
|
-
return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
|
107
|
-
|
108
|
-
def handle_ohlcv(self, client: Client, message, subscription):
|
109
|
-
#
|
110
|
-
# initial snapshot
|
111
|
-
# [
|
112
|
-
# 341527, # channel id
|
113
|
-
# [
|
114
|
-
# [
|
115
|
-
# 1654705860000, # timestamp
|
116
|
-
# 1802.6, # open
|
117
|
-
# 1800.3, # close
|
118
|
-
# 1802.8, # high
|
119
|
-
# 1800.3, # low
|
120
|
-
# 86.49588236 # volume
|
121
|
-
# ],
|
122
|
-
# [
|
123
|
-
# 1654705800000,
|
124
|
-
# 1803.6,
|
125
|
-
# 1802.6,
|
126
|
-
# 1804.9,
|
127
|
-
# 1802.3,
|
128
|
-
# 74.6348086
|
129
|
-
# ],
|
130
|
-
# [
|
131
|
-
# 1654705740000,
|
132
|
-
# 1802.5,
|
133
|
-
# 1803.2,
|
134
|
-
# 1804.4,
|
135
|
-
# 1802.4,
|
136
|
-
# 23.61801085
|
137
|
-
# ]
|
138
|
-
# ]
|
139
|
-
# ]
|
140
|
-
#
|
141
|
-
# update
|
142
|
-
# [
|
143
|
-
# 211171,
|
144
|
-
# [
|
145
|
-
# 1654705680000,
|
146
|
-
# 1801,
|
147
|
-
# 1802.4,
|
148
|
-
# 1802.9,
|
149
|
-
# 1800.4,
|
150
|
-
# 23.91911091
|
151
|
-
# ]
|
152
|
-
# ]
|
153
|
-
#
|
154
|
-
data = self.safe_value(message, 1, [])
|
155
|
-
ohlcvs = None
|
156
|
-
first = self.safe_value(data, 0)
|
157
|
-
if isinstance(first, list):
|
158
|
-
# snapshot
|
159
|
-
ohlcvs = data
|
160
|
-
else:
|
161
|
-
# update
|
162
|
-
ohlcvs = [data]
|
163
|
-
channel = self.safe_value(subscription, 'channel')
|
164
|
-
key = self.safe_string(subscription, 'key')
|
165
|
-
keyParts = key.split(':')
|
166
|
-
interval = self.safe_string(keyParts, 1)
|
167
|
-
marketId = key
|
168
|
-
marketId = marketId.replace('trade:', '')
|
169
|
-
marketId = marketId.replace(interval + ':', '')
|
170
|
-
market = self.safe_market(marketId)
|
171
|
-
timeframe = self.find_timeframe(interval)
|
172
|
-
symbol = market['symbol']
|
173
|
-
messageHash = channel + ':' + interval + ':' + marketId
|
174
|
-
self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
|
175
|
-
stored = self.safe_value(self.ohlcvs[symbol], timeframe)
|
176
|
-
if stored is None:
|
177
|
-
limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
|
178
|
-
stored = ArrayCacheByTimestamp(limit)
|
179
|
-
self.ohlcvs[symbol][timeframe] = stored
|
180
|
-
ohlcvsLength = len(ohlcvs)
|
181
|
-
for i in range(0, ohlcvsLength):
|
182
|
-
ohlcv = ohlcvs[ohlcvsLength - i - 1]
|
183
|
-
parsed = self.parse_ohlcv(ohlcv, market)
|
184
|
-
stored.append(parsed)
|
185
|
-
client.resolve(stored, messageHash)
|
186
|
-
|
187
|
-
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
188
|
-
"""
|
189
|
-
get the list of most recent trades for a particular symbol
|
190
|
-
:param str symbol: unified symbol of the market to fetch trades for
|
191
|
-
:param int [since]: timestamp in ms of the earliest trade to fetch
|
192
|
-
:param int [limit]: the maximum amount of trades to fetch
|
193
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
194
|
-
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
195
|
-
"""
|
196
|
-
trades = await self.subscribe('trades', symbol, params)
|
197
|
-
if self.newUpdates:
|
198
|
-
limit = trades.getLimit(symbol, limit)
|
199
|
-
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
200
|
-
|
201
|
-
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
202
|
-
"""
|
203
|
-
watches information on multiple trades made by the user
|
204
|
-
:param str symbol: unified market symbol of the market trades were made in
|
205
|
-
:param int [since]: the earliest time in ms to fetch trades for
|
206
|
-
:param int [limit]: the maximum number of trade structures to retrieve
|
207
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
208
|
-
:returns dict[]: a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
|
209
|
-
"""
|
210
|
-
await self.load_markets()
|
211
|
-
messageHash = 'myTrade'
|
212
|
-
if symbol is not None:
|
213
|
-
market = self.market(symbol)
|
214
|
-
messageHash += ':' + market['id']
|
215
|
-
trades = await self.subscribe_private(messageHash)
|
216
|
-
if self.newUpdates:
|
217
|
-
limit = trades.getLimit(symbol, limit)
|
218
|
-
return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
|
219
|
-
|
220
|
-
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
221
|
-
"""
|
222
|
-
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
223
|
-
:param str symbol: unified symbol of the market to fetch the ticker for
|
224
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
225
|
-
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
226
|
-
"""
|
227
|
-
return await self.subscribe('ticker', symbol, params)
|
228
|
-
|
229
|
-
def handle_my_trade(self, client: Client, message, subscription={}):
|
230
|
-
#
|
231
|
-
# trade execution
|
232
|
-
# [
|
233
|
-
# 0,
|
234
|
-
# "te", # or tu
|
235
|
-
# [
|
236
|
-
# 1133411090,
|
237
|
-
# "tLTCUST",
|
238
|
-
# 1655110144598,
|
239
|
-
# 97084883506,
|
240
|
-
# 0.1,
|
241
|
-
# 42.821,
|
242
|
-
# "EXCHANGE MARKET",
|
243
|
-
# 42.799,
|
244
|
-
# -1,
|
245
|
-
# null,
|
246
|
-
# null,
|
247
|
-
# 1655110144596
|
248
|
-
# ]
|
249
|
-
# ]
|
250
|
-
#
|
251
|
-
name = 'myTrade'
|
252
|
-
data = self.safe_value(message, 2)
|
253
|
-
trade = self.parse_ws_trade(data)
|
254
|
-
symbol = trade['symbol']
|
255
|
-
market = self.market(symbol)
|
256
|
-
messageHash = name + ':' + market['id']
|
257
|
-
if self.myTrades is None:
|
258
|
-
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
259
|
-
self.myTrades = ArrayCacheBySymbolById(limit)
|
260
|
-
tradesArray = self.myTrades
|
261
|
-
tradesArray.append(trade)
|
262
|
-
self.myTrades = tradesArray
|
263
|
-
# generic subscription
|
264
|
-
client.resolve(tradesArray, name)
|
265
|
-
# specific subscription
|
266
|
-
client.resolve(tradesArray, messageHash)
|
267
|
-
|
268
|
-
def handle_trades(self, client: Client, message, subscription):
|
269
|
-
#
|
270
|
-
# initial snapshot
|
271
|
-
#
|
272
|
-
# [
|
273
|
-
# 188687, # channel id
|
274
|
-
# [
|
275
|
-
# [1128060675, 1654701572690, 0.00217533, 1815.3], # id, mts, amount, price
|
276
|
-
# [1128060665, 1654701551231, -0.00280472, 1814.1],
|
277
|
-
# [1128060664, 1654701550996, -0.00364444, 1814.1],
|
278
|
-
# [1128060656, 1654701527730, -0.00265203, 1814.2],
|
279
|
-
# [1128060647, 1654701505193, 0.00262395, 1815.2],
|
280
|
-
# [1128060642, 1654701484656, -0.13411443, 1816],
|
281
|
-
# [1128060641, 1654701484656, -0.00088557, 1816],
|
282
|
-
# [1128060639, 1654701478326, -0.002, 1816],
|
283
|
-
# ]
|
284
|
-
# ]
|
285
|
-
# update
|
286
|
-
#
|
287
|
-
# [
|
288
|
-
# 360141,
|
289
|
-
# "te",
|
290
|
-
# [
|
291
|
-
# 1128060969, # id
|
292
|
-
# 1654702500098, # mts
|
293
|
-
# 0.00325131, # amount positive buy, negative sell
|
294
|
-
# 1818.5, # price
|
295
|
-
# ],
|
296
|
-
# ]
|
297
|
-
#
|
298
|
-
#
|
299
|
-
channel = self.safe_value(subscription, 'channel')
|
300
|
-
marketId = self.safe_string(subscription, 'symbol')
|
301
|
-
market = self.safe_market(marketId)
|
302
|
-
messageHash = channel + ':' + marketId
|
303
|
-
tradesLimit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
304
|
-
symbol = market['symbol']
|
305
|
-
stored = self.safe_value(self.trades, symbol)
|
306
|
-
if stored is None:
|
307
|
-
stored = ArrayCache(tradesLimit)
|
308
|
-
self.trades[symbol] = stored
|
309
|
-
messageLength = len(message)
|
310
|
-
if messageLength == 2:
|
311
|
-
# initial snapshot
|
312
|
-
trades = self.safe_list(message, 1, [])
|
313
|
-
# needs to be reversed to make chronological order
|
314
|
-
length = len(trades)
|
315
|
-
for i in range(0, length):
|
316
|
-
index = length - i - 1
|
317
|
-
parsed = self.parse_ws_trade(trades[index], market)
|
318
|
-
stored.append(parsed)
|
319
|
-
else:
|
320
|
-
# update
|
321
|
-
type = self.safe_string(message, 1)
|
322
|
-
if type == 'tu':
|
323
|
-
# don't resolve for a duplicate update
|
324
|
-
# since te and tu updates are duplicated on the public stream
|
325
|
-
return
|
326
|
-
trade = self.safe_value(message, 2, [])
|
327
|
-
parsed = self.parse_ws_trade(trade, market)
|
328
|
-
stored.append(parsed)
|
329
|
-
client.resolve(stored, messageHash)
|
330
|
-
|
331
|
-
def parse_ws_trade(self, trade, market=None):
|
332
|
-
#
|
333
|
-
# [
|
334
|
-
# 1128060969, # id
|
335
|
-
# 1654702500098, # mts
|
336
|
-
# 0.00325131, # amount positive buy, negative sell
|
337
|
-
# 1818.5, # price
|
338
|
-
# ]
|
339
|
-
#
|
340
|
-
# trade execution
|
341
|
-
#
|
342
|
-
# [
|
343
|
-
# 1133411090, # id
|
344
|
-
# "tLTCUST", # symbol
|
345
|
-
# 1655110144598, # create ms
|
346
|
-
# 97084883506, # order id
|
347
|
-
# 0.1, # amount
|
348
|
-
# 42.821, # price
|
349
|
-
# "EXCHANGE MARKET", # order type
|
350
|
-
# 42.799, # order price
|
351
|
-
# -1, # maker
|
352
|
-
# null, # fee
|
353
|
-
# null, # fee currency
|
354
|
-
# 1655110144596 # cid
|
355
|
-
# ]
|
356
|
-
#
|
357
|
-
# trade update
|
358
|
-
#
|
359
|
-
# [
|
360
|
-
# 1133411090,
|
361
|
-
# "tLTCUST",
|
362
|
-
# 1655110144598,
|
363
|
-
# 97084883506,
|
364
|
-
# 0.1,
|
365
|
-
# 42.821,
|
366
|
-
# "EXCHANGE MARKET",
|
367
|
-
# 42.799,
|
368
|
-
# -1,
|
369
|
-
# -0.0002,
|
370
|
-
# "LTC",
|
371
|
-
# 1655110144596
|
372
|
-
# ]
|
373
|
-
#
|
374
|
-
numFields = len(trade)
|
375
|
-
isPublic = numFields <= 8
|
376
|
-
marketId = self.safe_string(trade, 1) if (not isPublic) else None
|
377
|
-
market = self.safe_market(marketId, market)
|
378
|
-
createdKey = 1 if isPublic else 2
|
379
|
-
priceKey = 3 if isPublic else 5
|
380
|
-
amountKey = 2 if isPublic else 4
|
381
|
-
marketId = market['id']
|
382
|
-
type = self.safe_string(trade, 6)
|
383
|
-
if type is not None:
|
384
|
-
if type.find('LIMIT') > -1:
|
385
|
-
type = 'limit'
|
386
|
-
elif type.find('MARKET') > -1:
|
387
|
-
type = 'market'
|
388
|
-
orderId = self.safe_string(trade, 3) if (not isPublic) else None
|
389
|
-
id = self.safe_string(trade, 0)
|
390
|
-
timestamp = self.safe_integer(trade, createdKey)
|
391
|
-
price = self.safe_string(trade, priceKey)
|
392
|
-
amountString = self.safe_string(trade, amountKey)
|
393
|
-
amount = self.parse_number(Precise.string_abs(amountString))
|
394
|
-
side = None
|
395
|
-
if amount is not None:
|
396
|
-
side = 'buy' if Precise.string_gt(amountString, '0') else 'sell'
|
397
|
-
symbol = self.safe_symbol(marketId, market)
|
398
|
-
feeValue = self.safe_string(trade, 9)
|
399
|
-
fee = None
|
400
|
-
if feeValue is not None:
|
401
|
-
currencyId = self.safe_string(trade, 10)
|
402
|
-
code = self.safe_currency_code(currencyId)
|
403
|
-
fee = {
|
404
|
-
'cost': feeValue,
|
405
|
-
'currency': code,
|
406
|
-
}
|
407
|
-
maker = self.safe_integer(trade, 8)
|
408
|
-
takerOrMaker = None
|
409
|
-
if maker is not None:
|
410
|
-
takerOrMaker = 'taker' if (maker == -1) else 'maker'
|
411
|
-
return self.safe_trade({
|
412
|
-
'info': trade,
|
413
|
-
'timestamp': timestamp,
|
414
|
-
'datetime': self.iso8601(timestamp),
|
415
|
-
'symbol': symbol,
|
416
|
-
'id': id,
|
417
|
-
'order': orderId,
|
418
|
-
'type': type,
|
419
|
-
'takerOrMaker': takerOrMaker,
|
420
|
-
'side': side,
|
421
|
-
'price': price,
|
422
|
-
'amount': amount,
|
423
|
-
'cost': None,
|
424
|
-
'fee': fee,
|
425
|
-
}, market)
|
426
|
-
|
427
|
-
def handle_ticker(self, client: Client, message, subscription):
|
428
|
-
#
|
429
|
-
# [
|
430
|
-
# 340432, # channel ID
|
431
|
-
# [
|
432
|
-
# 236.62, # 1 BID float Price of last highest bid
|
433
|
-
# 9.0029, # 2 BID_SIZE float Size of the last highest bid
|
434
|
-
# 236.88, # 3 ASK float Price of last lowest ask
|
435
|
-
# 7.1138, # 4 ASK_SIZE float Size of the last lowest ask
|
436
|
-
# -1.02, # 5 DAILY_CHANGE float Amount that the last price has changed since yesterday
|
437
|
-
# 0, # 6 DAILY_CHANGE_PERC float Amount that the price has changed expressed in percentage terms
|
438
|
-
# 236.52, # 7 LAST_PRICE float Price of the last trade.
|
439
|
-
# 5191.36754297, # 8 VOLUME float Daily volume
|
440
|
-
# 250.01, # 9 HIGH float Daily high
|
441
|
-
# 220.05, # 10 LOW float Daily low
|
442
|
-
# ]
|
443
|
-
# ]
|
444
|
-
#
|
445
|
-
ticker = self.safe_value(message, 1)
|
446
|
-
marketId = self.safe_string(subscription, 'symbol')
|
447
|
-
market = self.safe_market(marketId)
|
448
|
-
symbol = self.safe_symbol(marketId)
|
449
|
-
parsed = self.parse_ws_ticker(ticker, market)
|
450
|
-
channel = 'ticker'
|
451
|
-
messageHash = channel + ':' + marketId
|
452
|
-
self.tickers[symbol] = parsed
|
453
|
-
client.resolve(parsed, messageHash)
|
454
|
-
|
455
|
-
def parse_ws_ticker(self, ticker, market=None):
|
456
|
-
#
|
457
|
-
# [
|
458
|
-
# 236.62, # 1 BID float Price of last highest bid
|
459
|
-
# 9.0029, # 2 BID_SIZE float Size of the last highest bid
|
460
|
-
# 236.88, # 3 ASK float Price of last lowest ask
|
461
|
-
# 7.1138, # 4 ASK_SIZE float Size of the last lowest ask
|
462
|
-
# -1.02, # 5 DAILY_CHANGE float Amount that the last price has changed since yesterday
|
463
|
-
# 0, # 6 DAILY_CHANGE_PERC float Amount that the price has changed expressed in percentage terms
|
464
|
-
# 236.52, # 7 LAST_PRICE float Price of the last trade.
|
465
|
-
# 5191.36754297, # 8 VOLUME float Daily volume
|
466
|
-
# 250.01, # 9 HIGH float Daily high
|
467
|
-
# 220.05, # 10 LOW float Daily low
|
468
|
-
# ]
|
469
|
-
#
|
470
|
-
market = self.safe_market(None, market)
|
471
|
-
symbol = market['symbol']
|
472
|
-
last = self.safe_string(ticker, 6)
|
473
|
-
change = self.safe_string(ticker, 4)
|
474
|
-
return self.safe_ticker({
|
475
|
-
'symbol': symbol,
|
476
|
-
'timestamp': None,
|
477
|
-
'datetime': None,
|
478
|
-
'high': self.safe_string(ticker, 8),
|
479
|
-
'low': self.safe_string(ticker, 9),
|
480
|
-
'bid': self.safe_string(ticker, 0),
|
481
|
-
'bidVolume': self.safe_string(ticker, 1),
|
482
|
-
'ask': self.safe_string(ticker, 2),
|
483
|
-
'askVolume': self.safe_string(ticker, 3),
|
484
|
-
'vwap': None,
|
485
|
-
'open': None,
|
486
|
-
'close': last,
|
487
|
-
'last': last,
|
488
|
-
'previousClose': None,
|
489
|
-
'change': change,
|
490
|
-
'percentage': self.safe_string(ticker, 5),
|
491
|
-
'average': None,
|
492
|
-
'baseVolume': self.safe_string(ticker, 7),
|
493
|
-
'quoteVolume': None,
|
494
|
-
'info': ticker,
|
495
|
-
}, market)
|
496
|
-
|
497
|
-
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
498
|
-
"""
|
499
|
-
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
500
|
-
:param str symbol: unified symbol of the market to fetch the order book for
|
501
|
-
:param int [limit]: the maximum amount of order book entries to return
|
502
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
503
|
-
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
504
|
-
"""
|
505
|
-
if limit is not None:
|
506
|
-
if (limit != 25) and (limit != 100):
|
507
|
-
raise ExchangeError(self.id + ' watchOrderBook limit argument must be None, 25 or 100')
|
508
|
-
options = self.safe_value(self.options, 'watchOrderBook', {})
|
509
|
-
prec = self.safe_string(options, 'prec', 'P0')
|
510
|
-
freq = self.safe_string(options, 'freq', 'F0')
|
511
|
-
request = {
|
512
|
-
'prec': prec, # string, level of price aggregation, 'P0', 'P1', 'P2', 'P3', 'P4', default P0
|
513
|
-
'freq': freq, # string, frequency of updates 'F0' = realtime, 'F1' = 2 seconds, default is 'F0'
|
514
|
-
}
|
515
|
-
if limit is not None:
|
516
|
-
request['len'] = limit # string, number of price points, '25', '100', default = '25'
|
517
|
-
orderbook = await self.subscribe('book', symbol, self.deep_extend(request, params))
|
518
|
-
return orderbook.limit()
|
519
|
-
|
520
|
-
def handle_order_book(self, client: Client, message, subscription):
|
521
|
-
#
|
522
|
-
# first message(snapshot)
|
523
|
-
#
|
524
|
-
# [
|
525
|
-
# 18691, # channel id
|
526
|
-
# [
|
527
|
-
# [7364.8, 10, 4.354802], # price, count, size > 0 = bid
|
528
|
-
# [7364.7, 1, 0.00288831],
|
529
|
-
# [7364.3, 12, 0.048],
|
530
|
-
# [7364.9, 3, -0.42028976], # price, count, size < 0 = ask
|
531
|
-
# [7365, 1, -0.25],
|
532
|
-
# [7365.5, 1, -0.00371937],
|
533
|
-
# ]
|
534
|
-
# ]
|
535
|
-
#
|
536
|
-
# subsequent updates
|
537
|
-
#
|
538
|
-
# [
|
539
|
-
# 358169, # channel id
|
540
|
-
# [
|
541
|
-
# 1807.1, # price
|
542
|
-
# 0, # cound
|
543
|
-
# 1 # size
|
544
|
-
# ]
|
545
|
-
# ]
|
546
|
-
#
|
547
|
-
marketId = self.safe_string(subscription, 'symbol')
|
548
|
-
symbol = self.safe_symbol(marketId)
|
549
|
-
channel = 'book'
|
550
|
-
messageHash = channel + ':' + marketId
|
551
|
-
prec = self.safe_string(subscription, 'prec', 'P0')
|
552
|
-
isRaw = (prec == 'R0')
|
553
|
-
# if it is an initial snapshot
|
554
|
-
orderbook = self.safe_value(self.orderbooks, symbol)
|
555
|
-
if orderbook is None:
|
556
|
-
limit = self.safe_integer(subscription, 'len')
|
557
|
-
if isRaw:
|
558
|
-
# raw order books
|
559
|
-
self.orderbooks[symbol] = self.indexed_order_book({}, limit)
|
560
|
-
else:
|
561
|
-
# P0, P1, P2, P3, P4
|
562
|
-
self.orderbooks[symbol] = self.counted_order_book({}, limit)
|
563
|
-
orderbook = self.orderbooks[symbol]
|
564
|
-
if isRaw:
|
565
|
-
deltas = message[1]
|
566
|
-
for i in range(0, len(deltas)):
|
567
|
-
delta = deltas[i]
|
568
|
-
delta2 = delta[2]
|
569
|
-
size = -delta2 if (delta2 < 0) else delta2
|
570
|
-
side = 'asks' if (delta2 < 0) else 'bids'
|
571
|
-
bookside = orderbook[side]
|
572
|
-
idString = self.safe_string(delta, 0)
|
573
|
-
price = self.safe_float(delta, 1)
|
574
|
-
bookside.store(price, size, idString)
|
575
|
-
else:
|
576
|
-
deltas = message[1]
|
577
|
-
for i in range(0, len(deltas)):
|
578
|
-
delta = deltas[i]
|
579
|
-
amount = self.safe_number(delta, 2)
|
580
|
-
counter = self.safe_number(delta, 1)
|
581
|
-
price = self.safe_number(delta, 0)
|
582
|
-
size = -amount if (amount < 0) else amount
|
583
|
-
side = 'asks' if (amount < 0) else 'bids'
|
584
|
-
bookside = orderbook[side]
|
585
|
-
bookside.store(price, size, counter)
|
586
|
-
orderbook['symbol'] = symbol
|
587
|
-
client.resolve(orderbook, messageHash)
|
588
|
-
else:
|
589
|
-
deltas = message[1]
|
590
|
-
orderbookItem = self.orderbooks[symbol]
|
591
|
-
if isRaw:
|
592
|
-
price = self.safe_string(deltas, 1)
|
593
|
-
deltas2 = deltas[2]
|
594
|
-
size = -deltas2 if (deltas2 < 0) else deltas2
|
595
|
-
side = 'asks' if (deltas2 < 0) else 'bids'
|
596
|
-
bookside = orderbookItem[side]
|
597
|
-
# price = 0 means that you have to remove the order from your book
|
598
|
-
amount = size if Precise.string_gt(price, '0') else '0'
|
599
|
-
idString = self.safe_string(deltas, 0)
|
600
|
-
bookside.store(self.parse_number(price), self.parse_number(amount), idString)
|
601
|
-
else:
|
602
|
-
amount = self.safe_string(deltas, 2)
|
603
|
-
counter = self.safe_string(deltas, 1)
|
604
|
-
price = self.safe_string(deltas, 0)
|
605
|
-
size = Precise.string_neg(amount) if Precise.string_lt(amount, '0') else amount
|
606
|
-
side = 'asks' if Precise.string_lt(amount, '0') else 'bids'
|
607
|
-
bookside = orderbookItem[side]
|
608
|
-
bookside.store(self.parse_number(price), self.parse_number(size), self.parse_number(counter))
|
609
|
-
client.resolve(orderbook, messageHash)
|
610
|
-
|
611
|
-
def handle_checksum(self, client: Client, message, subscription):
|
612
|
-
#
|
613
|
-
# [173904, "cs", -890884919]
|
614
|
-
#
|
615
|
-
marketId = self.safe_string(subscription, 'symbol')
|
616
|
-
symbol = self.safe_symbol(marketId)
|
617
|
-
channel = 'book'
|
618
|
-
messageHash = channel + ':' + marketId
|
619
|
-
book = self.safe_value(self.orderbooks, symbol)
|
620
|
-
if book is None:
|
621
|
-
return
|
622
|
-
depth = 25 # covers the first 25 bids and asks
|
623
|
-
stringArray = []
|
624
|
-
bids = book['bids']
|
625
|
-
asks = book['asks']
|
626
|
-
prec = self.safe_string(subscription, 'prec', 'P0')
|
627
|
-
isRaw = (prec == 'R0')
|
628
|
-
idToCheck = 2 if isRaw else 0
|
629
|
-
# pepperoni pizza from bitfinex
|
630
|
-
for i in range(0, depth):
|
631
|
-
bid = self.safe_value(bids, i)
|
632
|
-
ask = self.safe_value(asks, i)
|
633
|
-
if bid is not None:
|
634
|
-
stringArray.append(self.number_to_string(bids[i][idToCheck]))
|
635
|
-
stringArray.append(self.number_to_string(bids[i][1]))
|
636
|
-
if ask is not None:
|
637
|
-
stringArray.append(self.number_to_string(asks[i][idToCheck]))
|
638
|
-
aski1 = asks[i][1]
|
639
|
-
stringArray.append(self.number_to_string(-aski1))
|
640
|
-
payload = ':'.join(stringArray)
|
641
|
-
localChecksum = self.crc32(payload, True)
|
642
|
-
responseChecksum = self.safe_integer(message, 2)
|
643
|
-
if responseChecksum != localChecksum:
|
644
|
-
error = InvalidNonce(self.id + ' invalid checksum')
|
645
|
-
client.reject(error, messageHash)
|
646
|
-
|
647
|
-
async def watch_balance(self, params={}) -> Balances:
|
648
|
-
"""
|
649
|
-
watch balance and get the amount of funds available for trading or funds locked in orders
|
650
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
651
|
-
:param str [params.type]: spot or contract if not provided self.options['defaultType'] is used
|
652
|
-
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
653
|
-
"""
|
654
|
-
await self.load_markets()
|
655
|
-
balanceType = self.safe_string(params, 'wallet', 'exchange') # exchange, margin
|
656
|
-
params = self.omit(params, 'wallet')
|
657
|
-
messageHash = 'balance:' + balanceType
|
658
|
-
return await self.subscribe_private(messageHash)
|
659
|
-
|
660
|
-
def handle_balance(self, client: Client, message, subscription):
|
661
|
-
#
|
662
|
-
# snapshot(exchange + margin together)
|
663
|
-
# [
|
664
|
-
# 0,
|
665
|
-
# "ws",
|
666
|
-
# [
|
667
|
-
# [
|
668
|
-
# "exchange",
|
669
|
-
# "LTC",
|
670
|
-
# 0.05479727,
|
671
|
-
# 0,
|
672
|
-
# null,
|
673
|
-
# "Trading fees for 0.05 LTC(LTCUST) @ 51.872 on BFX(0.2%)",
|
674
|
-
# null,
|
675
|
-
# ]
|
676
|
-
# [
|
677
|
-
# "margin",
|
678
|
-
# "USTF0",
|
679
|
-
# 11.960650700086292,
|
680
|
-
# 0,
|
681
|
-
# null,
|
682
|
-
# "Trading fees for 0.1 LTCF0(LTCF0:USTF0) @ 51.844 on BFX(0.065%)",
|
683
|
-
# null,
|
684
|
-
# ],
|
685
|
-
# ],
|
686
|
-
# ]
|
687
|
-
#
|
688
|
-
# spot
|
689
|
-
# [
|
690
|
-
# 0,
|
691
|
-
# "wu",
|
692
|
-
# [
|
693
|
-
# "exchange",
|
694
|
-
# "LTC", # currency
|
695
|
-
# 0.06729727, # wallet balance
|
696
|
-
# 0, # unsettled balance
|
697
|
-
# 0.06729727, # available balance might be null
|
698
|
-
# "Exchange 0.4 LTC for UST @ 65.075",
|
699
|
-
# {
|
700
|
-
# "reason": "TRADE",
|
701
|
-
# "order_id": 96596397973,
|
702
|
-
# "order_id_oppo": 96596632735,
|
703
|
-
# "trade_price": "65.075",
|
704
|
-
# "trade_amount": "-0.4",
|
705
|
-
# "order_cid": 1654636218766,
|
706
|
-
# "order_gid": null
|
707
|
-
# }
|
708
|
-
# ]
|
709
|
-
# ]
|
710
|
-
#
|
711
|
-
# margin
|
712
|
-
#
|
713
|
-
# [
|
714
|
-
# "margin",
|
715
|
-
# "USTF0",
|
716
|
-
# 11.960650700086292, # total
|
717
|
-
# 0,
|
718
|
-
# 6.776250700086292, # available
|
719
|
-
# "Trading fees for 0.1 LTCF0(LTCF0:USTF0) @ 51.844 on BFX(0.065%)",
|
720
|
-
# null
|
721
|
-
# ]
|
722
|
-
#
|
723
|
-
updateType = self.safe_value(message, 1)
|
724
|
-
data = None
|
725
|
-
if updateType == 'ws':
|
726
|
-
data = self.safe_value(message, 2)
|
727
|
-
else:
|
728
|
-
data = [self.safe_value(message, 2)]
|
729
|
-
updatedTypes = {}
|
730
|
-
for i in range(0, len(data)):
|
731
|
-
rawBalance = data[i]
|
732
|
-
currencyId = self.safe_string(rawBalance, 1)
|
733
|
-
code = self.safe_currency_code(currencyId)
|
734
|
-
balance = self.parse_ws_balance(rawBalance)
|
735
|
-
balanceType = self.safe_string(rawBalance, 0)
|
736
|
-
oldBalance = self.safe_value(self.balance, balanceType, {})
|
737
|
-
oldBalance[code] = balance
|
738
|
-
oldBalance['info'] = message
|
739
|
-
self.balance[balanceType] = self.safe_balance(oldBalance)
|
740
|
-
updatedTypes[balanceType] = True
|
741
|
-
updatesKeys = list(updatedTypes.keys())
|
742
|
-
for i in range(0, len(updatesKeys)):
|
743
|
-
type = updatesKeys[i]
|
744
|
-
messageHash = 'balance:' + type
|
745
|
-
client.resolve(self.balance[type], messageHash)
|
746
|
-
|
747
|
-
def parse_ws_balance(self, balance):
|
748
|
-
#
|
749
|
-
# [
|
750
|
-
# "exchange",
|
751
|
-
# "LTC",
|
752
|
-
# 0.05479727, # balance
|
753
|
-
# 0,
|
754
|
-
# null, # available null if not calculated yet
|
755
|
-
# "Trading fees for 0.05 LTC(LTCUST) @ 51.872 on BFX(0.2%)",
|
756
|
-
# null,
|
757
|
-
# ]
|
758
|
-
#
|
759
|
-
totalBalance = self.safe_string(balance, 2)
|
760
|
-
availableBalance = self.safe_string(balance, 4)
|
761
|
-
account = self.account()
|
762
|
-
if availableBalance is not None:
|
763
|
-
account['free'] = availableBalance
|
764
|
-
account['total'] = totalBalance
|
765
|
-
return account
|
766
|
-
|
767
|
-
def handle_system_status(self, client: Client, message):
|
768
|
-
#
|
769
|
-
# {
|
770
|
-
# "event": "info",
|
771
|
-
# "version": 2,
|
772
|
-
# "serverId": "e293377e-7bb7-427e-b28c-5db045b2c1d1",
|
773
|
-
# "platform": {status: 1}, # 1 for operative, 0 for maintenance
|
774
|
-
# }
|
775
|
-
#
|
776
|
-
return message
|
777
|
-
|
778
|
-
def handle_subscription_status(self, client: Client, message):
|
779
|
-
#
|
780
|
-
# {
|
781
|
-
# "event": "subscribed",
|
782
|
-
# "channel": "book",
|
783
|
-
# "chanId": 67473,
|
784
|
-
# "symbol": "tBTCUSD",
|
785
|
-
# "prec": "P0",
|
786
|
-
# "freq": "F0",
|
787
|
-
# "len": "25",
|
788
|
-
# "pair": "BTCUSD"
|
789
|
-
# }
|
790
|
-
#
|
791
|
-
channelId = self.safe_string(message, 'chanId')
|
792
|
-
client.subscriptions[channelId] = message
|
793
|
-
return message
|
794
|
-
|
795
|
-
async def authenticate(self, params={}):
|
796
|
-
url = self.urls['api']['ws']['private']
|
797
|
-
client = self.client(url)
|
798
|
-
messageHash = 'authenticated'
|
799
|
-
future = client.future(messageHash)
|
800
|
-
authenticated = self.safe_value(client.subscriptions, messageHash)
|
801
|
-
if authenticated is None:
|
802
|
-
nonce = self.milliseconds()
|
803
|
-
payload = 'AUTH' + str(nonce)
|
804
|
-
signature = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha384, 'hex')
|
805
|
-
event = 'auth'
|
806
|
-
request = {
|
807
|
-
'apiKey': self.apiKey,
|
808
|
-
'authSig': signature,
|
809
|
-
'authNonce': nonce,
|
810
|
-
'authPayload': payload,
|
811
|
-
'event': event,
|
812
|
-
}
|
813
|
-
message = self.extend(request, params)
|
814
|
-
self.watch(url, messageHash, message, messageHash)
|
815
|
-
return future
|
816
|
-
|
817
|
-
def handle_authentication_message(self, client: Client, message):
|
818
|
-
messageHash = 'authenticated'
|
819
|
-
status = self.safe_string(message, 'status')
|
820
|
-
if status == 'OK':
|
821
|
-
# we resolve the future here permanently so authentication only happens once
|
822
|
-
future = self.safe_value(client.futures, messageHash)
|
823
|
-
future.resolve(True)
|
824
|
-
else:
|
825
|
-
error = AuthenticationError(self.json(message))
|
826
|
-
client.reject(error, messageHash)
|
827
|
-
# allows further authentication attempts
|
828
|
-
if messageHash in client.subscriptions:
|
829
|
-
del client.subscriptions[messageHash]
|
830
|
-
|
831
|
-
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
832
|
-
"""
|
833
|
-
watches information on multiple orders made by the user
|
834
|
-
:param str symbol: unified market symbol of the market orders were made in
|
835
|
-
:param int [since]: the earliest time in ms to fetch orders for
|
836
|
-
:param int [limit]: the maximum number of order structures to retrieve
|
837
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
838
|
-
:returns dict[]: a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
|
839
|
-
"""
|
840
|
-
await self.load_markets()
|
841
|
-
messageHash = 'orders'
|
842
|
-
if symbol is not None:
|
843
|
-
market = self.market(symbol)
|
844
|
-
messageHash += ':' + market['id']
|
845
|
-
orders = await self.subscribe_private(messageHash)
|
846
|
-
if self.newUpdates:
|
847
|
-
limit = orders.getLimit(symbol, limit)
|
848
|
-
return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
|
849
|
-
|
850
|
-
def handle_orders(self, client: Client, message, subscription):
|
851
|
-
#
|
852
|
-
# limit order
|
853
|
-
# [
|
854
|
-
# 0,
|
855
|
-
# "on", # ou or oc
|
856
|
-
# [
|
857
|
-
# 96923856256, # order id
|
858
|
-
# null, # gid
|
859
|
-
# 1655029337026, # cid
|
860
|
-
# "tLTCUST", # symbol
|
861
|
-
# 1655029337027, # created timestamp
|
862
|
-
# 1655029337029, # updated timestamp
|
863
|
-
# 0.1, # amount
|
864
|
-
# 0.1, # amount_orig
|
865
|
-
# "EXCHANGE LIMIT", # order type
|
866
|
-
# null, # type_prev
|
867
|
-
# null, # mts_tif
|
868
|
-
# null, # placeholder
|
869
|
-
# 0, # flags
|
870
|
-
# "ACTIVE", # status
|
871
|
-
# null,
|
872
|
-
# null,
|
873
|
-
# 30, # price
|
874
|
-
# 0, # price average
|
875
|
-
# 0, # price_trailling
|
876
|
-
# 0, # price_aux_limit
|
877
|
-
# null,
|
878
|
-
# null,
|
879
|
-
# null,
|
880
|
-
# 0, # notify
|
881
|
-
# 0,
|
882
|
-
# null,
|
883
|
-
# null,
|
884
|
-
# null,
|
885
|
-
# "BFX",
|
886
|
-
# null,
|
887
|
-
# null,
|
888
|
-
# ]
|
889
|
-
# ]
|
890
|
-
#
|
891
|
-
data = self.safe_value(message, 2, [])
|
892
|
-
messageType = self.safe_string(message, 1)
|
893
|
-
if self.orders is None:
|
894
|
-
limit = self.safe_integer(self.options, 'ordersLimit', 1000)
|
895
|
-
self.orders = ArrayCacheBySymbolById(limit)
|
896
|
-
orders = self.orders
|
897
|
-
symbolIds = {}
|
898
|
-
if messageType == 'os':
|
899
|
-
snapshotLength = len(data)
|
900
|
-
if snapshotLength == 0:
|
901
|
-
return
|
902
|
-
for i in range(0, len(data)):
|
903
|
-
value = data[i]
|
904
|
-
parsed = self.parse_ws_order(value)
|
905
|
-
symbol = parsed['symbol']
|
906
|
-
symbolIds[symbol] = True
|
907
|
-
orders.append(parsed)
|
908
|
-
else:
|
909
|
-
parsed = self.parse_ws_order(data)
|
910
|
-
orders.append(parsed)
|
911
|
-
symbol = parsed['symbol']
|
912
|
-
symbolIds[symbol] = True
|
913
|
-
name = 'orders'
|
914
|
-
client.resolve(self.orders, name)
|
915
|
-
keys = list(symbolIds.keys())
|
916
|
-
for i in range(0, len(keys)):
|
917
|
-
symbol = keys[i]
|
918
|
-
market = self.market(symbol)
|
919
|
-
messageHash = name + ':' + market['id']
|
920
|
-
client.resolve(self.orders, messageHash)
|
921
|
-
|
922
|
-
def parse_ws_order_status(self, status):
|
923
|
-
statuses = {
|
924
|
-
'ACTIVE': 'open',
|
925
|
-
'CANCELED': 'canceled',
|
926
|
-
'EXECUTED': 'closed',
|
927
|
-
'PARTIALLY': 'open',
|
928
|
-
}
|
929
|
-
return self.safe_string(statuses, status, status)
|
930
|
-
|
931
|
-
def parse_ws_order(self, order, market=None):
|
932
|
-
#
|
933
|
-
# [
|
934
|
-
# 97084883506, # order id
|
935
|
-
# null,
|
936
|
-
# 1655110144596, # clientOrderId
|
937
|
-
# "tLTCUST", # symbol
|
938
|
-
# 1655110144596, # created timestamp
|
939
|
-
# 1655110144598, # updated timestamp
|
940
|
-
# 0, # amount
|
941
|
-
# 0.1, # amount_orig negative if sell order
|
942
|
-
# "EXCHANGE MARKET", # type
|
943
|
-
# null,
|
944
|
-
# null,
|
945
|
-
# null,
|
946
|
-
# 0,
|
947
|
-
# "EXECUTED @ 42.821(0.1)", # status
|
948
|
-
# null,
|
949
|
-
# null,
|
950
|
-
# 42.799, # price
|
951
|
-
# 42.821, # price average
|
952
|
-
# 0, # price trailling
|
953
|
-
# 0, # price_aux_limit
|
954
|
-
# null,
|
955
|
-
# null,
|
956
|
-
# null,
|
957
|
-
# 0,
|
958
|
-
# 0,
|
959
|
-
# null,
|
960
|
-
# null,
|
961
|
-
# null,
|
962
|
-
# "BFX",
|
963
|
-
# null,
|
964
|
-
# null,
|
965
|
-
# {}
|
966
|
-
# ]
|
967
|
-
#
|
968
|
-
id = self.safe_string(order, 0)
|
969
|
-
clientOrderId = self.safe_string(order, 1)
|
970
|
-
marketId = self.safe_string(order, 3)
|
971
|
-
symbol = self.safe_symbol(marketId)
|
972
|
-
market = self.safe_market(symbol)
|
973
|
-
amount = self.safe_string(order, 7)
|
974
|
-
side = 'buy'
|
975
|
-
if Precise.string_lt(amount, '0'):
|
976
|
-
amount = Precise.string_abs(amount)
|
977
|
-
side = 'sell'
|
978
|
-
remaining = Precise.string_abs(self.safe_string(order, 6))
|
979
|
-
type = self.safe_string(order, 8)
|
980
|
-
if type.find('LIMIT') > -1:
|
981
|
-
type = 'limit'
|
982
|
-
elif type.find('MARKET') > -1:
|
983
|
-
type = 'market'
|
984
|
-
rawState = self.safe_string(order, 13)
|
985
|
-
stateParts = rawState.split(' ')
|
986
|
-
trimmedStatus = self.safe_string(stateParts, 0)
|
987
|
-
status = self.parse_ws_order_status(trimmedStatus)
|
988
|
-
price = self.safe_string(order, 16)
|
989
|
-
timestamp = self.safe_integer_2(order, 5, 4)
|
990
|
-
average = self.safe_string(order, 17)
|
991
|
-
stopPrice = self.omit_zero(self.safe_string(order, 18))
|
992
|
-
return self.safe_order({
|
993
|
-
'info': order,
|
994
|
-
'id': id,
|
995
|
-
'clientOrderId': clientOrderId,
|
996
|
-
'timestamp': timestamp,
|
997
|
-
'datetime': self.iso8601(timestamp),
|
998
|
-
'lastTradeTimestamp': None,
|
999
|
-
'symbol': symbol,
|
1000
|
-
'type': type,
|
1001
|
-
'side': side,
|
1002
|
-
'price': price,
|
1003
|
-
'stopPrice': stopPrice,
|
1004
|
-
'triggerPrice': stopPrice,
|
1005
|
-
'average': average,
|
1006
|
-
'amount': amount,
|
1007
|
-
'remaining': remaining,
|
1008
|
-
'filled': None,
|
1009
|
-
'status': status,
|
1010
|
-
'fee': None,
|
1011
|
-
'cost': None,
|
1012
|
-
'trades': None,
|
1013
|
-
}, market)
|
1014
|
-
|
1015
|
-
def handle_message(self, client: Client, message):
|
1016
|
-
channelId = self.safe_string(message, 0)
|
1017
|
-
#
|
1018
|
-
# [
|
1019
|
-
# 1231,
|
1020
|
-
# "hb",
|
1021
|
-
# ]
|
1022
|
-
#
|
1023
|
-
# auth message
|
1024
|
-
# {
|
1025
|
-
# "event": "auth",
|
1026
|
-
# "status": "OK",
|
1027
|
-
# "chanId": 0,
|
1028
|
-
# "userId": 3159883,
|
1029
|
-
# "auth_id": "ac7108e7-2f26-424d-9982-c24700dc02ca",
|
1030
|
-
# "caps": {
|
1031
|
-
# "orders": {read: 1, write: 1},
|
1032
|
-
# "account": {read: 1, write: 1},
|
1033
|
-
# "funding": {read: 1, write: 1},
|
1034
|
-
# "history": {read: 1, write: 0},
|
1035
|
-
# "wallets": {read: 1, write: 1},
|
1036
|
-
# "withdraw": {read: 0, write: 1},
|
1037
|
-
# "positions": {read: 1, write: 1},
|
1038
|
-
# "ui_withdraw": {read: 0, write: 0}
|
1039
|
-
# }
|
1040
|
-
# }
|
1041
|
-
#
|
1042
|
-
if isinstance(message, list):
|
1043
|
-
if message[1] == 'hb':
|
1044
|
-
return # skip heartbeats within subscription channels for now
|
1045
|
-
subscription = self.safe_value(client.subscriptions, channelId, {})
|
1046
|
-
channel = self.safe_string(subscription, 'channel')
|
1047
|
-
name = self.safe_string(message, 1)
|
1048
|
-
publicMethods = {
|
1049
|
-
'book': self.handle_order_book,
|
1050
|
-
'cs': self.handle_checksum,
|
1051
|
-
'candles': self.handle_ohlcv,
|
1052
|
-
'ticker': self.handle_ticker,
|
1053
|
-
'trades': self.handle_trades,
|
1054
|
-
}
|
1055
|
-
privateMethods = {
|
1056
|
-
'os': self.handle_orders,
|
1057
|
-
'ou': self.handle_orders,
|
1058
|
-
'on': self.handle_orders,
|
1059
|
-
'oc': self.handle_orders,
|
1060
|
-
'wu': self.handle_balance,
|
1061
|
-
'ws': self.handle_balance,
|
1062
|
-
'tu': self.handle_my_trade,
|
1063
|
-
}
|
1064
|
-
method = None
|
1065
|
-
if channelId == '0':
|
1066
|
-
method = self.safe_value(privateMethods, name)
|
1067
|
-
else:
|
1068
|
-
method = self.safe_value_2(publicMethods, name, channel)
|
1069
|
-
if method is not None:
|
1070
|
-
method(client, message, subscription)
|
1071
|
-
else:
|
1072
|
-
event = self.safe_string(message, 'event')
|
1073
|
-
if event is not None:
|
1074
|
-
methods = {
|
1075
|
-
'info': self.handle_system_status,
|
1076
|
-
'subscribed': self.handle_subscription_status,
|
1077
|
-
'auth': self.handle_authentication_message,
|
1078
|
-
}
|
1079
|
-
method = self.safe_value(methods, event)
|
1080
|
-
if method is not None:
|
1081
|
-
method(client, message)
|