crypto-com-sdk 0.0.13__py3-none-any.whl → 0.0.15__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.
- {crypto_com_sdk-0.0.13.dist-info → crypto_com_sdk-0.0.15.dist-info}/METADATA +1 -1
- crypto_com_sdk-0.0.15.dist-info/RECORD +288 -0
- cryptocom/__init__.py +7 -0
- cryptocom/ccxt/__init__.py +101 -0
- cryptocom/ccxt/abstract/cryptocom.py +121 -0
- cryptocom/ccxt/async_support/__init__.py +80 -0
- cryptocom/ccxt/async_support/base/__init__.py +1 -0
- cryptocom/ccxt/async_support/base/exchange.py +2100 -0
- cryptocom/ccxt/async_support/base/throttler.py +50 -0
- cryptocom/ccxt/async_support/base/ws/__init__.py +38 -0
- cryptocom/ccxt/async_support/base/ws/aiohttp_client.py +147 -0
- cryptocom/ccxt/async_support/base/ws/cache.py +213 -0
- cryptocom/ccxt/async_support/base/ws/client.py +214 -0
- cryptocom/ccxt/async_support/base/ws/fast_client.py +97 -0
- cryptocom/ccxt/async_support/base/ws/functions.py +59 -0
- cryptocom/ccxt/async_support/base/ws/future.py +69 -0
- cryptocom/ccxt/async_support/base/ws/order_book.py +78 -0
- cryptocom/ccxt/async_support/base/ws/order_book_side.py +174 -0
- cryptocom/ccxt/async_support/cryptocom.py +3125 -0
- cryptocom/ccxt/base/__init__.py +27 -0
- cryptocom/ccxt/base/decimal_to_precision.py +174 -0
- cryptocom/ccxt/base/errors.py +267 -0
- cryptocom/ccxt/base/exchange.py +6769 -0
- cryptocom/ccxt/base/precise.py +297 -0
- cryptocom/ccxt/base/types.py +577 -0
- cryptocom/ccxt/cryptocom.py +3125 -0
- cryptocom/ccxt/pro/__init__.py +21 -0
- cryptocom/ccxt/pro/cryptocom.py +1326 -0
- cryptocom/ccxt/static_dependencies/README.md +1 -0
- cryptocom/ccxt/static_dependencies/__init__.py +1 -0
- cryptocom/ccxt/static_dependencies/ecdsa/__init__.py +14 -0
- cryptocom/ccxt/static_dependencies/ecdsa/_version.py +520 -0
- cryptocom/ccxt/static_dependencies/ecdsa/curves.py +56 -0
- cryptocom/ccxt/static_dependencies/ecdsa/der.py +221 -0
- cryptocom/ccxt/static_dependencies/ecdsa/ecdsa.py +310 -0
- cryptocom/ccxt/static_dependencies/ecdsa/ellipticcurve.py +197 -0
- cryptocom/ccxt/static_dependencies/ecdsa/keys.py +332 -0
- cryptocom/ccxt/static_dependencies/ecdsa/numbertheory.py +531 -0
- cryptocom/ccxt/static_dependencies/ecdsa/rfc6979.py +100 -0
- cryptocom/ccxt/static_dependencies/ecdsa/util.py +266 -0
- cryptocom/ccxt/static_dependencies/ethereum/__init__.py +7 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/__init__.py +16 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/abi.py +19 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/base.py +152 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/codec.py +217 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/constants.py +3 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/decoding.py +565 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/encoding.py +720 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/exceptions.py +139 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/grammar.py +443 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/packed.py +13 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/registry.py +643 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/tools/__init__.py +3 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +230 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/utils/numeric.py +83 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/utils/padding.py +27 -0
- cryptocom/ccxt/static_dependencies/ethereum/abi/utils/string.py +19 -0
- cryptocom/ccxt/static_dependencies/ethereum/account/__init__.py +3 -0
- cryptocom/ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +4 -0
- cryptocom/ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +239 -0
- cryptocom/ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +40 -0
- cryptocom/ccxt/static_dependencies/ethereum/account/messages.py +263 -0
- cryptocom/ccxt/static_dependencies/ethereum/account/py.typed +0 -0
- cryptocom/ccxt/static_dependencies/ethereum/hexbytes/__init__.py +5 -0
- cryptocom/ccxt/static_dependencies/ethereum/hexbytes/_utils.py +54 -0
- cryptocom/ccxt/static_dependencies/ethereum/hexbytes/main.py +65 -0
- cryptocom/ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
- cryptocom/ccxt/static_dependencies/ethereum/typing/__init__.py +63 -0
- cryptocom/ccxt/static_dependencies/ethereum/typing/abi.py +6 -0
- cryptocom/ccxt/static_dependencies/ethereum/typing/bls.py +7 -0
- cryptocom/ccxt/static_dependencies/ethereum/typing/discovery.py +5 -0
- cryptocom/ccxt/static_dependencies/ethereum/typing/encoding.py +7 -0
- cryptocom/ccxt/static_dependencies/ethereum/typing/enums.py +17 -0
- cryptocom/ccxt/static_dependencies/ethereum/typing/ethpm.py +9 -0
- cryptocom/ccxt/static_dependencies/ethereum/typing/evm.py +20 -0
- cryptocom/ccxt/static_dependencies/ethereum/typing/networks.py +1122 -0
- cryptocom/ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/__init__.py +115 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/abi.py +72 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/address.py +171 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/applicators.py +151 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/conversions.py +190 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/currency.py +107 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/curried/__init__.py +269 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/debug.py +20 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/decorators.py +132 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/encoding.py +6 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/exceptions.py +4 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/functional.py +75 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/hexadecimal.py +74 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/humanize.py +188 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/logging.py +159 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/module_loading.py +31 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/numeric.py +43 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/toolz.py +76 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/types.py +54 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/typing/__init__.py +18 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/typing/misc.py +14 -0
- cryptocom/ccxt/static_dependencies/ethereum/utils/units.py +31 -0
- cryptocom/ccxt/static_dependencies/keccak/__init__.py +3 -0
- cryptocom/ccxt/static_dependencies/keccak/keccak.py +197 -0
- cryptocom/ccxt/static_dependencies/lark/__init__.py +38 -0
- cryptocom/ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
- cryptocom/ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
- cryptocom/ccxt/static_dependencies/lark/ast_utils.py +59 -0
- cryptocom/ccxt/static_dependencies/lark/common.py +86 -0
- cryptocom/ccxt/static_dependencies/lark/exceptions.py +292 -0
- cryptocom/ccxt/static_dependencies/lark/grammar.py +130 -0
- cryptocom/ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/lark/grammars/common.lark +59 -0
- cryptocom/ccxt/static_dependencies/lark/grammars/lark.lark +62 -0
- cryptocom/ccxt/static_dependencies/lark/grammars/python.lark +302 -0
- cryptocom/ccxt/static_dependencies/lark/grammars/unicode.lark +7 -0
- cryptocom/ccxt/static_dependencies/lark/indenter.py +143 -0
- cryptocom/ccxt/static_dependencies/lark/lark.py +658 -0
- cryptocom/ccxt/static_dependencies/lark/lexer.py +678 -0
- cryptocom/ccxt/static_dependencies/lark/load_grammar.py +1428 -0
- cryptocom/ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
- cryptocom/ccxt/static_dependencies/lark/parser_frontends.py +257 -0
- cryptocom/ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
- cryptocom/ccxt/static_dependencies/lark/parsers/earley.py +314 -0
- cryptocom/ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
- cryptocom/ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
- cryptocom/ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
- cryptocom/ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
- cryptocom/ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
- cryptocom/ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
- cryptocom/ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
- cryptocom/ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
- cryptocom/ccxt/static_dependencies/lark/py.typed +0 -0
- cryptocom/ccxt/static_dependencies/lark/reconstruct.py +107 -0
- cryptocom/ccxt/static_dependencies/lark/tools/__init__.py +70 -0
- cryptocom/ccxt/static_dependencies/lark/tools/nearley.py +202 -0
- cryptocom/ccxt/static_dependencies/lark/tools/serialize.py +32 -0
- cryptocom/ccxt/static_dependencies/lark/tools/standalone.py +196 -0
- cryptocom/ccxt/static_dependencies/lark/tree.py +267 -0
- cryptocom/ccxt/static_dependencies/lark/tree_matcher.py +186 -0
- cryptocom/ccxt/static_dependencies/lark/tree_templates.py +180 -0
- cryptocom/ccxt/static_dependencies/lark/utils.py +343 -0
- cryptocom/ccxt/static_dependencies/lark/visitors.py +596 -0
- cryptocom/ccxt/static_dependencies/marshmallow/__init__.py +81 -0
- cryptocom/ccxt/static_dependencies/marshmallow/base.py +65 -0
- cryptocom/ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
- cryptocom/ccxt/static_dependencies/marshmallow/decorators.py +231 -0
- cryptocom/ccxt/static_dependencies/marshmallow/error_store.py +60 -0
- cryptocom/ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
- cryptocom/ccxt/static_dependencies/marshmallow/fields.py +2114 -0
- cryptocom/ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
- cryptocom/ccxt/static_dependencies/marshmallow/py.typed +0 -0
- cryptocom/ccxt/static_dependencies/marshmallow/schema.py +1228 -0
- cryptocom/ccxt/static_dependencies/marshmallow/types.py +12 -0
- cryptocom/ccxt/static_dependencies/marshmallow/utils.py +378 -0
- cryptocom/ccxt/static_dependencies/marshmallow/validate.py +678 -0
- cryptocom/ccxt/static_dependencies/marshmallow/warnings.py +2 -0
- cryptocom/ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
- cryptocom/ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
- cryptocom/ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
- cryptocom/ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
- cryptocom/ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- cryptocom/ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
- cryptocom/ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
- cryptocom/ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
- cryptocom/ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
- cryptocom/ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- cryptocom/ccxt/static_dependencies/msgpack/__init__.py +55 -0
- cryptocom/ccxt/static_dependencies/msgpack/_cmsgpack.pyx +11 -0
- cryptocom/ccxt/static_dependencies/msgpack/_packer.pyx +374 -0
- cryptocom/ccxt/static_dependencies/msgpack/_unpacker.pyx +547 -0
- cryptocom/ccxt/static_dependencies/msgpack/buff_converter.h +8 -0
- cryptocom/ccxt/static_dependencies/msgpack/exceptions.py +48 -0
- cryptocom/ccxt/static_dependencies/msgpack/ext.py +168 -0
- cryptocom/ccxt/static_dependencies/msgpack/fallback.py +951 -0
- cryptocom/ccxt/static_dependencies/msgpack/pack.h +89 -0
- cryptocom/ccxt/static_dependencies/msgpack/pack_template.h +820 -0
- cryptocom/ccxt/static_dependencies/msgpack/sysdep.h +194 -0
- cryptocom/ccxt/static_dependencies/msgpack/unpack.h +391 -0
- cryptocom/ccxt/static_dependencies/msgpack/unpack_define.h +95 -0
- cryptocom/ccxt/static_dependencies/msgpack/unpack_template.h +464 -0
- cryptocom/ccxt/static_dependencies/parsimonious/__init__.py +10 -0
- cryptocom/ccxt/static_dependencies/parsimonious/exceptions.py +105 -0
- cryptocom/ccxt/static_dependencies/parsimonious/expressions.py +479 -0
- cryptocom/ccxt/static_dependencies/parsimonious/grammar.py +487 -0
- cryptocom/ccxt/static_dependencies/parsimonious/nodes.py +325 -0
- cryptocom/ccxt/static_dependencies/parsimonious/utils.py +40 -0
- cryptocom/ccxt/static_dependencies/starknet/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v0/__init__.py +2 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v0/model.py +44 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v0/parser.py +216 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v0/schemas.py +72 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v0/shape.py +63 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v1/__init__.py +2 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v1/core_structures.json +14 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v1/model.py +39 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v1/parser.py +220 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v1/parser_transformer.py +179 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v1/schemas.py +66 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v1/shape.py +47 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v2/__init__.py +2 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v2/model.py +89 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v2/parser.py +293 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v2/parser_transformer.py +192 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v2/schemas.py +132 -0
- cryptocom/ccxt/static_dependencies/starknet/abi/v2/shape.py +107 -0
- cryptocom/ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
- cryptocom/ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
- cryptocom/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
- cryptocom/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
- cryptocom/ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
- cryptocom/ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
- cryptocom/ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
- cryptocom/ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
- cryptocom/ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
- cryptocom/ccxt/static_dependencies/starknet/common.py +15 -0
- cryptocom/ccxt/static_dependencies/starknet/constants.py +39 -0
- cryptocom/ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/starknet/hash/address.py +79 -0
- cryptocom/ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
- cryptocom/ccxt/static_dependencies/starknet/hash/selector.py +16 -0
- cryptocom/ccxt/static_dependencies/starknet/hash/storage.py +12 -0
- cryptocom/ccxt/static_dependencies/starknet/hash/utils.py +78 -0
- cryptocom/ccxt/static_dependencies/starknet/models/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
- cryptocom/ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
- cryptocom/ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
- cryptocom/ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
- cryptocom/ccxt/static_dependencies/starknet/utils/schema.py +13 -0
- cryptocom/ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
- cryptocom/ccxt/static_dependencies/starkware/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
- cryptocom/ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
- cryptocom/ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
- cryptocom/ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
- cryptocom/ccxt/static_dependencies/sympy/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/sympy/core/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
- cryptocom/ccxt/static_dependencies/sympy/external/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
- cryptocom/ccxt/static_dependencies/sympy/external/importtools.py +187 -0
- cryptocom/ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
- cryptocom/ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
- cryptocom/ccxt/static_dependencies/toolz/__init__.py +26 -0
- cryptocom/ccxt/static_dependencies/toolz/_signatures.py +784 -0
- cryptocom/ccxt/static_dependencies/toolz/_version.py +520 -0
- cryptocom/ccxt/static_dependencies/toolz/compatibility.py +30 -0
- cryptocom/ccxt/static_dependencies/toolz/curried/__init__.py +101 -0
- cryptocom/ccxt/static_dependencies/toolz/curried/exceptions.py +22 -0
- cryptocom/ccxt/static_dependencies/toolz/curried/operator.py +22 -0
- cryptocom/ccxt/static_dependencies/toolz/dicttoolz.py +339 -0
- cryptocom/ccxt/static_dependencies/toolz/functoolz.py +1049 -0
- cryptocom/ccxt/static_dependencies/toolz/itertoolz.py +1057 -0
- cryptocom/ccxt/static_dependencies/toolz/recipes.py +46 -0
- cryptocom/ccxt/static_dependencies/toolz/utils.py +9 -0
- cryptocom/ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
- cryptocom/ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
- crypto_com_sdk-0.0.13.dist-info/RECORD +0 -3
- {crypto_com_sdk-0.0.13.dist-info → crypto_com_sdk-0.0.15.dist-info}/WHEEL +0 -0
@@ -0,0 +1,1326 @@
|
|
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, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
|
8
|
+
import hashlib
|
9
|
+
from ccxt.base.types import Any, Balances, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, 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 AuthenticationError
|
14
|
+
from ccxt.base.errors import NetworkError
|
15
|
+
from ccxt.base.errors import ChecksumError
|
16
|
+
|
17
|
+
|
18
|
+
from ccxt.async_support import cryptocom as cryptocomAsync
|
19
|
+
|
20
|
+
|
21
|
+
class cryptocom(cryptocomAsync):
|
22
|
+
|
23
|
+
def describe(self) -> Any:
|
24
|
+
return self.deep_extend(super(cryptocom, self).describe(), {
|
25
|
+
'has': {
|
26
|
+
'ws': True,
|
27
|
+
'watchBalance': True,
|
28
|
+
'watchTicker': True,
|
29
|
+
'watchTickers': True,
|
30
|
+
'watchBidsAsks': True,
|
31
|
+
'watchMyTrades': True,
|
32
|
+
'watchTrades': True,
|
33
|
+
'watchTradesForSymbols': True,
|
34
|
+
'watchOrderBook': True,
|
35
|
+
'watchOrderBookForSymbols': True,
|
36
|
+
'watchOrders': True,
|
37
|
+
'watchOHLCV': True,
|
38
|
+
'watchPositions': True,
|
39
|
+
'createOrderWs': True,
|
40
|
+
'cancelOrderWs': True,
|
41
|
+
'cancelAllOrders': True,
|
42
|
+
},
|
43
|
+
'urls': {
|
44
|
+
'api': {
|
45
|
+
'ws': {
|
46
|
+
'public': 'wss://stream.crypto.com/exchange/v1/market',
|
47
|
+
'private': 'wss://stream.crypto.com/exchange/v1/user',
|
48
|
+
},
|
49
|
+
},
|
50
|
+
'test': {
|
51
|
+
'public': 'wss://uat-stream.3ona.co/exchange/v1/market',
|
52
|
+
'private': 'wss://uat-stream.3ona.co/exchange/v1/user',
|
53
|
+
},
|
54
|
+
},
|
55
|
+
'options': {
|
56
|
+
'watchPositions': {
|
57
|
+
'fetchPositionsSnapshot': True, # or False
|
58
|
+
'awaitPositionsSnapshot': True, # whether to wait for the positions snapshot before providing updates
|
59
|
+
},
|
60
|
+
'watchOrderBook': {
|
61
|
+
'checksum': True,
|
62
|
+
},
|
63
|
+
},
|
64
|
+
'streaming': {
|
65
|
+
},
|
66
|
+
})
|
67
|
+
|
68
|
+
async def pong(self, client, message):
|
69
|
+
# {
|
70
|
+
# "id": 1587523073344,
|
71
|
+
# "method": "public/heartbeat",
|
72
|
+
# "code": 0
|
73
|
+
# }
|
74
|
+
try:
|
75
|
+
await client.send({'id': self.safe_integer(message, 'id'), 'method': 'public/respond-heartbeat'})
|
76
|
+
except Exception as e:
|
77
|
+
error = NetworkError(self.id + ' pong failed with error ' + self.json(e))
|
78
|
+
client.reset(error)
|
79
|
+
|
80
|
+
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
81
|
+
"""
|
82
|
+
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
83
|
+
|
84
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#book-instrument_name
|
85
|
+
|
86
|
+
:param str symbol: unified symbol of the market to fetch the order book for
|
87
|
+
:param int [limit]: the maximum amount of order book entries to return
|
88
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
89
|
+
:param str [params.bookSubscriptionType]: The subscription type. Allowed values: SNAPSHOT full snapshot. This is the default if not specified. SNAPSHOT_AND_UPDATE delta updates
|
90
|
+
:param int [params.bookUpdateFrequency]: Book update interval in ms. Allowed values: 100 for snapshot subscription 10 for delta subscription
|
91
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
92
|
+
"""
|
93
|
+
return await self.watch_order_book_for_symbols([symbol], limit, params)
|
94
|
+
|
95
|
+
async def un_watch_order_book(self, symbol: str, params={}) -> Any:
|
96
|
+
"""
|
97
|
+
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
98
|
+
|
99
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#book-instrument_name
|
100
|
+
|
101
|
+
:param str symbol: unified symbol of the market to fetch the order book for
|
102
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
103
|
+
:param str [params.bookSubscriptionType]: The subscription type. Allowed values: SNAPSHOT full snapshot. This is the default if not specified. SNAPSHOT_AND_UPDATE delta updates
|
104
|
+
:param int [params.bookUpdateFrequency]: Book update interval in ms. Allowed values: 100 for snapshot subscription 10 for delta subscription
|
105
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
106
|
+
"""
|
107
|
+
return await self.un_watch_order_book_for_symbols([symbol], params)
|
108
|
+
|
109
|
+
async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
|
110
|
+
"""
|
111
|
+
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
112
|
+
|
113
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#book-instrument_name
|
114
|
+
|
115
|
+
:param str[] symbols: unified array of symbols
|
116
|
+
:param int [limit]: the maximum amount of order book entries to return
|
117
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
118
|
+
:param str [params.bookSubscriptionType]: The subscription type. Allowed values: SNAPSHOT full snapshot. This is the default if not specified. SNAPSHOT_AND_UPDATE delta updates
|
119
|
+
:param int [params.bookUpdateFrequency]: Book update interval in ms. Allowed values: 100 for snapshot subscription 10 for delta subscription
|
120
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
121
|
+
"""
|
122
|
+
await self.load_markets()
|
123
|
+
symbols = self.market_symbols(symbols)
|
124
|
+
topics = []
|
125
|
+
messageHashes = []
|
126
|
+
if not limit:
|
127
|
+
limit = 50
|
128
|
+
topicParams = self.safe_value(params, 'params')
|
129
|
+
if topicParams is None:
|
130
|
+
params['params'] = {}
|
131
|
+
bookSubscriptionType = None
|
132
|
+
bookSubscriptionType2 = None
|
133
|
+
bookSubscriptionType, params = self.handle_option_and_params(params, 'watchOrderBook', 'bookSubscriptionType', 'SNAPSHOT_AND_UPDATE')
|
134
|
+
bookSubscriptionType2, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'bookSubscriptionType', bookSubscriptionType)
|
135
|
+
params['params']['bookSubscriptionType'] = bookSubscriptionType2
|
136
|
+
bookUpdateFrequency = None
|
137
|
+
bookUpdateFrequency2 = None
|
138
|
+
bookUpdateFrequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'bookUpdateFrequency')
|
139
|
+
bookUpdateFrequency2, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'bookUpdateFrequency', bookUpdateFrequency)
|
140
|
+
if bookUpdateFrequency2 is not None:
|
141
|
+
params['params']['bookSubscriptionType'] = bookUpdateFrequency2
|
142
|
+
for i in range(0, len(symbols)):
|
143
|
+
symbol = symbols[i]
|
144
|
+
market = self.market(symbol)
|
145
|
+
currentTopic = 'book' + '.' + market['id'] + '.' + str(limit)
|
146
|
+
messageHash = 'orderbook:' + market['symbol']
|
147
|
+
messageHashes.append(messageHash)
|
148
|
+
topics.append(currentTopic)
|
149
|
+
orderbook = await self.watch_public_multiple(messageHashes, topics, params)
|
150
|
+
return orderbook.limit()
|
151
|
+
|
152
|
+
async def un_watch_order_book_for_symbols(self, symbols: List[str], params={}) -> OrderBook:
|
153
|
+
"""
|
154
|
+
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
155
|
+
|
156
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#book-instrument_name
|
157
|
+
|
158
|
+
:param str[] symbols: unified array of symbols
|
159
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
160
|
+
:param int [params.limit]: orderbook limit, default is 50
|
161
|
+
:param str [params.bookSubscriptionType]: The subscription type. Allowed values: SNAPSHOT full snapshot. This is the default if not specified. SNAPSHOT_AND_UPDATE delta updates
|
162
|
+
:param int [params.bookUpdateFrequency]: Book update interval in ms. Allowed values: 100 for snapshot subscription 10 for delta subscription
|
163
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
164
|
+
"""
|
165
|
+
await self.load_markets()
|
166
|
+
symbols = self.market_symbols(symbols)
|
167
|
+
topics = []
|
168
|
+
subMessageHashes = []
|
169
|
+
messageHashes = []
|
170
|
+
limit = self.safe_integer(params, 'limit', 50)
|
171
|
+
topicParams = self.safe_value(params, 'params')
|
172
|
+
if topicParams is None:
|
173
|
+
params['params'] = {}
|
174
|
+
bookSubscriptionType = None
|
175
|
+
bookSubscriptionType2 = None
|
176
|
+
bookSubscriptionType, params = self.handle_option_and_params(params, 'watchOrderBook', 'bookSubscriptionType', 'SNAPSHOT_AND_UPDATE')
|
177
|
+
bookSubscriptionType2, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'bookSubscriptionType', bookSubscriptionType)
|
178
|
+
params['params']['bookSubscriptionType'] = bookSubscriptionType2
|
179
|
+
bookUpdateFrequency = None
|
180
|
+
bookUpdateFrequency2 = None
|
181
|
+
bookUpdateFrequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'bookUpdateFrequency')
|
182
|
+
bookUpdateFrequency2, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'bookUpdateFrequency', bookUpdateFrequency)
|
183
|
+
if bookUpdateFrequency2 is not None:
|
184
|
+
params['params']['bookSubscriptionType'] = bookUpdateFrequency2
|
185
|
+
for i in range(0, len(symbols)):
|
186
|
+
symbol = symbols[i]
|
187
|
+
market = self.market(symbol)
|
188
|
+
currentTopic = 'book' + '.' + market['id'] + '.' + str(limit)
|
189
|
+
messageHash = 'orderbook:' + market['symbol']
|
190
|
+
subMessageHashes.append(messageHash)
|
191
|
+
messageHashes.append('unsubscribe:' + messageHash)
|
192
|
+
topics.append(currentTopic)
|
193
|
+
return await self.un_watch_public_multiple('orderbook', symbols, messageHashes, subMessageHashes, topics, params)
|
194
|
+
|
195
|
+
def handle_delta(self, bookside, delta):
|
196
|
+
price = self.safe_float(delta, 0)
|
197
|
+
amount = self.safe_float(delta, 1)
|
198
|
+
count = self.safe_integer(delta, 2)
|
199
|
+
bookside.storeArray([price, amount, count])
|
200
|
+
|
201
|
+
def handle_deltas(self, bookside, deltas):
|
202
|
+
for i in range(0, len(deltas)):
|
203
|
+
self.handle_delta(bookside, deltas[i])
|
204
|
+
|
205
|
+
def handle_order_book(self, client: Client, message):
|
206
|
+
#
|
207
|
+
# snapshot
|
208
|
+
# {
|
209
|
+
# "instrument_name":"LTC_USDT",
|
210
|
+
# "subscription":"book.LTC_USDT.150",
|
211
|
+
# "channel":"book",
|
212
|
+
# "depth":150,
|
213
|
+
# "data": [
|
214
|
+
# {
|
215
|
+
# "bids": [
|
216
|
+
# [122.21, 0.74041, 4]
|
217
|
+
# ],
|
218
|
+
# "asks": [
|
219
|
+
# [122.29, 0.00002, 1]
|
220
|
+
# ]
|
221
|
+
# "t": 1648123943803,
|
222
|
+
# "s":754560122
|
223
|
+
# }
|
224
|
+
# ]
|
225
|
+
# }
|
226
|
+
# update
|
227
|
+
# {
|
228
|
+
# "instrument_name":"BTC_USDT",
|
229
|
+
# "subscription":"book.BTC_USDT.50",
|
230
|
+
# "channel":"book.update",
|
231
|
+
# "depth":50,
|
232
|
+
# "data":[
|
233
|
+
# {
|
234
|
+
# "update":{
|
235
|
+
# "asks":[
|
236
|
+
# [
|
237
|
+
# "43755.46",
|
238
|
+
# "0.10000",
|
239
|
+
# "1"
|
240
|
+
# ],
|
241
|
+
# ...
|
242
|
+
# ],
|
243
|
+
# "bids":[
|
244
|
+
# [
|
245
|
+
# "43737.46",
|
246
|
+
# "0.14096",
|
247
|
+
# "1"
|
248
|
+
# ],
|
249
|
+
# ...
|
250
|
+
# ]
|
251
|
+
# },
|
252
|
+
# "t":1704484068898,
|
253
|
+
# "tt":1704484068892,
|
254
|
+
# "u":78795598253024,
|
255
|
+
# "pu":78795598162080,
|
256
|
+
# "cs":-781431132
|
257
|
+
# }
|
258
|
+
# ]
|
259
|
+
# }
|
260
|
+
#
|
261
|
+
marketId = self.safe_string(message, 'instrument_name')
|
262
|
+
market = self.safe_market(marketId)
|
263
|
+
symbol = market['symbol']
|
264
|
+
data = self.safe_value(message, 'data')
|
265
|
+
data = self.safe_value(data, 0)
|
266
|
+
timestamp = self.safe_integer(data, 't')
|
267
|
+
if not (symbol in self.orderbooks):
|
268
|
+
limit = self.safe_integer(message, 'depth')
|
269
|
+
self.orderbooks[symbol] = self.counted_order_book({}, limit)
|
270
|
+
orderbook = self.orderbooks[symbol]
|
271
|
+
channel = self.safe_string(message, 'channel')
|
272
|
+
nonce = self.safe_integer_2(data, 'u', 's')
|
273
|
+
books = data
|
274
|
+
if channel == 'book': # snapshot
|
275
|
+
orderbook.reset({})
|
276
|
+
orderbook['symbol'] = symbol
|
277
|
+
orderbook['timestamp'] = timestamp
|
278
|
+
orderbook['datetime'] = self.iso8601(timestamp)
|
279
|
+
orderbook['nonce'] = nonce
|
280
|
+
else:
|
281
|
+
books = self.safe_value(data, 'update', {})
|
282
|
+
previousNonce = self.safe_integer(data, 'pu')
|
283
|
+
currentNonce = orderbook['nonce']
|
284
|
+
if currentNonce != previousNonce:
|
285
|
+
checksum = self.handle_option('watchOrderBook', 'checksum', True)
|
286
|
+
if checksum:
|
287
|
+
raise ChecksumError(self.id + ' ' + self.orderbook_checksum_message(symbol))
|
288
|
+
self.handle_deltas(orderbook['asks'], self.safe_value(books, 'asks', []))
|
289
|
+
self.handle_deltas(orderbook['bids'], self.safe_value(books, 'bids', []))
|
290
|
+
orderbook['nonce'] = nonce
|
291
|
+
self.orderbooks[symbol] = orderbook
|
292
|
+
messageHash = 'orderbook:' + symbol
|
293
|
+
client.resolve(orderbook, messageHash)
|
294
|
+
|
295
|
+
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
296
|
+
"""
|
297
|
+
get the list of most recent trades for a particular symbol
|
298
|
+
|
299
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#trade-instrument_name
|
300
|
+
|
301
|
+
:param str symbol: unified symbol of the market to fetch trades for
|
302
|
+
:param int [since]: timestamp in ms of the earliest trade to fetch
|
303
|
+
:param int [limit]: the maximum amount of trades to fetch
|
304
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
305
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
306
|
+
"""
|
307
|
+
return await self.watch_trades_for_symbols([symbol], since, limit, params)
|
308
|
+
|
309
|
+
async def un_watch_trades(self, symbol: str, params={}) -> List[Trade]:
|
310
|
+
"""
|
311
|
+
get the list of most recent trades for a particular symbol
|
312
|
+
|
313
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#trade-instrument_name
|
314
|
+
|
315
|
+
:param str symbol: unified symbol of the market to fetch trades for
|
316
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
317
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
318
|
+
"""
|
319
|
+
return await self.un_watch_trades_for_symbols([symbol], params)
|
320
|
+
|
321
|
+
async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
322
|
+
"""
|
323
|
+
get the list of most recent trades for a particular symbol
|
324
|
+
|
325
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#trade-instrument_name
|
326
|
+
|
327
|
+
:param str[] symbols: unified symbol of the market to fetch trades for
|
328
|
+
:param int [since]: timestamp in ms of the earliest trade to fetch
|
329
|
+
:param int [limit]: the maximum amount of trades to fetch
|
330
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
331
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
332
|
+
"""
|
333
|
+
await self.load_markets()
|
334
|
+
symbols = self.market_symbols(symbols)
|
335
|
+
topics = []
|
336
|
+
for i in range(0, len(symbols)):
|
337
|
+
symbol = symbols[i]
|
338
|
+
market = self.market(symbol)
|
339
|
+
currentTopic = 'trade' + '.' + market['id']
|
340
|
+
topics.append(currentTopic)
|
341
|
+
trades = await self.watch_public_multiple(topics, topics, params)
|
342
|
+
if self.newUpdates:
|
343
|
+
first = self.safe_value(trades, 0)
|
344
|
+
tradeSymbol = self.safe_string(first, 'symbol')
|
345
|
+
limit = trades.getLimit(tradeSymbol, limit)
|
346
|
+
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
347
|
+
|
348
|
+
async def un_watch_trades_for_symbols(self, symbols: List[str], params={}) -> Any:
|
349
|
+
"""
|
350
|
+
get the list of most recent trades for a particular symbol
|
351
|
+
|
352
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#trade-instrument_name
|
353
|
+
|
354
|
+
:param str[] [symbols]: list of unified market symbols to unwatch trades for
|
355
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
356
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
357
|
+
"""
|
358
|
+
await self.load_markets()
|
359
|
+
symbols = self.market_symbols(symbols)
|
360
|
+
topics = []
|
361
|
+
messageHashes = []
|
362
|
+
for i in range(0, len(symbols)):
|
363
|
+
symbol = symbols[i]
|
364
|
+
market = self.market(symbol)
|
365
|
+
currentTopic = 'trade' + '.' + market['id']
|
366
|
+
messageHashes.append('unsubscribe:trades:' + market['symbol'])
|
367
|
+
topics.append(currentTopic)
|
368
|
+
return await self.un_watch_public_multiple('trades', symbols, messageHashes, topics, topics, params)
|
369
|
+
|
370
|
+
def handle_trades(self, client: Client, message):
|
371
|
+
#
|
372
|
+
# {
|
373
|
+
# "code": 0,
|
374
|
+
# "method": "subscribe",
|
375
|
+
# "result": {
|
376
|
+
# "instrument_name": "BTC_USDT",
|
377
|
+
# "subscription": "trade.BTC_USDT",
|
378
|
+
# "channel": "trade",
|
379
|
+
# "data": [
|
380
|
+
# {
|
381
|
+
# "dataTime":1648122434405,
|
382
|
+
# "d":"2358394540212355488",
|
383
|
+
# "s":"SELL",
|
384
|
+
# "p":42980.85,
|
385
|
+
# "q":0.002325,
|
386
|
+
# "t":1648122434404,
|
387
|
+
# "i":"BTC_USDT"
|
388
|
+
# }
|
389
|
+
# (...)
|
390
|
+
# ]
|
391
|
+
# }
|
392
|
+
#
|
393
|
+
channel = self.safe_string(message, 'channel')
|
394
|
+
marketId = self.safe_string(message, 'instrument_name')
|
395
|
+
symbolSpecificMessageHash = self.safe_string(message, 'subscription')
|
396
|
+
market = self.safe_market(marketId)
|
397
|
+
symbol = market['symbol']
|
398
|
+
stored = self.safe_value(self.trades, symbol)
|
399
|
+
if stored is None:
|
400
|
+
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
401
|
+
stored = ArrayCache(limit)
|
402
|
+
self.trades[symbol] = stored
|
403
|
+
data = self.safe_value(message, 'data', [])
|
404
|
+
dataLength = len(data)
|
405
|
+
if dataLength == 0:
|
406
|
+
return
|
407
|
+
parsedTrades = self.parse_trades(data, market)
|
408
|
+
for j in range(0, len(parsedTrades)):
|
409
|
+
stored.append(parsedTrades[j])
|
410
|
+
channelReplaced = channel.replace('.' + marketId, '')
|
411
|
+
client.resolve(stored, symbolSpecificMessageHash)
|
412
|
+
client.resolve(stored, channelReplaced)
|
413
|
+
|
414
|
+
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
415
|
+
"""
|
416
|
+
watches information on multiple trades made by the user
|
417
|
+
|
418
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#user-trade-instrument_name
|
419
|
+
|
420
|
+
:param str symbol: unified market symbol of the market trades were made in
|
421
|
+
:param int [since]: the earliest time in ms to fetch trades for
|
422
|
+
:param int [limit]: the maximum number of trade structures to retrieve
|
423
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
424
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
425
|
+
"""
|
426
|
+
await self.load_markets()
|
427
|
+
market = None
|
428
|
+
if symbol is not None:
|
429
|
+
market = self.market(symbol)
|
430
|
+
symbol = market['symbol']
|
431
|
+
messageHash = 'user.trade'
|
432
|
+
messageHash = (messageHash + '.' + market['id']) if (market is not None) else messageHash
|
433
|
+
trades = await self.watch_private_subscribe(messageHash, params)
|
434
|
+
if self.newUpdates:
|
435
|
+
limit = trades.getLimit(symbol, limit)
|
436
|
+
return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
|
437
|
+
|
438
|
+
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
439
|
+
"""
|
440
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
441
|
+
|
442
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
|
443
|
+
|
444
|
+
:param str symbol: unified symbol of the market to fetch the ticker for
|
445
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
446
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
447
|
+
"""
|
448
|
+
await self.load_markets()
|
449
|
+
market = self.market(symbol)
|
450
|
+
messageHash = 'ticker' + '.' + market['id']
|
451
|
+
return await self.watch_public(messageHash, params)
|
452
|
+
|
453
|
+
async def un_watch_ticker(self, symbol: str, params={}) -> Any:
|
454
|
+
"""
|
455
|
+
unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
456
|
+
|
457
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
|
458
|
+
|
459
|
+
:param str symbol: unified symbol of the market to fetch the ticker for
|
460
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
461
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
462
|
+
"""
|
463
|
+
await self.load_markets()
|
464
|
+
market = self.market(symbol)
|
465
|
+
subMessageHash = 'ticker' + '.' + market['id']
|
466
|
+
messageHash = 'unsubscribe:ticker:' + market['symbol']
|
467
|
+
return await self.un_watch_public_multiple('ticker', [market['symbol']], [messageHash], [subMessageHash], [subMessageHash], params)
|
468
|
+
|
469
|
+
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
470
|
+
"""
|
471
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
472
|
+
|
473
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
|
474
|
+
|
475
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
476
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
477
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
478
|
+
"""
|
479
|
+
await self.load_markets()
|
480
|
+
symbols = self.market_symbols(symbols, None, False)
|
481
|
+
messageHashes = []
|
482
|
+
marketIds = self.market_ids(symbols)
|
483
|
+
for i in range(0, len(marketIds)):
|
484
|
+
marketId = marketIds[i]
|
485
|
+
messageHashes.append('ticker.' + marketId)
|
486
|
+
url = self.urls['api']['ws']['public']
|
487
|
+
id = self.nonce()
|
488
|
+
request: dict = {
|
489
|
+
'method': 'subscribe',
|
490
|
+
'params': {
|
491
|
+
'channels': messageHashes,
|
492
|
+
},
|
493
|
+
'nonce': id,
|
494
|
+
}
|
495
|
+
ticker = await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
496
|
+
if self.newUpdates:
|
497
|
+
result: dict = {}
|
498
|
+
result[ticker['symbol']] = ticker
|
499
|
+
return result
|
500
|
+
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
501
|
+
|
502
|
+
async def un_watch_tickers(self, symbols: Strings = None, params={}) -> Any:
|
503
|
+
"""
|
504
|
+
unWatches a price ticker
|
505
|
+
|
506
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
|
507
|
+
|
508
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
509
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
510
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
511
|
+
"""
|
512
|
+
await self.load_markets()
|
513
|
+
symbols = self.market_symbols(symbols, None, False)
|
514
|
+
messageHashes = []
|
515
|
+
subMessageHashes = []
|
516
|
+
marketIds = self.market_ids(symbols)
|
517
|
+
for i in range(0, len(marketIds)):
|
518
|
+
marketId = marketIds[i]
|
519
|
+
symbol = symbols[i]
|
520
|
+
subMessageHashes.append('ticker.' + marketId)
|
521
|
+
messageHashes.append('unsubscribe:ticker:' + symbol)
|
522
|
+
return await self.un_watch_public_multiple('ticker', symbols, messageHashes, subMessageHashes, subMessageHashes, params)
|
523
|
+
|
524
|
+
def handle_ticker(self, client: Client, message):
|
525
|
+
#
|
526
|
+
# {
|
527
|
+
# "instrument_name": "ETHUSD-PERP",
|
528
|
+
# "subscription": "ticker.ETHUSD-PERP",
|
529
|
+
# "channel": "ticker",
|
530
|
+
# "data": [
|
531
|
+
# {
|
532
|
+
# "h": "2400.20",
|
533
|
+
# "l": "2277.10",
|
534
|
+
# "a": "2335.25",
|
535
|
+
# "c": "-0.0022",
|
536
|
+
# "b": "2335.10",
|
537
|
+
# "bs": "5.4000",
|
538
|
+
# "k": "2335.16",
|
539
|
+
# "ks": "1.9970",
|
540
|
+
# "i": "ETHUSD-PERP",
|
541
|
+
# "v": "1305697.6462",
|
542
|
+
# "vv": "3058704939.17",
|
543
|
+
# "oi": "161646.3614",
|
544
|
+
# "t": 1726069647560
|
545
|
+
# }
|
546
|
+
# ]
|
547
|
+
# }
|
548
|
+
#
|
549
|
+
self.handle_bid_ask(client, message)
|
550
|
+
messageHash = self.safe_string(message, 'subscription')
|
551
|
+
marketId = self.safe_string(message, 'instrument_name')
|
552
|
+
market = self.safe_market(marketId)
|
553
|
+
data = self.safe_value(message, 'data', [])
|
554
|
+
for i in range(0, len(data)):
|
555
|
+
ticker = data[i]
|
556
|
+
parsed = self.parse_ws_ticker(ticker, market)
|
557
|
+
symbol = parsed['symbol']
|
558
|
+
self.tickers[symbol] = parsed
|
559
|
+
client.resolve(parsed, messageHash)
|
560
|
+
|
561
|
+
def parse_ws_ticker(self, ticker: dict, market: Market = None) -> Ticker:
|
562
|
+
#
|
563
|
+
# {
|
564
|
+
# "h": "2400.20",
|
565
|
+
# "l": "2277.10",
|
566
|
+
# "a": "2335.25",
|
567
|
+
# "c": "-0.0022",
|
568
|
+
# "b": "2335.10",
|
569
|
+
# "bs": "5.4000",
|
570
|
+
# "k": "2335.16",
|
571
|
+
# "ks": "1.9970",
|
572
|
+
# "i": "ETHUSD-PERP",
|
573
|
+
# "v": "1305697.6462",
|
574
|
+
# "vv": "3058704939.17",
|
575
|
+
# "oi": "161646.3614",
|
576
|
+
# "t": 1726069647560
|
577
|
+
# }
|
578
|
+
#
|
579
|
+
timestamp = self.safe_integer(ticker, 't')
|
580
|
+
marketId = self.safe_string(ticker, 'i')
|
581
|
+
market = self.safe_market(marketId, market, '_')
|
582
|
+
quote = self.safe_string(market, 'quote')
|
583
|
+
last = self.safe_string(ticker, 'a')
|
584
|
+
return self.safe_ticker({
|
585
|
+
'symbol': market['symbol'],
|
586
|
+
'timestamp': timestamp,
|
587
|
+
'datetime': self.iso8601(timestamp),
|
588
|
+
'high': self.safe_number(ticker, 'h'),
|
589
|
+
'low': self.safe_number(ticker, 'l'),
|
590
|
+
'bid': self.safe_number(ticker, 'b'),
|
591
|
+
'bidVolume': self.safe_number(ticker, 'bs'),
|
592
|
+
'ask': self.safe_number(ticker, 'k'),
|
593
|
+
'askVolume': self.safe_number(ticker, 'ks'),
|
594
|
+
'vwap': None,
|
595
|
+
'open': None,
|
596
|
+
'close': last,
|
597
|
+
'last': last,
|
598
|
+
'previousClose': None,
|
599
|
+
'change': None,
|
600
|
+
'percentage': self.safe_string(ticker, 'c'),
|
601
|
+
'average': None,
|
602
|
+
'baseVolume': self.safe_string(ticker, 'v'),
|
603
|
+
'quoteVolume': self.safe_string(ticker, 'vv') if (quote == 'USD') else None,
|
604
|
+
'info': ticker,
|
605
|
+
}, market)
|
606
|
+
|
607
|
+
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
608
|
+
"""
|
609
|
+
|
610
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
|
611
|
+
|
612
|
+
watches best bid & ask for symbols
|
613
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
614
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
615
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
616
|
+
"""
|
617
|
+
await self.load_markets()
|
618
|
+
symbols = self.market_symbols(symbols, None, False)
|
619
|
+
messageHashes = []
|
620
|
+
topics = []
|
621
|
+
marketIds = self.market_ids(symbols)
|
622
|
+
for i in range(0, len(marketIds)):
|
623
|
+
marketId = marketIds[i]
|
624
|
+
messageHashes.append('bidask.' + symbols[i])
|
625
|
+
topics.append('ticker.' + marketId)
|
626
|
+
url = self.urls['api']['ws']['public']
|
627
|
+
id = self.nonce()
|
628
|
+
request: dict = {
|
629
|
+
'method': 'subscribe',
|
630
|
+
'params': {
|
631
|
+
'channels': topics,
|
632
|
+
},
|
633
|
+
'nonce': id,
|
634
|
+
}
|
635
|
+
newTickers = await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
636
|
+
if self.newUpdates:
|
637
|
+
tickers: dict = {}
|
638
|
+
tickers[newTickers['symbol']] = newTickers
|
639
|
+
return tickers
|
640
|
+
return self.filter_by_array(self.bidsasks, 'symbol', symbols)
|
641
|
+
|
642
|
+
def handle_bid_ask(self, client: Client, message):
|
643
|
+
data = self.safe_list(message, 'data', [])
|
644
|
+
ticker = self.safe_dict(data, 0, {})
|
645
|
+
parsedTicker = self.parse_ws_bid_ask(ticker)
|
646
|
+
symbol = parsedTicker['symbol']
|
647
|
+
self.bidsasks[symbol] = parsedTicker
|
648
|
+
messageHash = 'bidask.' + symbol
|
649
|
+
client.resolve(parsedTicker, messageHash)
|
650
|
+
|
651
|
+
def parse_ws_bid_ask(self, ticker, market=None):
|
652
|
+
marketId = self.safe_string(ticker, 'i')
|
653
|
+
market = self.safe_market(marketId, market)
|
654
|
+
symbol = self.safe_string(market, 'symbol')
|
655
|
+
timestamp = self.safe_integer(ticker, 't')
|
656
|
+
return self.safe_ticker({
|
657
|
+
'symbol': symbol,
|
658
|
+
'timestamp': timestamp,
|
659
|
+
'datetime': self.iso8601(timestamp),
|
660
|
+
'ask': self.safe_string(ticker, 'k'),
|
661
|
+
'askVolume': self.safe_string(ticker, 'ks'),
|
662
|
+
'bid': self.safe_string(ticker, 'b'),
|
663
|
+
'bidVolume': self.safe_string(ticker, 'bs'),
|
664
|
+
'info': ticker,
|
665
|
+
}, market)
|
666
|
+
|
667
|
+
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
668
|
+
"""
|
669
|
+
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
670
|
+
|
671
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#candlestick-time_frame-instrument_name
|
672
|
+
|
673
|
+
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
674
|
+
:param str timeframe: the length of time each candle represents
|
675
|
+
:param int [since]: timestamp in ms of the earliest candle to fetch
|
676
|
+
:param int [limit]: the maximum amount of candles to fetch
|
677
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
678
|
+
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
679
|
+
"""
|
680
|
+
await self.load_markets()
|
681
|
+
market = self.market(symbol)
|
682
|
+
symbol = market['symbol']
|
683
|
+
interval = self.safe_string(self.timeframes, timeframe, timeframe)
|
684
|
+
messageHash = 'candlestick' + '.' + interval + '.' + market['id']
|
685
|
+
ohlcv = await self.watch_public(messageHash, params)
|
686
|
+
if self.newUpdates:
|
687
|
+
limit = ohlcv.getLimit(symbol, limit)
|
688
|
+
return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
|
689
|
+
|
690
|
+
async def un_watch_ohlcv(self, symbol: str, timeframe='1m', params={}) -> Any:
|
691
|
+
"""
|
692
|
+
unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
693
|
+
|
694
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#candlestick-time_frame-instrument_name
|
695
|
+
|
696
|
+
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
697
|
+
:param str timeframe: the length of time each candle represents
|
698
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
699
|
+
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
700
|
+
"""
|
701
|
+
await self.load_markets()
|
702
|
+
market = self.market(symbol)
|
703
|
+
symbol = market['symbol']
|
704
|
+
interval = self.safe_string(self.timeframes, timeframe, timeframe)
|
705
|
+
subMessageHash = 'candlestick' + '.' + interval + '.' + market['id']
|
706
|
+
messageHash = 'unsubscribe:ohlcv:' + market['symbol'] + ':' + timeframe
|
707
|
+
subExtend = {
|
708
|
+
'symbolsAndTimeframes': [[market['symbol'], timeframe]],
|
709
|
+
}
|
710
|
+
return await self.un_watch_public_multiple('ohlcv', [market['symbol']], [messageHash], [subMessageHash], [subMessageHash], params, subExtend)
|
711
|
+
|
712
|
+
def handle_ohlcv(self, client: Client, message):
|
713
|
+
#
|
714
|
+
# {
|
715
|
+
# "instrument_name": "BTC_USDT",
|
716
|
+
# "subscription": "candlestick.1m.BTC_USDT",
|
717
|
+
# "channel": "candlestick",
|
718
|
+
# "depth": 300,
|
719
|
+
# "interval": "1m",
|
720
|
+
# "data": [[Object]]
|
721
|
+
# }
|
722
|
+
#
|
723
|
+
messageHash = self.safe_string(message, 'subscription')
|
724
|
+
marketId = self.safe_string(message, 'instrument_name')
|
725
|
+
market = self.safe_market(marketId)
|
726
|
+
symbol = market['symbol']
|
727
|
+
interval = self.safe_string(message, 'interval')
|
728
|
+
timeframe = self.find_timeframe(interval)
|
729
|
+
self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
|
730
|
+
stored = self.safe_value(self.ohlcvs[symbol], timeframe)
|
731
|
+
if stored is None:
|
732
|
+
limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
|
733
|
+
stored = ArrayCacheByTimestamp(limit)
|
734
|
+
self.ohlcvs[symbol][timeframe] = stored
|
735
|
+
data = self.safe_value(message, 'data')
|
736
|
+
for i in range(0, len(data)):
|
737
|
+
tick = data[i]
|
738
|
+
parsed = self.parse_ohlcv(tick, market)
|
739
|
+
stored.append(parsed)
|
740
|
+
client.resolve(stored, messageHash)
|
741
|
+
|
742
|
+
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
743
|
+
"""
|
744
|
+
watches information on multiple orders made by the user
|
745
|
+
|
746
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#user-order-instrument_name
|
747
|
+
|
748
|
+
:param str symbol: unified market symbol of the market orders were made in
|
749
|
+
:param int [since]: the earliest time in ms to fetch orders for
|
750
|
+
:param int [limit]: the maximum number of order structures to retrieve
|
751
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
752
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
753
|
+
"""
|
754
|
+
await self.load_markets()
|
755
|
+
market = None
|
756
|
+
if symbol is not None:
|
757
|
+
market = self.market(symbol)
|
758
|
+
symbol = market['symbol']
|
759
|
+
messageHash = 'user.order'
|
760
|
+
messageHash = (messageHash + '.' + market['id']) if (market is not None) else messageHash
|
761
|
+
orders = await self.watch_private_subscribe(messageHash, params)
|
762
|
+
if self.newUpdates:
|
763
|
+
limit = orders.getLimit(symbol, limit)
|
764
|
+
return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
|
765
|
+
|
766
|
+
def handle_orders(self, client: Client, message, subscription=None):
|
767
|
+
#
|
768
|
+
# {
|
769
|
+
# "method": "subscribe",
|
770
|
+
# "result": {
|
771
|
+
# "instrument_name": "ETH_CRO",
|
772
|
+
# "subscription": "user.order.ETH_CRO",
|
773
|
+
# "channel": "user.order",
|
774
|
+
# "data": [
|
775
|
+
# {
|
776
|
+
# "status": "ACTIVE",
|
777
|
+
# "side": "BUY",
|
778
|
+
# "price": 1,
|
779
|
+
# "quantity": 1,
|
780
|
+
# "order_id": "366455245775097673",
|
781
|
+
# "client_oid": "my_order_0002",
|
782
|
+
# "create_time": 1588758017375,
|
783
|
+
# "update_time": 1588758017411,
|
784
|
+
# "type": "LIMIT",
|
785
|
+
# "instrument_name": "ETH_CRO",
|
786
|
+
# "cumulative_quantity": 0,
|
787
|
+
# "cumulative_value": 0,
|
788
|
+
# "avg_price": 0,
|
789
|
+
# "fee_currency": "CRO",
|
790
|
+
# "time_in_force":"GOOD_TILL_CANCEL"
|
791
|
+
# }
|
792
|
+
# ],
|
793
|
+
# "channel": "user.order.ETH_CRO"
|
794
|
+
# }
|
795
|
+
# }
|
796
|
+
#
|
797
|
+
channel = self.safe_string(message, 'channel')
|
798
|
+
symbolSpecificMessageHash = self.safe_string(message, 'subscription')
|
799
|
+
orders = self.safe_value(message, 'data', [])
|
800
|
+
ordersLength = len(orders)
|
801
|
+
if ordersLength > 0:
|
802
|
+
if self.orders is None:
|
803
|
+
limit = self.safe_integer(self.options, 'ordersLimit', 1000)
|
804
|
+
self.orders = ArrayCacheBySymbolById(limit)
|
805
|
+
stored = self.orders
|
806
|
+
parsed = self.parse_orders(orders)
|
807
|
+
for i in range(0, len(parsed)):
|
808
|
+
stored.append(parsed[i])
|
809
|
+
client.resolve(stored, symbolSpecificMessageHash)
|
810
|
+
# non-symbol specific
|
811
|
+
client.resolve(stored, channel) # channel might have a symbol-specific suffix
|
812
|
+
client.resolve(stored, 'user.order')
|
813
|
+
|
814
|
+
async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
|
815
|
+
"""
|
816
|
+
watch all open positions
|
817
|
+
|
818
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#user-position_balance
|
819
|
+
|
820
|
+
:param str[] [symbols]: list of unified market symbols to watch positions for
|
821
|
+
:param int [since]: the earliest time in ms to fetch positions for
|
822
|
+
:param int [limit]: the maximum number of positions to retrieve
|
823
|
+
:param dict params: extra parameters specific to the exchange API endpoint
|
824
|
+
:returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
|
825
|
+
"""
|
826
|
+
await self.load_markets()
|
827
|
+
await self.authenticate()
|
828
|
+
url = self.urls['api']['ws']['private']
|
829
|
+
id = self.nonce()
|
830
|
+
request: dict = {
|
831
|
+
'method': 'subscribe',
|
832
|
+
'params': {
|
833
|
+
'channels': ['user.position_balance'],
|
834
|
+
},
|
835
|
+
'nonce': id,
|
836
|
+
}
|
837
|
+
messageHash = 'positions'
|
838
|
+
symbols = self.market_symbols(symbols)
|
839
|
+
if not self.is_empty(symbols):
|
840
|
+
messageHash = '::' + ','.join(symbols)
|
841
|
+
client = self.client(url)
|
842
|
+
self.set_positions_cache(client, symbols)
|
843
|
+
fetchPositionsSnapshot = self.handle_option('watchPositions', 'fetchPositionsSnapshot', True)
|
844
|
+
awaitPositionsSnapshot = self.handle_option('watchPositions', 'awaitPositionsSnapshot', True)
|
845
|
+
if fetchPositionsSnapshot and awaitPositionsSnapshot and self.positions is None:
|
846
|
+
snapshot = await client.future('fetchPositionsSnapshot')
|
847
|
+
return self.filter_by_symbols_since_limit(snapshot, symbols, since, limit, True)
|
848
|
+
newPositions = await self.watch(url, messageHash, self.extend(request, params))
|
849
|
+
if self.newUpdates:
|
850
|
+
return newPositions
|
851
|
+
return self.filter_by_symbols_since_limit(self.positions, symbols, since, limit, True)
|
852
|
+
|
853
|
+
def set_positions_cache(self, client: Client, type, symbols: Strings = None):
|
854
|
+
fetchPositionsSnapshot = self.handle_option('watchPositions', 'fetchPositionsSnapshot', False)
|
855
|
+
if fetchPositionsSnapshot:
|
856
|
+
messageHash = 'fetchPositionsSnapshot'
|
857
|
+
if not (messageHash in client.futures):
|
858
|
+
client.future(messageHash)
|
859
|
+
self.spawn(self.load_positions_snapshot, client, messageHash)
|
860
|
+
else:
|
861
|
+
self.positions = ArrayCacheBySymbolBySide()
|
862
|
+
|
863
|
+
async def load_positions_snapshot(self, client, messageHash):
|
864
|
+
positions = await self.fetch_positions()
|
865
|
+
self.positions = ArrayCacheBySymbolBySide()
|
866
|
+
cache = self.positions
|
867
|
+
for i in range(0, len(positions)):
|
868
|
+
position = positions[i]
|
869
|
+
contracts = self.safe_number(position, 'contracts', 0)
|
870
|
+
if contracts > 0:
|
871
|
+
cache.append(position)
|
872
|
+
# don't remove the future from the .futures cache
|
873
|
+
future = client.futures[messageHash]
|
874
|
+
future.resolve(cache)
|
875
|
+
client.resolve(cache, 'positions')
|
876
|
+
|
877
|
+
def handle_positions(self, client, message):
|
878
|
+
#
|
879
|
+
# {
|
880
|
+
# "subscription": "user.position_balance",
|
881
|
+
# "channel": "user.position_balance",
|
882
|
+
# "data": [{
|
883
|
+
# "balances": [{
|
884
|
+
# "instrument_name": "USD",
|
885
|
+
# "quantity": "8.9979961950886",
|
886
|
+
# "update_timestamp_ms": 1695598760597,
|
887
|
+
# }],
|
888
|
+
# "positions": [{
|
889
|
+
# "account_id": "96a0edb1-afb5-4c7c-af89-5cb610319e2c",
|
890
|
+
# "instrument_name": "LTCUSD-PERP",
|
891
|
+
# "type": "PERPETUAL_SWAP",
|
892
|
+
# "quantity": "1.8",
|
893
|
+
# "cost": "114.766",
|
894
|
+
# "open_position_pnl": "-0.0216206",
|
895
|
+
# "session_pnl": "0.00962994",
|
896
|
+
# "update_timestamp_ms": 1695598760597,
|
897
|
+
# "open_pos_cost": "114.766",
|
898
|
+
# }],
|
899
|
+
# }],
|
900
|
+
# }
|
901
|
+
#
|
902
|
+
# each account is connected to a different endpoint
|
903
|
+
# and has exactly one subscriptionhash which is the account type
|
904
|
+
data = self.safe_value(message, 'data', [])
|
905
|
+
firstData = self.safe_value(data, 0, {})
|
906
|
+
rawPositions = self.safe_value(firstData, 'positions', [])
|
907
|
+
if self.positions is None:
|
908
|
+
self.positions = ArrayCacheBySymbolBySide()
|
909
|
+
cache = self.positions
|
910
|
+
newPositions = []
|
911
|
+
for i in range(0, len(rawPositions)):
|
912
|
+
rawPosition = rawPositions[i]
|
913
|
+
position = self.parse_position(rawPosition)
|
914
|
+
newPositions.append(position)
|
915
|
+
cache.append(position)
|
916
|
+
messageHashes = self.find_message_hashes(client, 'positions::')
|
917
|
+
for i in range(0, len(messageHashes)):
|
918
|
+
messageHash = messageHashes[i]
|
919
|
+
parts = messageHash.split('::')
|
920
|
+
symbolsString = parts[1]
|
921
|
+
symbols = symbolsString.split(',')
|
922
|
+
positions = self.filter_by_array(newPositions, 'symbol', symbols, False)
|
923
|
+
if not self.is_empty(positions):
|
924
|
+
client.resolve(positions, messageHash)
|
925
|
+
client.resolve(newPositions, 'positions')
|
926
|
+
|
927
|
+
async def watch_balance(self, params={}) -> Balances:
|
928
|
+
"""
|
929
|
+
watch balance and get the amount of funds available for trading or funds locked in orders
|
930
|
+
|
931
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#user-balance
|
932
|
+
|
933
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
934
|
+
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
935
|
+
"""
|
936
|
+
messageHash = 'user.balance'
|
937
|
+
return await self.watch_private_subscribe(messageHash, params)
|
938
|
+
|
939
|
+
def handle_balance(self, client: Client, message):
|
940
|
+
#
|
941
|
+
# {
|
942
|
+
# "id": 1,
|
943
|
+
# "method": "subscribe",
|
944
|
+
# "code": 0,
|
945
|
+
# "result": {
|
946
|
+
# "subscription": "user.balance",
|
947
|
+
# "channel": "user.balance",
|
948
|
+
# "data": [
|
949
|
+
# {
|
950
|
+
# "total_available_balance": "5.84684368",
|
951
|
+
# "total_margin_balance": "5.84684368",
|
952
|
+
# "total_initial_margin": "0",
|
953
|
+
# "total_maintenance_margin": "0",
|
954
|
+
# "total_position_cost": "0",
|
955
|
+
# "total_cash_balance": "6.44412101",
|
956
|
+
# "total_collateral_value": "5.846843685",
|
957
|
+
# "total_session_unrealized_pnl": "0",
|
958
|
+
# "instrument_name": "USD",
|
959
|
+
# "total_session_realized_pnl": "0",
|
960
|
+
# "position_balances": [
|
961
|
+
# {
|
962
|
+
# "quantity": "0.0002119875",
|
963
|
+
# "reserved_qty": "0",
|
964
|
+
# "collateral_weight": "0.9",
|
965
|
+
# "collateral_amount": "5.37549592",
|
966
|
+
# "market_value": "5.97277325",
|
967
|
+
# "max_withdrawal_balance": "0.00021198",
|
968
|
+
# "instrument_name": "BTC",
|
969
|
+
# "hourly_interest_rate": "0"
|
970
|
+
# },
|
971
|
+
# ],
|
972
|
+
# "total_effective_leverage": "0",
|
973
|
+
# "position_limit": "3000000",
|
974
|
+
# "used_position_limit": "0",
|
975
|
+
# "total_borrow": "0",
|
976
|
+
# "margin_score": "0",
|
977
|
+
# "is_liquidating": False,
|
978
|
+
# "has_risk": False,
|
979
|
+
# "terminatable": True
|
980
|
+
# }
|
981
|
+
# ]
|
982
|
+
# }
|
983
|
+
# }
|
984
|
+
#
|
985
|
+
messageHash = self.safe_string(message, 'subscription')
|
986
|
+
data = self.safe_value(message, 'data', [])
|
987
|
+
positionBalances = self.safe_value(data[0], 'position_balances', [])
|
988
|
+
self.balance['info'] = data
|
989
|
+
for i in range(0, len(positionBalances)):
|
990
|
+
balance = positionBalances[i]
|
991
|
+
currencyId = self.safe_string(balance, 'instrument_name')
|
992
|
+
code = self.safe_currency_code(currencyId)
|
993
|
+
account = self.account()
|
994
|
+
account['total'] = self.safe_string(balance, 'quantity')
|
995
|
+
account['used'] = self.safe_string(balance, 'reserved_qty')
|
996
|
+
self.balance[code] = account
|
997
|
+
self.balance = self.safe_balance(self.balance)
|
998
|
+
client.resolve(self.balance, messageHash)
|
999
|
+
messageHashRequest = self.safe_string(message, 'id')
|
1000
|
+
client.resolve(self.balance, messageHashRequest)
|
1001
|
+
|
1002
|
+
async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
|
1003
|
+
"""
|
1004
|
+
|
1005
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-create-order
|
1006
|
+
|
1007
|
+
create a trade order
|
1008
|
+
:param str symbol: unified symbol of the market to create an order in
|
1009
|
+
:param str type: 'market' or 'limit'
|
1010
|
+
:param str side: 'buy' or 'sell'
|
1011
|
+
:param float amount: how much of currency you want to trade in units of base currency
|
1012
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
1013
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1014
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1015
|
+
"""
|
1016
|
+
await self.load_markets()
|
1017
|
+
params = self.create_order_request(symbol, type, side, amount, price, params)
|
1018
|
+
request: dict = {
|
1019
|
+
'method': 'private/create-order',
|
1020
|
+
'params': params,
|
1021
|
+
}
|
1022
|
+
messageHash = self.nonce()
|
1023
|
+
return await self.watch_private_request(messageHash, request)
|
1024
|
+
|
1025
|
+
def handle_order(self, client: Client, message):
|
1026
|
+
#
|
1027
|
+
# {
|
1028
|
+
# "id": 1,
|
1029
|
+
# "method": "private/create-order",
|
1030
|
+
# "code": 0,
|
1031
|
+
# "result": {
|
1032
|
+
# "client_oid": "c5f682ed-7108-4f1c-b755-972fcdca0f02",
|
1033
|
+
# "order_id": "18342311"
|
1034
|
+
# }
|
1035
|
+
# }
|
1036
|
+
#
|
1037
|
+
messageHash = self.safe_string(message, 'id')
|
1038
|
+
rawOrder = self.safe_value(message, 'result', {})
|
1039
|
+
order = self.parse_order(rawOrder)
|
1040
|
+
client.resolve(order, messageHash)
|
1041
|
+
|
1042
|
+
async def cancel_order_ws(self, id: str, symbol: Str = None, params={}) -> Order:
|
1043
|
+
"""
|
1044
|
+
cancels an open order
|
1045
|
+
|
1046
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-cancel-order
|
1047
|
+
|
1048
|
+
:param str id: the order id of the order to cancel
|
1049
|
+
:param str [symbol]: unified symbol of the market the order was made in
|
1050
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1051
|
+
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1052
|
+
"""
|
1053
|
+
await self.load_markets()
|
1054
|
+
params = self.extend({
|
1055
|
+
'order_id': id,
|
1056
|
+
}, params)
|
1057
|
+
request: dict = {
|
1058
|
+
'method': 'private/cancel-order',
|
1059
|
+
'params': params,
|
1060
|
+
}
|
1061
|
+
messageHash = self.nonce()
|
1062
|
+
return await self.watch_private_request(messageHash, request)
|
1063
|
+
|
1064
|
+
async def cancel_all_orders_ws(self, symbol: Str = None, params={}):
|
1065
|
+
"""
|
1066
|
+
cancel all open orders
|
1067
|
+
|
1068
|
+
https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-cancel-all-orders
|
1069
|
+
|
1070
|
+
:param str symbol: unified market symbol of the orders to cancel
|
1071
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1072
|
+
:returns dict} Returns exchange raw message {@link https://docs.ccxt.com/#/?id=order-structure:
|
1073
|
+
"""
|
1074
|
+
await self.load_markets()
|
1075
|
+
market = None
|
1076
|
+
request: dict = {
|
1077
|
+
'method': 'private/cancel-all-orders',
|
1078
|
+
'params': self.extend({}, params),
|
1079
|
+
}
|
1080
|
+
if symbol is not None:
|
1081
|
+
market = self.market(symbol)
|
1082
|
+
request['params']['instrument_name'] = market['id']
|
1083
|
+
messageHash = self.nonce()
|
1084
|
+
return await self.watch_private_request(messageHash, request)
|
1085
|
+
|
1086
|
+
def handle_cancel_all_orders(self, client: Client, message):
|
1087
|
+
#
|
1088
|
+
# {
|
1089
|
+
# "id": 1688914586647,
|
1090
|
+
# "method": "private/cancel-all-orders",
|
1091
|
+
# "code": 0
|
1092
|
+
# }
|
1093
|
+
#
|
1094
|
+
messageHash = self.safe_string(message, 'id')
|
1095
|
+
client.resolve(message, messageHash)
|
1096
|
+
|
1097
|
+
async def watch_public(self, messageHash, params={}):
|
1098
|
+
url = self.urls['api']['ws']['public']
|
1099
|
+
id = self.nonce()
|
1100
|
+
request: dict = {
|
1101
|
+
'method': 'subscribe',
|
1102
|
+
'params': {
|
1103
|
+
'channels': [messageHash],
|
1104
|
+
},
|
1105
|
+
'nonce': id,
|
1106
|
+
}
|
1107
|
+
message = self.extend(request, params)
|
1108
|
+
return await self.watch(url, messageHash, message, messageHash)
|
1109
|
+
|
1110
|
+
async def watch_public_multiple(self, messageHashes, topics, params={}):
|
1111
|
+
url = self.urls['api']['ws']['public']
|
1112
|
+
id = self.nonce()
|
1113
|
+
request: dict = {
|
1114
|
+
'method': 'subscribe',
|
1115
|
+
'params': {
|
1116
|
+
'channels': topics,
|
1117
|
+
},
|
1118
|
+
'nonce': id,
|
1119
|
+
}
|
1120
|
+
message = self.deep_extend(request, params)
|
1121
|
+
return await self.watch_multiple(url, messageHashes, message, messageHashes)
|
1122
|
+
|
1123
|
+
async def un_watch_public_multiple(self, topic: str, symbols: List[str], messageHashes: List[str], subMessageHashes: List[str], topics: List[str], params={}, subExtend={}):
|
1124
|
+
url = self.urls['api']['ws']['public']
|
1125
|
+
id = self.nonce()
|
1126
|
+
request: dict = {
|
1127
|
+
'method': 'unsubscribe',
|
1128
|
+
'params': {
|
1129
|
+
'channels': topics,
|
1130
|
+
},
|
1131
|
+
'nonce': id,
|
1132
|
+
'id': str(id),
|
1133
|
+
}
|
1134
|
+
subscription = {
|
1135
|
+
'id': str(id),
|
1136
|
+
'topic': topic,
|
1137
|
+
'symbols': symbols,
|
1138
|
+
'subMessageHashes': subMessageHashes,
|
1139
|
+
'messageHashes': messageHashes,
|
1140
|
+
}
|
1141
|
+
message = self.deep_extend(request, params)
|
1142
|
+
return await self.watch_multiple(url, messageHashes, message, messageHashes, self.extend(subscription, subExtend))
|
1143
|
+
|
1144
|
+
async def watch_private_request(self, nonce, params={}):
|
1145
|
+
await self.authenticate()
|
1146
|
+
url = self.urls['api']['ws']['private']
|
1147
|
+
request: dict = {
|
1148
|
+
'id': nonce,
|
1149
|
+
'nonce': nonce,
|
1150
|
+
}
|
1151
|
+
message = self.extend(request, params)
|
1152
|
+
return await self.watch(url, str(nonce), message, True)
|
1153
|
+
|
1154
|
+
async def watch_private_subscribe(self, messageHash, params={}):
|
1155
|
+
await self.authenticate()
|
1156
|
+
url = self.urls['api']['ws']['private']
|
1157
|
+
id = self.nonce()
|
1158
|
+
request: dict = {
|
1159
|
+
'method': 'subscribe',
|
1160
|
+
'params': {
|
1161
|
+
'channels': [messageHash],
|
1162
|
+
},
|
1163
|
+
'nonce': id,
|
1164
|
+
}
|
1165
|
+
message = self.extend(request, params)
|
1166
|
+
return await self.watch(url, messageHash, message, messageHash)
|
1167
|
+
|
1168
|
+
def handle_error_message(self, client: Client, message):
|
1169
|
+
#
|
1170
|
+
# {
|
1171
|
+
# "id": 0,
|
1172
|
+
# "code": 10004,
|
1173
|
+
# "method": "subscribe",
|
1174
|
+
# "message": "invalid channel {"channels":["trade.BTCUSD-PERP"]}"
|
1175
|
+
# }
|
1176
|
+
#
|
1177
|
+
id = self.safe_string(message, 'id')
|
1178
|
+
errorCode = self.safe_string(message, 'code')
|
1179
|
+
try:
|
1180
|
+
if errorCode and errorCode != '0':
|
1181
|
+
feedback = self.id + ' ' + self.json(message)
|
1182
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
|
1183
|
+
messageString = self.safe_value(message, 'message')
|
1184
|
+
if messageString is not None:
|
1185
|
+
self.throw_broadly_matched_exception(self.exceptions['broad'], messageString, feedback)
|
1186
|
+
raise ExchangeError(feedback)
|
1187
|
+
return False
|
1188
|
+
except Exception as e:
|
1189
|
+
if isinstance(e, AuthenticationError):
|
1190
|
+
messageHash = 'authenticated'
|
1191
|
+
client.reject(e, messageHash)
|
1192
|
+
if messageHash in client.subscriptions:
|
1193
|
+
del client.subscriptions[messageHash]
|
1194
|
+
else:
|
1195
|
+
client.reject(e, id)
|
1196
|
+
return True
|
1197
|
+
|
1198
|
+
def handle_subscribe(self, client: Client, message):
|
1199
|
+
methods: dict = {
|
1200
|
+
'candlestick': self.handle_ohlcv,
|
1201
|
+
'ticker': self.handle_ticker,
|
1202
|
+
'trade': self.handle_trades,
|
1203
|
+
'book': self.handle_order_book,
|
1204
|
+
'book.update': self.handle_order_book,
|
1205
|
+
'user.order': self.handle_orders,
|
1206
|
+
'user.trade': self.handle_trades,
|
1207
|
+
'user.balance': self.handle_balance,
|
1208
|
+
'user.position_balance': self.handle_positions,
|
1209
|
+
}
|
1210
|
+
result = self.safe_value_2(message, 'result', 'info')
|
1211
|
+
channel = self.safe_string(result, 'channel')
|
1212
|
+
if (channel is not None) and channel.find('user.trade') > -1:
|
1213
|
+
# channel might be user.trade.BTC_USDT
|
1214
|
+
self.handle_trades(client, result)
|
1215
|
+
if (channel is not None) and channel.startswith('user.order'):
|
1216
|
+
# channel might be user.order.BTC_USDT
|
1217
|
+
self.handle_orders(client, result)
|
1218
|
+
method = self.safe_value(methods, channel)
|
1219
|
+
if method is not None:
|
1220
|
+
method(client, result)
|
1221
|
+
|
1222
|
+
def handle_message(self, client: Client, message):
|
1223
|
+
#
|
1224
|
+
# ping
|
1225
|
+
# {
|
1226
|
+
# "id": 1587523073344,
|
1227
|
+
# "method": "public/heartbeat",
|
1228
|
+
# "code": 0
|
1229
|
+
# }
|
1230
|
+
# auth
|
1231
|
+
# {id: 1648132625434, method: "public/auth", code: 0}
|
1232
|
+
# ohlcv
|
1233
|
+
# {
|
1234
|
+
# "code": 0,
|
1235
|
+
# "method": "subscribe",
|
1236
|
+
# "result": {
|
1237
|
+
# "instrument_name": "BTC_USDT",
|
1238
|
+
# "subscription": "candlestick.1m.BTC_USDT",
|
1239
|
+
# "channel": "candlestick",
|
1240
|
+
# "depth": 300,
|
1241
|
+
# "interval": "1m",
|
1242
|
+
# "data": [[Object]]
|
1243
|
+
# }
|
1244
|
+
# }
|
1245
|
+
# ticker
|
1246
|
+
# {
|
1247
|
+
# "info":{
|
1248
|
+
# "instrument_name":"BTC_USDT",
|
1249
|
+
# "subscription":"ticker.BTC_USDT",
|
1250
|
+
# "channel":"ticker",
|
1251
|
+
# "data":[{}]
|
1252
|
+
#
|
1253
|
+
# handle unsubscribe
|
1254
|
+
# {"id":1725448572836,"method":"unsubscribe","code":0}
|
1255
|
+
#
|
1256
|
+
if self.handle_error_message(client, message):
|
1257
|
+
return
|
1258
|
+
method = self.safe_string(message, 'method')
|
1259
|
+
methods: dict = {
|
1260
|
+
'': self.handle_ping,
|
1261
|
+
'public/heartbeat': self.handle_ping,
|
1262
|
+
'public/auth': self.handle_authenticate,
|
1263
|
+
'private/create-order': self.handle_order,
|
1264
|
+
'private/cancel-order': self.handle_order,
|
1265
|
+
'private/cancel-all-orders': self.handle_cancel_all_orders,
|
1266
|
+
'private/close-position': self.handle_order,
|
1267
|
+
'subscribe': self.handle_subscribe,
|
1268
|
+
'unsubscribe': self.handle_unsubscribe,
|
1269
|
+
}
|
1270
|
+
callMethod = self.safe_value(methods, method)
|
1271
|
+
if callMethod is not None:
|
1272
|
+
callMethod(client, message)
|
1273
|
+
|
1274
|
+
async def authenticate(self, params={}):
|
1275
|
+
self.check_required_credentials()
|
1276
|
+
url = self.urls['api']['ws']['private']
|
1277
|
+
client = self.client(url)
|
1278
|
+
messageHash = 'authenticated'
|
1279
|
+
future = client.future(messageHash)
|
1280
|
+
authenticated = self.safe_value(client.subscriptions, messageHash)
|
1281
|
+
if authenticated is None:
|
1282
|
+
method = 'public/auth'
|
1283
|
+
nonce = str(self.nonce())
|
1284
|
+
auth = method + nonce + self.apiKey + nonce
|
1285
|
+
signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
|
1286
|
+
request: dict = {
|
1287
|
+
'id': nonce,
|
1288
|
+
'nonce': nonce,
|
1289
|
+
'method': method,
|
1290
|
+
'api_key': self.apiKey,
|
1291
|
+
'sig': signature,
|
1292
|
+
}
|
1293
|
+
message = self.extend(request, params)
|
1294
|
+
self.watch(url, messageHash, message, messageHash)
|
1295
|
+
return await future
|
1296
|
+
|
1297
|
+
def handle_ping(self, client: Client, message):
|
1298
|
+
self.spawn(self.pong, client, message)
|
1299
|
+
|
1300
|
+
def handle_authenticate(self, client: Client, message):
|
1301
|
+
#
|
1302
|
+
# {id: 1648132625434, method: "public/auth", code: 0}
|
1303
|
+
#
|
1304
|
+
future = self.safe_value(client.futures, 'authenticated')
|
1305
|
+
future.resolve(True)
|
1306
|
+
|
1307
|
+
def handle_unsubscribe(self, client: Client, message):
|
1308
|
+
id = self.safe_string(message, 'id')
|
1309
|
+
keys = list(client.subscriptions.keys())
|
1310
|
+
for i in range(0, len(keys)):
|
1311
|
+
messageHash = keys[i]
|
1312
|
+
if not (messageHash in client.subscriptions):
|
1313
|
+
continue
|
1314
|
+
# the previous iteration can have deleted the messageHash from the subscriptions
|
1315
|
+
if messageHash.startswith('unsubscribe'):
|
1316
|
+
subscription = client.subscriptions[messageHash]
|
1317
|
+
subId = self.safe_string(subscription, 'id')
|
1318
|
+
if id != subId:
|
1319
|
+
continue
|
1320
|
+
messageHashes = self.safe_list(subscription, 'messageHashes', [])
|
1321
|
+
subMessageHashes = self.safe_list(subscription, 'subMessageHashes', [])
|
1322
|
+
for j in range(0, len(messageHashes)):
|
1323
|
+
unsubHash = messageHashes[j]
|
1324
|
+
subHash = subMessageHashes[j]
|
1325
|
+
self.clean_unsubscription(client, subHash, unsubHash)
|
1326
|
+
self.clean_cache(subscription)
|