gate-io-api 0.0.6__py3-none-any.whl → 0.0.8__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.
Potentially problematic release.
This version of gate-io-api might be problematic. Click here for more details.
- {gate_io_api-0.0.6.dist-info → gate_io_api-0.0.8.dist-info}/METADATA +33 -14
- gate_io_api-0.0.8.dist-info/RECORD +3 -0
- gate_io_api/__init__.py +0 -7
- gate_io_api/ccxt/__init__.py +0 -101
- gate_io_api/ccxt/abstract/gate.py +0 -284
- gate_io_api/ccxt/async_support/__init__.py +0 -80
- gate_io_api/ccxt/async_support/base/__init__.py +0 -1
- gate_io_api/ccxt/async_support/base/exchange.py +0 -2100
- gate_io_api/ccxt/async_support/base/throttler.py +0 -50
- gate_io_api/ccxt/async_support/base/ws/__init__.py +0 -38
- gate_io_api/ccxt/async_support/base/ws/aiohttp_client.py +0 -147
- gate_io_api/ccxt/async_support/base/ws/cache.py +0 -213
- gate_io_api/ccxt/async_support/base/ws/client.py +0 -214
- gate_io_api/ccxt/async_support/base/ws/fast_client.py +0 -97
- gate_io_api/ccxt/async_support/base/ws/functions.py +0 -59
- gate_io_api/ccxt/async_support/base/ws/future.py +0 -69
- gate_io_api/ccxt/async_support/base/ws/order_book.py +0 -78
- gate_io_api/ccxt/async_support/base/ws/order_book_side.py +0 -174
- gate_io_api/ccxt/async_support/gate.py +0 -7739
- gate_io_api/ccxt/base/__init__.py +0 -27
- gate_io_api/ccxt/base/decimal_to_precision.py +0 -174
- gate_io_api/ccxt/base/errors.py +0 -267
- gate_io_api/ccxt/base/exchange.py +0 -6770
- gate_io_api/ccxt/base/precise.py +0 -297
- gate_io_api/ccxt/base/types.py +0 -577
- gate_io_api/ccxt/gate.py +0 -7738
- gate_io_api/ccxt/pro/__init__.py +0 -21
- gate_io_api/ccxt/pro/gate.py +0 -1950
- gate_io_api/ccxt/static_dependencies/README.md +0 -1
- gate_io_api/ccxt/static_dependencies/__init__.py +0 -1
- gate_io_api/ccxt/static_dependencies/ecdsa/__init__.py +0 -14
- gate_io_api/ccxt/static_dependencies/ecdsa/_version.py +0 -520
- gate_io_api/ccxt/static_dependencies/ecdsa/curves.py +0 -56
- gate_io_api/ccxt/static_dependencies/ecdsa/der.py +0 -221
- gate_io_api/ccxt/static_dependencies/ecdsa/ecdsa.py +0 -310
- gate_io_api/ccxt/static_dependencies/ecdsa/ellipticcurve.py +0 -197
- gate_io_api/ccxt/static_dependencies/ecdsa/keys.py +0 -332
- gate_io_api/ccxt/static_dependencies/ecdsa/numbertheory.py +0 -531
- gate_io_api/ccxt/static_dependencies/ecdsa/rfc6979.py +0 -100
- gate_io_api/ccxt/static_dependencies/ecdsa/util.py +0 -266
- gate_io_api/ccxt/static_dependencies/ethereum/__init__.py +0 -7
- gate_io_api/ccxt/static_dependencies/ethereum/abi/__init__.py +0 -16
- gate_io_api/ccxt/static_dependencies/ethereum/abi/abi.py +0 -19
- gate_io_api/ccxt/static_dependencies/ethereum/abi/base.py +0 -152
- gate_io_api/ccxt/static_dependencies/ethereum/abi/codec.py +0 -217
- gate_io_api/ccxt/static_dependencies/ethereum/abi/constants.py +0 -3
- gate_io_api/ccxt/static_dependencies/ethereum/abi/decoding.py +0 -565
- gate_io_api/ccxt/static_dependencies/ethereum/abi/encoding.py +0 -720
- gate_io_api/ccxt/static_dependencies/ethereum/abi/exceptions.py +0 -139
- gate_io_api/ccxt/static_dependencies/ethereum/abi/grammar.py +0 -443
- gate_io_api/ccxt/static_dependencies/ethereum/abi/packed.py +0 -13
- gate_io_api/ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
- gate_io_api/ccxt/static_dependencies/ethereum/abi/registry.py +0 -643
- gate_io_api/ccxt/static_dependencies/ethereum/abi/tools/__init__.py +0 -3
- gate_io_api/ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +0 -230
- gate_io_api/ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/ethereum/abi/utils/numeric.py +0 -83
- gate_io_api/ccxt/static_dependencies/ethereum/abi/utils/padding.py +0 -27
- gate_io_api/ccxt/static_dependencies/ethereum/abi/utils/string.py +0 -19
- gate_io_api/ccxt/static_dependencies/ethereum/account/__init__.py +0 -3
- gate_io_api/ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +0 -4
- gate_io_api/ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +0 -239
- gate_io_api/ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +0 -40
- gate_io_api/ccxt/static_dependencies/ethereum/account/messages.py +0 -263
- gate_io_api/ccxt/static_dependencies/ethereum/account/py.typed +0 -0
- gate_io_api/ccxt/static_dependencies/ethereum/hexbytes/__init__.py +0 -5
- gate_io_api/ccxt/static_dependencies/ethereum/hexbytes/_utils.py +0 -54
- gate_io_api/ccxt/static_dependencies/ethereum/hexbytes/main.py +0 -65
- gate_io_api/ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
- gate_io_api/ccxt/static_dependencies/ethereum/typing/__init__.py +0 -63
- gate_io_api/ccxt/static_dependencies/ethereum/typing/abi.py +0 -6
- gate_io_api/ccxt/static_dependencies/ethereum/typing/bls.py +0 -7
- gate_io_api/ccxt/static_dependencies/ethereum/typing/discovery.py +0 -5
- gate_io_api/ccxt/static_dependencies/ethereum/typing/encoding.py +0 -7
- gate_io_api/ccxt/static_dependencies/ethereum/typing/enums.py +0 -17
- gate_io_api/ccxt/static_dependencies/ethereum/typing/ethpm.py +0 -9
- gate_io_api/ccxt/static_dependencies/ethereum/typing/evm.py +0 -20
- gate_io_api/ccxt/static_dependencies/ethereum/typing/networks.py +0 -1122
- gate_io_api/ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
- gate_io_api/ccxt/static_dependencies/ethereum/utils/__init__.py +0 -115
- gate_io_api/ccxt/static_dependencies/ethereum/utils/abi.py +0 -72
- gate_io_api/ccxt/static_dependencies/ethereum/utils/address.py +0 -171
- gate_io_api/ccxt/static_dependencies/ethereum/utils/applicators.py +0 -151
- gate_io_api/ccxt/static_dependencies/ethereum/utils/conversions.py +0 -190
- gate_io_api/ccxt/static_dependencies/ethereum/utils/currency.py +0 -107
- gate_io_api/ccxt/static_dependencies/ethereum/utils/curried/__init__.py +0 -269
- gate_io_api/ccxt/static_dependencies/ethereum/utils/debug.py +0 -20
- gate_io_api/ccxt/static_dependencies/ethereum/utils/decorators.py +0 -132
- gate_io_api/ccxt/static_dependencies/ethereum/utils/encoding.py +0 -6
- gate_io_api/ccxt/static_dependencies/ethereum/utils/exceptions.py +0 -4
- gate_io_api/ccxt/static_dependencies/ethereum/utils/functional.py +0 -75
- gate_io_api/ccxt/static_dependencies/ethereum/utils/hexadecimal.py +0 -74
- gate_io_api/ccxt/static_dependencies/ethereum/utils/humanize.py +0 -188
- gate_io_api/ccxt/static_dependencies/ethereum/utils/logging.py +0 -159
- gate_io_api/ccxt/static_dependencies/ethereum/utils/module_loading.py +0 -31
- gate_io_api/ccxt/static_dependencies/ethereum/utils/numeric.py +0 -43
- gate_io_api/ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
- gate_io_api/ccxt/static_dependencies/ethereum/utils/toolz.py +0 -76
- gate_io_api/ccxt/static_dependencies/ethereum/utils/types.py +0 -54
- gate_io_api/ccxt/static_dependencies/ethereum/utils/typing/__init__.py +0 -18
- gate_io_api/ccxt/static_dependencies/ethereum/utils/typing/misc.py +0 -14
- gate_io_api/ccxt/static_dependencies/ethereum/utils/units.py +0 -31
- gate_io_api/ccxt/static_dependencies/keccak/__init__.py +0 -3
- gate_io_api/ccxt/static_dependencies/keccak/keccak.py +0 -197
- gate_io_api/ccxt/static_dependencies/lark/__init__.py +0 -38
- gate_io_api/ccxt/static_dependencies/lark/__pyinstaller/__init__.py +0 -6
- gate_io_api/ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +0 -14
- gate_io_api/ccxt/static_dependencies/lark/ast_utils.py +0 -59
- gate_io_api/ccxt/static_dependencies/lark/common.py +0 -86
- gate_io_api/ccxt/static_dependencies/lark/exceptions.py +0 -292
- gate_io_api/ccxt/static_dependencies/lark/grammar.py +0 -130
- gate_io_api/ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/lark/grammars/common.lark +0 -59
- gate_io_api/ccxt/static_dependencies/lark/grammars/lark.lark +0 -62
- gate_io_api/ccxt/static_dependencies/lark/grammars/python.lark +0 -302
- gate_io_api/ccxt/static_dependencies/lark/grammars/unicode.lark +0 -7
- gate_io_api/ccxt/static_dependencies/lark/indenter.py +0 -143
- gate_io_api/ccxt/static_dependencies/lark/lark.py +0 -658
- gate_io_api/ccxt/static_dependencies/lark/lexer.py +0 -678
- gate_io_api/ccxt/static_dependencies/lark/load_grammar.py +0 -1428
- gate_io_api/ccxt/static_dependencies/lark/parse_tree_builder.py +0 -391
- gate_io_api/ccxt/static_dependencies/lark/parser_frontends.py +0 -257
- gate_io_api/ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/lark/parsers/cyk.py +0 -340
- gate_io_api/ccxt/static_dependencies/lark/parsers/earley.py +0 -314
- gate_io_api/ccxt/static_dependencies/lark/parsers/earley_common.py +0 -42
- gate_io_api/ccxt/static_dependencies/lark/parsers/earley_forest.py +0 -801
- gate_io_api/ccxt/static_dependencies/lark/parsers/grammar_analysis.py +0 -203
- gate_io_api/ccxt/static_dependencies/lark/parsers/lalr_analysis.py +0 -332
- gate_io_api/ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +0 -158
- gate_io_api/ccxt/static_dependencies/lark/parsers/lalr_parser.py +0 -122
- gate_io_api/ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +0 -110
- gate_io_api/ccxt/static_dependencies/lark/parsers/xearley.py +0 -165
- gate_io_api/ccxt/static_dependencies/lark/py.typed +0 -0
- gate_io_api/ccxt/static_dependencies/lark/reconstruct.py +0 -107
- gate_io_api/ccxt/static_dependencies/lark/tools/__init__.py +0 -70
- gate_io_api/ccxt/static_dependencies/lark/tools/nearley.py +0 -202
- gate_io_api/ccxt/static_dependencies/lark/tools/serialize.py +0 -32
- gate_io_api/ccxt/static_dependencies/lark/tools/standalone.py +0 -196
- gate_io_api/ccxt/static_dependencies/lark/tree.py +0 -267
- gate_io_api/ccxt/static_dependencies/lark/tree_matcher.py +0 -186
- gate_io_api/ccxt/static_dependencies/lark/tree_templates.py +0 -180
- gate_io_api/ccxt/static_dependencies/lark/utils.py +0 -343
- gate_io_api/ccxt/static_dependencies/lark/visitors.py +0 -596
- gate_io_api/ccxt/static_dependencies/marshmallow/__init__.py +0 -81
- gate_io_api/ccxt/static_dependencies/marshmallow/base.py +0 -65
- gate_io_api/ccxt/static_dependencies/marshmallow/class_registry.py +0 -94
- gate_io_api/ccxt/static_dependencies/marshmallow/decorators.py +0 -231
- gate_io_api/ccxt/static_dependencies/marshmallow/error_store.py +0 -60
- gate_io_api/ccxt/static_dependencies/marshmallow/exceptions.py +0 -71
- gate_io_api/ccxt/static_dependencies/marshmallow/fields.py +0 -2114
- gate_io_api/ccxt/static_dependencies/marshmallow/orderedset.py +0 -89
- gate_io_api/ccxt/static_dependencies/marshmallow/py.typed +0 -0
- gate_io_api/ccxt/static_dependencies/marshmallow/schema.py +0 -1228
- gate_io_api/ccxt/static_dependencies/marshmallow/types.py +0 -12
- gate_io_api/ccxt/static_dependencies/marshmallow/utils.py +0 -378
- gate_io_api/ccxt/static_dependencies/marshmallow/validate.py +0 -678
- gate_io_api/ccxt/static_dependencies/marshmallow/warnings.py +0 -2
- gate_io_api/ccxt/static_dependencies/marshmallow_dataclass/__init__.py +0 -1047
- gate_io_api/ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +0 -51
- gate_io_api/ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +0 -45
- gate_io_api/ccxt/static_dependencies/marshmallow_dataclass/mypy.py +0 -71
- gate_io_api/ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- gate_io_api/ccxt/static_dependencies/marshmallow_dataclass/typing.py +0 -14
- gate_io_api/ccxt/static_dependencies/marshmallow_dataclass/union_field.py +0 -82
- gate_io_api/ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +0 -1
- gate_io_api/ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +0 -193
- gate_io_api/ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- gate_io_api/ccxt/static_dependencies/msgpack/__init__.py +0 -55
- gate_io_api/ccxt/static_dependencies/msgpack/_cmsgpack.pyx +0 -11
- gate_io_api/ccxt/static_dependencies/msgpack/_packer.pyx +0 -374
- gate_io_api/ccxt/static_dependencies/msgpack/_unpacker.pyx +0 -547
- gate_io_api/ccxt/static_dependencies/msgpack/buff_converter.h +0 -8
- gate_io_api/ccxt/static_dependencies/msgpack/exceptions.py +0 -48
- gate_io_api/ccxt/static_dependencies/msgpack/ext.py +0 -168
- gate_io_api/ccxt/static_dependencies/msgpack/fallback.py +0 -951
- gate_io_api/ccxt/static_dependencies/msgpack/pack.h +0 -89
- gate_io_api/ccxt/static_dependencies/msgpack/pack_template.h +0 -820
- gate_io_api/ccxt/static_dependencies/msgpack/sysdep.h +0 -194
- gate_io_api/ccxt/static_dependencies/msgpack/unpack.h +0 -391
- gate_io_api/ccxt/static_dependencies/msgpack/unpack_define.h +0 -95
- gate_io_api/ccxt/static_dependencies/msgpack/unpack_template.h +0 -464
- gate_io_api/ccxt/static_dependencies/parsimonious/__init__.py +0 -10
- gate_io_api/ccxt/static_dependencies/parsimonious/exceptions.py +0 -105
- gate_io_api/ccxt/static_dependencies/parsimonious/expressions.py +0 -479
- gate_io_api/ccxt/static_dependencies/parsimonious/grammar.py +0 -487
- gate_io_api/ccxt/static_dependencies/parsimonious/nodes.py +0 -325
- gate_io_api/ccxt/static_dependencies/parsimonious/utils.py +0 -40
- gate_io_api/ccxt/static_dependencies/starknet/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/starknet/abi/v0/__init__.py +0 -2
- gate_io_api/ccxt/static_dependencies/starknet/abi/v0/model.py +0 -44
- gate_io_api/ccxt/static_dependencies/starknet/abi/v0/parser.py +0 -216
- gate_io_api/ccxt/static_dependencies/starknet/abi/v0/schemas.py +0 -72
- gate_io_api/ccxt/static_dependencies/starknet/abi/v0/shape.py +0 -63
- gate_io_api/ccxt/static_dependencies/starknet/abi/v1/__init__.py +0 -2
- gate_io_api/ccxt/static_dependencies/starknet/abi/v1/core_structures.json +0 -14
- gate_io_api/ccxt/static_dependencies/starknet/abi/v1/model.py +0 -39
- gate_io_api/ccxt/static_dependencies/starknet/abi/v1/parser.py +0 -220
- gate_io_api/ccxt/static_dependencies/starknet/abi/v1/parser_transformer.py +0 -179
- gate_io_api/ccxt/static_dependencies/starknet/abi/v1/schemas.py +0 -66
- gate_io_api/ccxt/static_dependencies/starknet/abi/v1/shape.py +0 -47
- gate_io_api/ccxt/static_dependencies/starknet/abi/v2/__init__.py +0 -2
- gate_io_api/ccxt/static_dependencies/starknet/abi/v2/model.py +0 -89
- gate_io_api/ccxt/static_dependencies/starknet/abi/v2/parser.py +0 -293
- gate_io_api/ccxt/static_dependencies/starknet/abi/v2/parser_transformer.py +0 -192
- gate_io_api/ccxt/static_dependencies/starknet/abi/v2/schemas.py +0 -132
- gate_io_api/ccxt/static_dependencies/starknet/abi/v2/shape.py +0 -107
- gate_io_api/ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/starknet/cairo/data_types.py +0 -123
- gate_io_api/ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +0 -77
- gate_io_api/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +0 -46
- gate_io_api/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +0 -138
- gate_io_api/ccxt/static_dependencies/starknet/cairo/felt.py +0 -64
- gate_io_api/ccxt/static_dependencies/starknet/cairo/type_parser.py +0 -121
- gate_io_api/ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +0 -59
- gate_io_api/ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +0 -77
- gate_io_api/ccxt/static_dependencies/starknet/ccxt_utils.py +0 -7
- gate_io_api/ccxt/static_dependencies/starknet/common.py +0 -15
- gate_io_api/ccxt/static_dependencies/starknet/constants.py +0 -39
- gate_io_api/ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/starknet/hash/address.py +0 -79
- gate_io_api/ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +0 -111
- gate_io_api/ccxt/static_dependencies/starknet/hash/selector.py +0 -16
- gate_io_api/ccxt/static_dependencies/starknet/hash/storage.py +0 -12
- gate_io_api/ccxt/static_dependencies/starknet/hash/utils.py +0 -78
- gate_io_api/ccxt/static_dependencies/starknet/models/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/starknet/models/typed_data.py +0 -45
- gate_io_api/ccxt/static_dependencies/starknet/serialization/__init__.py +0 -24
- gate_io_api/ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +0 -40
- gate_io_api/ccxt/static_dependencies/starknet/serialization/_context.py +0 -142
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +0 -10
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +0 -82
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +0 -43
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +0 -37
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +0 -66
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +0 -71
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +0 -71
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +0 -50
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +0 -58
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +0 -43
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +0 -40
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +0 -72
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +0 -36
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +0 -36
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +0 -76
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +0 -100
- gate_io_api/ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +0 -32
- gate_io_api/ccxt/static_dependencies/starknet/serialization/errors.py +0 -10
- gate_io_api/ccxt/static_dependencies/starknet/serialization/factory.py +0 -229
- gate_io_api/ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +0 -110
- gate_io_api/ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +0 -59
- gate_io_api/ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +0 -86
- gate_io_api/ccxt/static_dependencies/starknet/utils/iterable.py +0 -13
- gate_io_api/ccxt/static_dependencies/starknet/utils/schema.py +0 -13
- gate_io_api/ccxt/static_dependencies/starknet/utils/typed_data.py +0 -182
- gate_io_api/ccxt/static_dependencies/starkware/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +0 -50
- gate_io_api/ccxt/static_dependencies/starkware/crypto/math_utils.py +0 -78
- gate_io_api/ccxt/static_dependencies/starkware/crypto/signature.py +0 -2344
- gate_io_api/ccxt/static_dependencies/starkware/crypto/utils.py +0 -63
- gate_io_api/ccxt/static_dependencies/sympy/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/sympy/core/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/sympy/core/intfunc.py +0 -35
- gate_io_api/ccxt/static_dependencies/sympy/external/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/sympy/external/gmpy.py +0 -345
- gate_io_api/ccxt/static_dependencies/sympy/external/importtools.py +0 -187
- gate_io_api/ccxt/static_dependencies/sympy/external/ntheory.py +0 -637
- gate_io_api/ccxt/static_dependencies/sympy/external/pythonmpq.py +0 -341
- gate_io_api/ccxt/static_dependencies/toolz/__init__.py +0 -26
- gate_io_api/ccxt/static_dependencies/toolz/_signatures.py +0 -784
- gate_io_api/ccxt/static_dependencies/toolz/_version.py +0 -520
- gate_io_api/ccxt/static_dependencies/toolz/compatibility.py +0 -30
- gate_io_api/ccxt/static_dependencies/toolz/curried/__init__.py +0 -101
- gate_io_api/ccxt/static_dependencies/toolz/curried/exceptions.py +0 -22
- gate_io_api/ccxt/static_dependencies/toolz/curried/operator.py +0 -22
- gate_io_api/ccxt/static_dependencies/toolz/dicttoolz.py +0 -339
- gate_io_api/ccxt/static_dependencies/toolz/functoolz.py +0 -1049
- gate_io_api/ccxt/static_dependencies/toolz/itertoolz.py +0 -1057
- gate_io_api/ccxt/static_dependencies/toolz/recipes.py +0 -46
- gate_io_api/ccxt/static_dependencies/toolz/utils.py +0 -9
- gate_io_api/ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
- gate_io_api/ccxt/static_dependencies/typing_inspect/typing_inspect.py +0 -851
- gate_io_api-0.0.6.dist-info/RECORD +0 -288
- {gate_io_api-0.0.6.dist-info → gate_io_api-0.0.8.dist-info}/WHEEL +0 -0
gate_io_api/ccxt/pro/gate.py
DELETED
|
@@ -1,1950 +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, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
|
|
8
|
-
import hashlib
|
|
9
|
-
from ccxt.base.types import Any, Balances, Int, Liquidation, Market, MarketType, Num, Order, OrderBook, OrderRequest, 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 ArgumentsRequired
|
|
15
|
-
from ccxt.base.errors import BadRequest
|
|
16
|
-
from ccxt.base.errors import NotSupported
|
|
17
|
-
from ccxt.base.errors import ChecksumError
|
|
18
|
-
from ccxt.base.precise import Precise
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
from ccxt.async_support import gate as gateAsync
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class gate(gateAsync):
|
|
25
|
-
|
|
26
|
-
def describe(self) -> Any:
|
|
27
|
-
return self.deep_extend(super(gate, self).describe(), {
|
|
28
|
-
'has': {
|
|
29
|
-
'ws': True,
|
|
30
|
-
'cancelAllOrdersWs': True,
|
|
31
|
-
'cancelOrderWs': True,
|
|
32
|
-
'createMarketBuyOrderWithCostWs': True,
|
|
33
|
-
'createMarketOrderWs': True,
|
|
34
|
-
'createMarketOrderWithCostWs': False,
|
|
35
|
-
'createMarketSellOrderWithCostWs': False,
|
|
36
|
-
'createOrderWs': True,
|
|
37
|
-
'createOrdersWs': True,
|
|
38
|
-
'createPostOnlyOrderWs': True,
|
|
39
|
-
'createReduceOnlyOrderWs': True,
|
|
40
|
-
'createStopLimitOrderWs': True,
|
|
41
|
-
'createStopLossOrderWs': True,
|
|
42
|
-
'createStopMarketOrderWs': False,
|
|
43
|
-
'createStopOrderWs': True,
|
|
44
|
-
'createTakeProfitOrderWs': True,
|
|
45
|
-
'createTriggerOrderWs': True,
|
|
46
|
-
'editOrderWs': True,
|
|
47
|
-
'fetchOrderWs': True,
|
|
48
|
-
'fetchOrdersWs': False,
|
|
49
|
-
'fetchOpenOrdersWs': True,
|
|
50
|
-
'fetchClosedOrdersWs': True,
|
|
51
|
-
'watchOrderBook': True,
|
|
52
|
-
'watchBidsAsks': True,
|
|
53
|
-
'watchTicker': True,
|
|
54
|
-
'watchTickers': True,
|
|
55
|
-
'watchTrades': True,
|
|
56
|
-
'watchTradesForSymbols': True,
|
|
57
|
-
'watchMyTrades': True,
|
|
58
|
-
'watchOHLCV': True,
|
|
59
|
-
'watchBalance': True,
|
|
60
|
-
'watchOrders': True,
|
|
61
|
-
'watchLiquidations': False,
|
|
62
|
-
'watchLiquidationsForSymbols': False,
|
|
63
|
-
'watchMyLiquidations': True,
|
|
64
|
-
'watchMyLiquidationsForSymbols': True,
|
|
65
|
-
'watchPositions': True,
|
|
66
|
-
},
|
|
67
|
-
'urls': {
|
|
68
|
-
'api': {
|
|
69
|
-
'ws': 'wss://ws.gate.io/v4',
|
|
70
|
-
'spot': 'wss://api.gateio.ws/ws/v4/',
|
|
71
|
-
'swap': {
|
|
72
|
-
'usdt': 'wss://fx-ws.gateio.ws/v4/ws/usdt',
|
|
73
|
-
'btc': 'wss://fx-ws.gateio.ws/v4/ws/btc',
|
|
74
|
-
},
|
|
75
|
-
'future': {
|
|
76
|
-
'usdt': 'wss://fx-ws.gateio.ws/v4/ws/delivery/usdt',
|
|
77
|
-
'btc': 'wss://fx-ws.gateio.ws/v4/ws/delivery/btc',
|
|
78
|
-
},
|
|
79
|
-
'option': {
|
|
80
|
-
'usdt': 'wss://op-ws.gateio.live/v4/ws/usdt',
|
|
81
|
-
'btc': 'wss://op-ws.gateio.live/v4/ws/btc',
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
'test': {
|
|
85
|
-
'swap': {
|
|
86
|
-
'usdt': 'wss://fx-ws-testnet.gateio.ws/v4/ws/usdt',
|
|
87
|
-
'btc': 'wss://fx-ws-testnet.gateio.ws/v4/ws/btc',
|
|
88
|
-
},
|
|
89
|
-
'future': {
|
|
90
|
-
'usdt': 'wss://fx-ws-testnet.gateio.ws/v4/ws/usdt',
|
|
91
|
-
'btc': 'wss://fx-ws-testnet.gateio.ws/v4/ws/btc',
|
|
92
|
-
},
|
|
93
|
-
'option': {
|
|
94
|
-
'usdt': 'wss://op-ws-testnet.gateio.live/v4/ws/usdt',
|
|
95
|
-
'btc': 'wss://op-ws-testnet.gateio.live/v4/ws/btc',
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
'options': {
|
|
100
|
-
'tradesLimit': 1000,
|
|
101
|
-
'OHLCVLimit': 1000,
|
|
102
|
-
'watchTradesSubscriptions': {},
|
|
103
|
-
'watchTickerSubscriptions': {},
|
|
104
|
-
'watchOrderBookSubscriptions': {},
|
|
105
|
-
'watchTicker': {
|
|
106
|
-
'name': 'tickers', # or book_ticker
|
|
107
|
-
},
|
|
108
|
-
'watchOrderBook': {
|
|
109
|
-
'interval': '100ms',
|
|
110
|
-
'snapshotDelay': 10, # how many deltas to cache before fetching a snapshot
|
|
111
|
-
'snapshotMaxRetries': 3,
|
|
112
|
-
'checksum': True,
|
|
113
|
-
},
|
|
114
|
-
'watchBalance': {
|
|
115
|
-
'settle': 'usdt', # or btc
|
|
116
|
-
'spot': 'spot.balances', # spot.margin_balances, spot.funding_balances or spot.cross_balances
|
|
117
|
-
},
|
|
118
|
-
'watchPositions': {
|
|
119
|
-
'fetchPositionsSnapshot': True, # or False
|
|
120
|
-
'awaitPositionsSnapshot': True, # whether to wait for the positions snapshot before providing updates
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
'exceptions': {
|
|
124
|
-
'ws': {
|
|
125
|
-
'exact': {
|
|
126
|
-
'1': BadRequest,
|
|
127
|
-
'2': BadRequest,
|
|
128
|
-
'4': AuthenticationError,
|
|
129
|
-
'6': AuthenticationError,
|
|
130
|
-
'11': AuthenticationError,
|
|
131
|
-
},
|
|
132
|
-
'broad': {},
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
|
138
|
-
"""
|
|
139
|
-
|
|
140
|
-
https://www.gate.io/docs/developers/apiv4/ws/en/#order-place
|
|
141
|
-
https://www.gate.io/docs/developers/futures/ws/en/#order-place
|
|
142
|
-
|
|
143
|
-
Create an order on the exchange
|
|
144
|
-
:param str symbol: Unified CCXT market symbol
|
|
145
|
-
:param str type: 'limit' or 'market' *"market" is contract only*
|
|
146
|
-
:param str side: 'buy' or 'sell'
|
|
147
|
-
:param float amount: the amount of currency to trade
|
|
148
|
-
:param float [price]: *ignored in "market" orders* the price at which the order is to be fulfilled at in units of the quote currency
|
|
149
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
150
|
-
:param float [params.stopPrice]: The price at which a trigger order is triggered at
|
|
151
|
-
:param str [params.timeInForce]: "GTC", "IOC", or "PO"
|
|
152
|
-
:param float [params.stopLossPrice]: The price at which a stop loss order is triggered at
|
|
153
|
-
:param float [params.takeProfitPrice]: The price at which a take profit order is triggered at
|
|
154
|
-
:param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
|
|
155
|
-
:param int [params.iceberg]: Amount to display for the iceberg order, Null or 0 for normal orders, Set to -1 to hide the order completely
|
|
156
|
-
:param str [params.text]: User defined information
|
|
157
|
-
:param str [params.account]: *spot and margin only* "spot", "margin" or "cross_margin"
|
|
158
|
-
:param bool [params.auto_borrow]: *margin only* Used in margin or cross margin trading to allow automatic loan of insufficient amount if balance is not enough
|
|
159
|
-
:param str [params.settle]: *contract only* Unified Currency Code for settle currency
|
|
160
|
-
:param bool [params.reduceOnly]: *contract only* Indicates if self order is to reduce the size of a position
|
|
161
|
-
:param bool [params.close]: *contract only* Set to close the position, with size set to 0
|
|
162
|
-
:param bool [params.auto_size]: *contract only* Set side to close dual-mode position, close_long closes the long side, while close_short the short one, size also needs to be set to 0
|
|
163
|
-
:param int [params.price_type]: *contract only* 0 latest deal price, 1 mark price, 2 index price
|
|
164
|
-
:param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
|
|
165
|
-
:returns dict|None: `An order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
166
|
-
"""
|
|
167
|
-
await self.load_markets()
|
|
168
|
-
market = self.market(symbol)
|
|
169
|
-
symbol = market['symbol']
|
|
170
|
-
messageType = self.get_type_by_market(market)
|
|
171
|
-
channel = messageType + '.order_place'
|
|
172
|
-
url = self.get_url_by_market(market)
|
|
173
|
-
params['textIsRequired'] = True
|
|
174
|
-
request = self.create_order_request(symbol, type, side, amount, price, params)
|
|
175
|
-
await self.authenticate(url, messageType)
|
|
176
|
-
rawOrder = await self.request_private(url, request, channel)
|
|
177
|
-
order = self.parse_order(rawOrder, market)
|
|
178
|
-
return order
|
|
179
|
-
|
|
180
|
-
async def create_orders_ws(self, orders: List[OrderRequest], params={}):
|
|
181
|
-
"""
|
|
182
|
-
create a list of trade orders
|
|
183
|
-
|
|
184
|
-
https://www.gate.io/docs/developers/futures/ws/en/#order-batch-place
|
|
185
|
-
|
|
186
|
-
:param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
|
|
187
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
188
|
-
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
189
|
-
"""
|
|
190
|
-
await self.load_markets()
|
|
191
|
-
request = self.createOrdersRequest(orders, params)
|
|
192
|
-
firstOrder = orders[0]
|
|
193
|
-
market = self.market(firstOrder['symbol'])
|
|
194
|
-
if market['swap'] is not True:
|
|
195
|
-
raise NotSupported(self.id + ' createOrdersWs is not supported for swap markets')
|
|
196
|
-
messageType = self.get_type_by_market(market)
|
|
197
|
-
channel = messageType + '.order_batch_place'
|
|
198
|
-
url = self.get_url_by_market(market)
|
|
199
|
-
await self.authenticate(url, messageType)
|
|
200
|
-
rawOrders = await self.request_private(url, request, channel)
|
|
201
|
-
return self.parse_orders(rawOrders, market)
|
|
202
|
-
|
|
203
|
-
async def cancel_all_orders_ws(self, symbol: Str = None, params={}):
|
|
204
|
-
"""
|
|
205
|
-
cancel all open orders
|
|
206
|
-
|
|
207
|
-
https://www.gate.io/docs/developers/futures/ws/en/#cancel-all-open-orders-matched
|
|
208
|
-
https://www.gate.io/docs/developers/apiv4/ws/en/#order-cancel-all-with-specified-currency-pair
|
|
209
|
-
|
|
210
|
-
:param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
|
|
211
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
212
|
-
:param str [params.channel]: the channel to use, defaults to spot.order_cancel_cp or futures.order_cancel_cp
|
|
213
|
-
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
214
|
-
"""
|
|
215
|
-
await self.load_markets()
|
|
216
|
-
market = None if (symbol is None) else self.market(symbol)
|
|
217
|
-
trigger = self.safe_bool_2(params, 'stop', 'trigger')
|
|
218
|
-
messageType = self.get_type_by_market(market)
|
|
219
|
-
channel = messageType + '.order_cancel_cp'
|
|
220
|
-
channel, params = self.handle_option_and_params(params, 'cancelAllOrdersWs', 'channel', channel)
|
|
221
|
-
url = self.get_url_by_market(market)
|
|
222
|
-
params = self.omit(params, ['stop', 'trigger'])
|
|
223
|
-
type, query = self.handle_market_type_and_params('cancelAllOrders', market, params)
|
|
224
|
-
request, requestParams = self.multiOrderSpotPrepareRequest(market, trigger, query) if (type == 'spot') else self.prepareRequest(market, type, query)
|
|
225
|
-
await self.authenticate(url, messageType)
|
|
226
|
-
rawOrders = await self.request_private(url, self.extend(request, requestParams), channel)
|
|
227
|
-
return self.parse_orders(rawOrders, market)
|
|
228
|
-
|
|
229
|
-
async def cancel_order_ws(self, id: str, symbol: Str = None, params={}):
|
|
230
|
-
"""
|
|
231
|
-
Cancels an open order
|
|
232
|
-
|
|
233
|
-
https://www.gate.io/docs/developers/apiv4/ws/en/#order-cancel
|
|
234
|
-
https://www.gate.io/docs/developers/futures/ws/en/#order-cancel
|
|
235
|
-
|
|
236
|
-
:param str id: Order id
|
|
237
|
-
:param str symbol: Unified market symbol
|
|
238
|
-
:param dict [params]: Parameters specified by the exchange api
|
|
239
|
-
:param bool [params.trigger]: True if the order to be cancelled is a trigger order
|
|
240
|
-
:returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
241
|
-
"""
|
|
242
|
-
await self.load_markets()
|
|
243
|
-
market = None if (symbol is None) else self.market(symbol)
|
|
244
|
-
trigger = self.safe_value_n(params, ['is_stop_order', 'stop', 'trigger'], False)
|
|
245
|
-
params = self.omit(params, ['is_stop_order', 'stop', 'trigger'])
|
|
246
|
-
type, query = self.handle_market_type_and_params('cancelOrder', market, params)
|
|
247
|
-
request, requestParams = self.spotOrderPrepareRequest(market, trigger, query) if (type == 'spot' or type == 'margin') else self.prepareRequest(market, type, query)
|
|
248
|
-
messageType = self.get_type_by_market(market)
|
|
249
|
-
channel = messageType + '.order_cancel'
|
|
250
|
-
url = self.get_url_by_market(market)
|
|
251
|
-
await self.authenticate(url, messageType)
|
|
252
|
-
request['order_id'] = str(id)
|
|
253
|
-
res = await self.request_private(url, self.extend(request, requestParams), channel)
|
|
254
|
-
return self.parse_order(res, market)
|
|
255
|
-
|
|
256
|
-
async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
|
257
|
-
"""
|
|
258
|
-
edit a trade order, gate currently only supports the modification of the price or amount fields
|
|
259
|
-
|
|
260
|
-
https://www.gate.io/docs/developers/apiv4/ws/en/#order-amend
|
|
261
|
-
https://www.gate.io/docs/developers/futures/ws/en/#order-amend
|
|
262
|
-
|
|
263
|
-
:param str id: order id
|
|
264
|
-
:param str symbol: unified symbol of the market to create an order in
|
|
265
|
-
:param str type: 'market' or 'limit'
|
|
266
|
-
:param str side: 'buy' or 'sell'
|
|
267
|
-
:param float amount: how much of the currency you want to trade in units of the base currency
|
|
268
|
-
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
269
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
270
|
-
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
271
|
-
"""
|
|
272
|
-
await self.load_markets()
|
|
273
|
-
market = self.market(symbol)
|
|
274
|
-
extendedRequest = self.edit_order_request(id, symbol, type, side, amount, price, params)
|
|
275
|
-
messageType = self.get_type_by_market(market)
|
|
276
|
-
channel = messageType + '.order_amend'
|
|
277
|
-
url = self.get_url_by_market(market)
|
|
278
|
-
await self.authenticate(url, messageType)
|
|
279
|
-
rawOrder = await self.request_private(url, extendedRequest, channel)
|
|
280
|
-
return self.parse_order(rawOrder, market)
|
|
281
|
-
|
|
282
|
-
async def fetch_order_ws(self, id: str, symbol: Str = None, params={}):
|
|
283
|
-
"""
|
|
284
|
-
Retrieves information on an order
|
|
285
|
-
|
|
286
|
-
https://www.gate.io/docs/developers/apiv4/ws/en/#order-status
|
|
287
|
-
https://www.gate.io/docs/developers/futures/ws/en/#order-status
|
|
288
|
-
|
|
289
|
-
:param str id: Order id
|
|
290
|
-
:param str symbol: Unified market symbol, *required for spot and margin*
|
|
291
|
-
:param dict [params]: Parameters specified by the exchange api
|
|
292
|
-
:param bool [params.trigger]: True if the order being fetched is a trigger order
|
|
293
|
-
:param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
|
|
294
|
-
:param str [params.type]: 'spot', 'swap', or 'future', if not provided self.options['defaultMarginMode'] is used
|
|
295
|
-
:param str [params.settle]: 'btc' or 'usdt' - settle currency for perpetual swap and future - market settle currency is used if symbol is not None, default="usdt" for swap and "btc" for future
|
|
296
|
-
:returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
297
|
-
"""
|
|
298
|
-
await self.load_markets()
|
|
299
|
-
market = None if (symbol is None) else self.market(symbol)
|
|
300
|
-
request, requestParams = self.fetchOrderRequest(id, symbol, params)
|
|
301
|
-
messageType = self.get_type_by_market(market)
|
|
302
|
-
channel = messageType + '.order_status'
|
|
303
|
-
url = self.get_url_by_market(market)
|
|
304
|
-
await self.authenticate(url, messageType)
|
|
305
|
-
rawOrder = await self.request_private(url, self.extend(request, requestParams), channel)
|
|
306
|
-
return self.parse_order(rawOrder, market)
|
|
307
|
-
|
|
308
|
-
async def fetch_open_orders_ws(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
309
|
-
"""
|
|
310
|
-
fetch all unfilled currently open orders
|
|
311
|
-
|
|
312
|
-
https://www.gate.io/docs/developers/futures/ws/en/#order-list
|
|
313
|
-
|
|
314
|
-
:param str symbol: unified market symbol
|
|
315
|
-
:param int [since]: the earliest time in ms to fetch open orders for
|
|
316
|
-
:param int [limit]: the maximum number of open orders structures to retrieve
|
|
317
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
318
|
-
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
319
|
-
"""
|
|
320
|
-
return await self.fetch_orders_by_status_ws('open', symbol, since, limit, params)
|
|
321
|
-
|
|
322
|
-
async def fetch_closed_orders_ws(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
323
|
-
"""
|
|
324
|
-
fetches information on multiple closed orders made by the user
|
|
325
|
-
|
|
326
|
-
https://www.gate.io/docs/developers/futures/ws/en/#order-list
|
|
327
|
-
|
|
328
|
-
:param str symbol: unified market symbol of the market orders were made in
|
|
329
|
-
:param int [since]: the earliest time in ms to fetch orders for
|
|
330
|
-
:param int [limit]: the maximum number of order structures to retrieve
|
|
331
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
332
|
-
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
333
|
-
"""
|
|
334
|
-
return await self.fetch_orders_by_status_ws('finished', symbol, since, limit, params)
|
|
335
|
-
|
|
336
|
-
async def fetch_orders_by_status_ws(self, status: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
|
337
|
-
"""
|
|
338
|
-
|
|
339
|
-
https://www.gate.io/docs/developers/futures/ws/en/#order-list
|
|
340
|
-
|
|
341
|
-
fetches information on multiple orders made by the user by status
|
|
342
|
-
:param str status: requested order status
|
|
343
|
-
:param str symbol: unified market symbol of the market orders were made in
|
|
344
|
-
:param int|None [since]: the earliest time in ms to fetch orders for
|
|
345
|
-
:param int|None [limit]: the maximum number of order structures to retrieve
|
|
346
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
347
|
-
:param int [params.orderId]: order id to begin at
|
|
348
|
-
:param int [params.limit]: the maximum number of order structures to retrieve
|
|
349
|
-
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
350
|
-
"""
|
|
351
|
-
await self.load_markets()
|
|
352
|
-
market = None
|
|
353
|
-
if symbol is not None:
|
|
354
|
-
market = self.market(symbol)
|
|
355
|
-
symbol = market['symbol']
|
|
356
|
-
if market['swap'] is not True:
|
|
357
|
-
raise NotSupported(self.id + ' fetchOrdersByStatusWs is only supported by swap markets. Use rest API for other markets')
|
|
358
|
-
request, requestParams = self.prepareOrdersByStatusRequest(status, symbol, since, limit, params)
|
|
359
|
-
newRequest = self.omit(request, ['settle'])
|
|
360
|
-
messageType = self.get_type_by_market(market)
|
|
361
|
-
channel = messageType + '.order_list'
|
|
362
|
-
url = self.get_url_by_market(market)
|
|
363
|
-
await self.authenticate(url, messageType)
|
|
364
|
-
rawOrders = await self.request_private(url, self.extend(newRequest, requestParams), channel)
|
|
365
|
-
orders = self.parse_orders(rawOrders, market)
|
|
366
|
-
return self.filter_by_symbol_since_limit(orders, symbol, since, limit)
|
|
367
|
-
|
|
368
|
-
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
|
369
|
-
"""
|
|
370
|
-
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
371
|
-
:param str symbol: unified symbol of the market to fetch the order book for
|
|
372
|
-
:param int [limit]: the maximum amount of order book entries to return
|
|
373
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
374
|
-
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
|
375
|
-
"""
|
|
376
|
-
await self.load_markets()
|
|
377
|
-
market = self.market(symbol)
|
|
378
|
-
symbol = market['symbol']
|
|
379
|
-
marketId = market['id']
|
|
380
|
-
interval, query = self.handle_option_and_params(params, 'watchOrderBook', 'interval', '100ms')
|
|
381
|
-
messageType = self.get_type_by_market(market)
|
|
382
|
-
channel = messageType + '.order_book_update'
|
|
383
|
-
messageHash = 'orderbook' + ':' + symbol
|
|
384
|
-
url = self.get_url_by_market(market)
|
|
385
|
-
payload = [marketId, interval]
|
|
386
|
-
if limit is None:
|
|
387
|
-
limit = 100
|
|
388
|
-
if market['contract']:
|
|
389
|
-
stringLimit = str(limit)
|
|
390
|
-
payload.append(stringLimit)
|
|
391
|
-
subscription: dict = {
|
|
392
|
-
'symbol': symbol,
|
|
393
|
-
'limit': limit,
|
|
394
|
-
}
|
|
395
|
-
orderbook = await self.subscribe_public(url, messageHash, payload, channel, query, subscription)
|
|
396
|
-
return orderbook.limit()
|
|
397
|
-
|
|
398
|
-
async def un_watch_order_book(self, symbol: str, params={}) -> Any:
|
|
399
|
-
"""
|
|
400
|
-
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
401
|
-
:param str symbol: unified symbol of the market to fetch the order book for
|
|
402
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
403
|
-
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
|
404
|
-
"""
|
|
405
|
-
await self.load_markets()
|
|
406
|
-
market = self.market(symbol)
|
|
407
|
-
symbol = market['symbol']
|
|
408
|
-
marketId = market['id']
|
|
409
|
-
interval = '100ms'
|
|
410
|
-
interval, params = self.handle_option_and_params(params, 'watchOrderBook', 'interval', interval)
|
|
411
|
-
messageType = self.get_type_by_market(market)
|
|
412
|
-
channel = messageType + '.order_book_update'
|
|
413
|
-
subMessageHash = 'orderbook' + ':' + symbol
|
|
414
|
-
messageHash = 'unsubscribe:orderbook' + ':' + symbol
|
|
415
|
-
url = self.get_url_by_market(market)
|
|
416
|
-
payload = [marketId, interval]
|
|
417
|
-
limit = self.safe_integer(params, 'limit', 100)
|
|
418
|
-
if market['contract']:
|
|
419
|
-
stringLimit = str(limit)
|
|
420
|
-
payload.append(stringLimit)
|
|
421
|
-
return await self.un_subscribe_public_multiple(url, 'orderbook', [symbol], [messageHash], [subMessageHash], payload, channel, params)
|
|
422
|
-
|
|
423
|
-
def handle_order_book_subscription(self, client: Client, message, subscription):
|
|
424
|
-
symbol = self.safe_string(subscription, 'symbol')
|
|
425
|
-
limit = self.safe_integer(subscription, 'limit')
|
|
426
|
-
self.orderbooks[symbol] = self.order_book({}, limit)
|
|
427
|
-
|
|
428
|
-
def handle_order_book(self, client: Client, message):
|
|
429
|
-
#
|
|
430
|
-
# spot
|
|
431
|
-
#
|
|
432
|
-
# {
|
|
433
|
-
# "time": 1650189272,
|
|
434
|
-
# "channel": "spot.order_book_update",
|
|
435
|
-
# "event": "update",
|
|
436
|
-
# "result": {
|
|
437
|
-
# "t": 1650189272515,
|
|
438
|
-
# "e": "depthUpdate",
|
|
439
|
-
# "E": 1650189272,
|
|
440
|
-
# "s": "GMT_USDT",
|
|
441
|
-
# "U": 140595902,
|
|
442
|
-
# "u": 140595902,
|
|
443
|
-
# "b": [
|
|
444
|
-
# ['2.51518', "228.119"],
|
|
445
|
-
# ['2.50587', "1510.11"],
|
|
446
|
-
# ['2.49944', "67.6"],
|
|
447
|
-
# ],
|
|
448
|
-
# "a": [
|
|
449
|
-
# ['2.5182', "4.199"],
|
|
450
|
-
# ["2.51926", "1874"],
|
|
451
|
-
# ['2.53528', "96.529"],
|
|
452
|
-
# ]
|
|
453
|
-
# }
|
|
454
|
-
# }
|
|
455
|
-
#
|
|
456
|
-
# swap
|
|
457
|
-
#
|
|
458
|
-
# {
|
|
459
|
-
# "id": null,
|
|
460
|
-
# "time": 1650188898,
|
|
461
|
-
# "channel": "futures.order_book_update",
|
|
462
|
-
# "event": "update",
|
|
463
|
-
# "error": null,
|
|
464
|
-
# "result": {
|
|
465
|
-
# "t": 1650188898938,
|
|
466
|
-
# "s": "GMT_USDT",
|
|
467
|
-
# "U": 1577718307,
|
|
468
|
-
# "u": 1577719254,
|
|
469
|
-
# "b": [
|
|
470
|
-
# {p: "2.5178", s: 0},
|
|
471
|
-
# {p: "2.5179", s: 0},
|
|
472
|
-
# {p: "2.518", s: 0},
|
|
473
|
-
# ],
|
|
474
|
-
# "a": [
|
|
475
|
-
# {p: "2.52", s: 0},
|
|
476
|
-
# {p: "2.5201", s: 0},
|
|
477
|
-
# {p: "2.5203", s: 0},
|
|
478
|
-
# ]
|
|
479
|
-
# }
|
|
480
|
-
# }
|
|
481
|
-
#
|
|
482
|
-
channel = self.safe_string(message, 'channel')
|
|
483
|
-
channelParts = channel.split('.')
|
|
484
|
-
rawMarketType = self.safe_string(channelParts, 0)
|
|
485
|
-
isSpot = rawMarketType == 'spot'
|
|
486
|
-
marketType = 'spot' if isSpot else 'contract'
|
|
487
|
-
delta = self.safe_value(message, 'result')
|
|
488
|
-
deltaStart = self.safe_integer(delta, 'U')
|
|
489
|
-
deltaEnd = self.safe_integer(delta, 'u')
|
|
490
|
-
marketId = self.safe_string(delta, 's')
|
|
491
|
-
symbol = self.safe_symbol(marketId, None, '_', marketType)
|
|
492
|
-
messageHash = 'orderbook:' + symbol
|
|
493
|
-
storedOrderBook = self.safe_value(self.orderbooks, symbol, self.order_book({}))
|
|
494
|
-
nonce = self.safe_integer(storedOrderBook, 'nonce')
|
|
495
|
-
if nonce is None:
|
|
496
|
-
cacheLength = 0
|
|
497
|
-
if storedOrderBook is not None:
|
|
498
|
-
cacheLength = len(storedOrderBook.cache)
|
|
499
|
-
snapshotDelay = self.handle_option('watchOrderBook', 'snapshotDelay', 10)
|
|
500
|
-
waitAmount = snapshotDelay if isSpot else 0
|
|
501
|
-
if cacheLength == waitAmount:
|
|
502
|
-
# max limit is 100
|
|
503
|
-
subscription = client.subscriptions[messageHash]
|
|
504
|
-
limit = self.safe_integer(subscription, 'limit')
|
|
505
|
-
self.spawn(self.load_order_book, client, messageHash, symbol, limit, {}) # needed for c#, number of args needs to match
|
|
506
|
-
storedOrderBook.cache.append(delta)
|
|
507
|
-
return
|
|
508
|
-
elif nonce >= deltaEnd:
|
|
509
|
-
return
|
|
510
|
-
elif nonce >= deltaStart - 1:
|
|
511
|
-
self.handle_delta(storedOrderBook, delta)
|
|
512
|
-
else:
|
|
513
|
-
del client.subscriptions[messageHash]
|
|
514
|
-
del self.orderbooks[symbol]
|
|
515
|
-
checksum = self.handle_option('watchOrderBook', 'checksum', True)
|
|
516
|
-
if checksum:
|
|
517
|
-
error = ChecksumError(self.id + ' ' + self.orderbook_checksum_message(symbol))
|
|
518
|
-
client.reject(error, messageHash)
|
|
519
|
-
client.resolve(storedOrderBook, messageHash)
|
|
520
|
-
|
|
521
|
-
def get_cache_index(self, orderBook, cache):
|
|
522
|
-
nonce = self.safe_integer(orderBook, 'nonce')
|
|
523
|
-
firstDelta = cache[0]
|
|
524
|
-
firstDeltaStart = self.safe_integer(firstDelta, 'U')
|
|
525
|
-
if nonce < firstDeltaStart:
|
|
526
|
-
return -1
|
|
527
|
-
for i in range(0, len(cache)):
|
|
528
|
-
delta = cache[i]
|
|
529
|
-
deltaStart = self.safe_integer(delta, 'U')
|
|
530
|
-
deltaEnd = self.safe_integer(delta, 'u')
|
|
531
|
-
if (nonce >= deltaStart - 1) and (nonce < deltaEnd):
|
|
532
|
-
return i
|
|
533
|
-
return len(cache)
|
|
534
|
-
|
|
535
|
-
def handle_bid_asks(self, bookSide, bidAsks):
|
|
536
|
-
for i in range(0, len(bidAsks)):
|
|
537
|
-
bidAsk = bidAsks[i]
|
|
538
|
-
if isinstance(bidAsk, list):
|
|
539
|
-
bookSide.storeArray(self.parse_bid_ask(bidAsk))
|
|
540
|
-
else:
|
|
541
|
-
price = self.safe_float(bidAsk, 'p')
|
|
542
|
-
amount = self.safe_float(bidAsk, 's')
|
|
543
|
-
bookSide.store(price, amount)
|
|
544
|
-
|
|
545
|
-
def handle_delta(self, orderbook, delta):
|
|
546
|
-
timestamp = self.safe_integer(delta, 't')
|
|
547
|
-
orderbook['timestamp'] = timestamp
|
|
548
|
-
orderbook['datetime'] = self.iso8601(timestamp)
|
|
549
|
-
orderbook['nonce'] = self.safe_integer(delta, 'u')
|
|
550
|
-
bids = self.safe_value(delta, 'b', [])
|
|
551
|
-
asks = self.safe_value(delta, 'a', [])
|
|
552
|
-
storedBids = orderbook['bids']
|
|
553
|
-
storedAsks = orderbook['asks']
|
|
554
|
-
self.handle_bid_asks(storedBids, bids)
|
|
555
|
-
self.handle_bid_asks(storedAsks, asks)
|
|
556
|
-
|
|
557
|
-
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
|
558
|
-
"""
|
|
559
|
-
|
|
560
|
-
https://www.gate.io/docs/developers/apiv4/ws/en/#tickers-channel
|
|
561
|
-
|
|
562
|
-
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
563
|
-
:param str symbol: unified symbol of the market to fetch the ticker for
|
|
564
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
565
|
-
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
566
|
-
"""
|
|
567
|
-
await self.load_markets()
|
|
568
|
-
market = self.market(symbol)
|
|
569
|
-
symbol = market['symbol']
|
|
570
|
-
params['callerMethodName'] = 'watchTicker'
|
|
571
|
-
result = await self.watch_tickers([symbol], params)
|
|
572
|
-
return self.safe_value(result, symbol)
|
|
573
|
-
|
|
574
|
-
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
|
575
|
-
"""
|
|
576
|
-
|
|
577
|
-
https://www.gate.io/docs/developers/apiv4/ws/en/#tickers-channel
|
|
578
|
-
|
|
579
|
-
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
580
|
-
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
581
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
582
|
-
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
583
|
-
"""
|
|
584
|
-
return await self.subscribe_watch_tickers_and_bids_asks(symbols, 'watchTickers', self.extend({'method': 'tickers'}, params))
|
|
585
|
-
|
|
586
|
-
def handle_ticker(self, client: Client, message):
|
|
587
|
-
#
|
|
588
|
-
# {
|
|
589
|
-
# "time": 1649326221,
|
|
590
|
-
# "channel": "spot.tickers",
|
|
591
|
-
# "event": "update",
|
|
592
|
-
# "result": {
|
|
593
|
-
# "currency_pair": "BTC_USDT",
|
|
594
|
-
# "last": "43444.82",
|
|
595
|
-
# "lowest_ask": "43444.82",
|
|
596
|
-
# "highest_bid": "43444.81",
|
|
597
|
-
# "change_percentage": "-4.0036",
|
|
598
|
-
# "base_volume": "5182.5412425462",
|
|
599
|
-
# "quote_volume": "227267634.93123952",
|
|
600
|
-
# "high_24h": "47698",
|
|
601
|
-
# "low_24h": "42721.03"
|
|
602
|
-
# }
|
|
603
|
-
# }
|
|
604
|
-
#
|
|
605
|
-
self.handle_ticker_and_bid_ask('ticker', client, message)
|
|
606
|
-
|
|
607
|
-
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
|
608
|
-
"""
|
|
609
|
-
|
|
610
|
-
https://www.gate.io/docs/developers/apiv4/ws/en/#best-bid-or-ask-price
|
|
611
|
-
https://www.gate.io/docs/developers/apiv4/ws/en/#order-book-channel
|
|
612
|
-
|
|
613
|
-
watches best bid & ask for symbols
|
|
614
|
-
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
615
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
616
|
-
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
617
|
-
"""
|
|
618
|
-
return await self.subscribe_watch_tickers_and_bids_asks(symbols, 'watchBidsAsks', self.extend({'method': 'book_ticker'}, params))
|
|
619
|
-
|
|
620
|
-
def handle_bid_ask(self, client: Client, message):
|
|
621
|
-
#
|
|
622
|
-
# {
|
|
623
|
-
# "time": 1671363004,
|
|
624
|
-
# "time_ms": 1671363004235,
|
|
625
|
-
# "channel": "spot.book_ticker",
|
|
626
|
-
# "event": "update",
|
|
627
|
-
# "result": {
|
|
628
|
-
# "t": 1671363004228,
|
|
629
|
-
# "u": 9793320464,
|
|
630
|
-
# "s": "BTC_USDT",
|
|
631
|
-
# "b": "16716.8",
|
|
632
|
-
# "B": "0.0134",
|
|
633
|
-
# "a": "16716.9",
|
|
634
|
-
# "A": "0.0353"
|
|
635
|
-
# }
|
|
636
|
-
# }
|
|
637
|
-
#
|
|
638
|
-
self.handle_ticker_and_bid_ask('bidask', client, message)
|
|
639
|
-
|
|
640
|
-
async def subscribe_watch_tickers_and_bids_asks(self, symbols: Strings = None, callerMethodName: Str = None, params={}) -> Tickers:
|
|
641
|
-
await self.load_markets()
|
|
642
|
-
callerMethodName, params = self.handle_param_string(params, 'callerMethodName', callerMethodName)
|
|
643
|
-
symbols = self.market_symbols(symbols, None, False)
|
|
644
|
-
market = self.market(symbols[0])
|
|
645
|
-
messageType = self.get_type_by_market(market)
|
|
646
|
-
marketIds = self.market_ids(symbols)
|
|
647
|
-
channelName = None
|
|
648
|
-
channelName, params = self.handle_option_and_params(params, callerMethodName, 'method')
|
|
649
|
-
url = self.get_url_by_market(market)
|
|
650
|
-
channel = messageType + '.' + channelName
|
|
651
|
-
isWatchTickers = callerMethodName.find('watchTicker') >= 0
|
|
652
|
-
prefix = 'ticker' if isWatchTickers else 'bidask'
|
|
653
|
-
messageHashes = []
|
|
654
|
-
for i in range(0, len(symbols)):
|
|
655
|
-
symbol = symbols[i]
|
|
656
|
-
messageHashes.append(prefix + ':' + symbol)
|
|
657
|
-
tickerOrBidAsk = await self.subscribe_public_multiple(url, messageHashes, marketIds, channel, params)
|
|
658
|
-
if self.newUpdates:
|
|
659
|
-
items: dict = {}
|
|
660
|
-
items[tickerOrBidAsk['symbol']] = tickerOrBidAsk
|
|
661
|
-
return items
|
|
662
|
-
result = self.tickers if isWatchTickers else self.bidsasks
|
|
663
|
-
return self.filter_by_array(result, 'symbol', symbols, True)
|
|
664
|
-
|
|
665
|
-
def handle_ticker_and_bid_ask(self, objectName: str, client: Client, message):
|
|
666
|
-
channel = self.safe_string(message, 'channel')
|
|
667
|
-
parts = channel.split('.')
|
|
668
|
-
rawMarketType = self.safe_string(parts, 0)
|
|
669
|
-
marketType = 'contract' if (rawMarketType == 'futures') else 'spot'
|
|
670
|
-
result = self.safe_value(message, 'result')
|
|
671
|
-
results = []
|
|
672
|
-
if isinstance(result, list):
|
|
673
|
-
results = self.safe_list(message, 'result', [])
|
|
674
|
-
else:
|
|
675
|
-
rawTicker = self.safe_dict(message, 'result', {})
|
|
676
|
-
results = [rawTicker]
|
|
677
|
-
isTicker = (objectName == 'ticker') # whether ticker or bid-ask
|
|
678
|
-
for i in range(0, len(results)):
|
|
679
|
-
rawTicker = results[i]
|
|
680
|
-
marketId = self.safe_string(rawTicker, 's')
|
|
681
|
-
market = self.safe_market(marketId, None, '_', marketType)
|
|
682
|
-
parsedItem = self.parse_ticker(rawTicker, market)
|
|
683
|
-
symbol = parsedItem['symbol']
|
|
684
|
-
if isTicker:
|
|
685
|
-
self.tickers[symbol] = parsedItem
|
|
686
|
-
else:
|
|
687
|
-
self.bidsasks[symbol] = parsedItem
|
|
688
|
-
messageHash = objectName + ':' + symbol
|
|
689
|
-
client.resolve(parsedItem, messageHash)
|
|
690
|
-
|
|
691
|
-
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
692
|
-
"""
|
|
693
|
-
get the list of most recent trades for a particular symbol
|
|
694
|
-
:param str symbol: unified symbol of the market to fetch trades for
|
|
695
|
-
:param int [since]: timestamp in ms of the earliest trade to fetch
|
|
696
|
-
:param int [limit]: the maximum amount of trades to fetch
|
|
697
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
698
|
-
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
|
699
|
-
"""
|
|
700
|
-
return await self.watch_trades_for_symbols([symbol], since, limit, params)
|
|
701
|
-
|
|
702
|
-
async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
703
|
-
"""
|
|
704
|
-
get the list of most recent trades for a particular symbol
|
|
705
|
-
:param str[] symbols: unified symbol of the market to fetch trades for
|
|
706
|
-
:param int [since]: timestamp in ms of the earliest trade to fetch
|
|
707
|
-
:param int [limit]: the maximum amount of trades to fetch
|
|
708
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
709
|
-
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
|
710
|
-
"""
|
|
711
|
-
await self.load_markets()
|
|
712
|
-
symbols = self.market_symbols(symbols)
|
|
713
|
-
marketIds = self.market_ids(symbols)
|
|
714
|
-
market = self.market(symbols[0])
|
|
715
|
-
messageType = self.get_type_by_market(market)
|
|
716
|
-
channel = messageType + '.trades'
|
|
717
|
-
messageHashes = []
|
|
718
|
-
for i in range(0, len(symbols)):
|
|
719
|
-
symbol = symbols[i]
|
|
720
|
-
messageHashes.append('trades:' + symbol)
|
|
721
|
-
url = self.get_url_by_market(market)
|
|
722
|
-
trades = await self.subscribe_public_multiple(url, messageHashes, marketIds, channel, params)
|
|
723
|
-
if self.newUpdates:
|
|
724
|
-
first = self.safe_value(trades, 0)
|
|
725
|
-
tradeSymbol = self.safe_string(first, 'symbol')
|
|
726
|
-
limit = trades.getLimit(tradeSymbol, limit)
|
|
727
|
-
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
|
728
|
-
|
|
729
|
-
async def un_watch_trades_for_symbols(self, symbols: List[str], params={}) -> Any:
|
|
730
|
-
"""
|
|
731
|
-
get the list of most recent trades for a particular symbol
|
|
732
|
-
:param str[] symbols: unified symbol of the market to fetch trades for
|
|
733
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
734
|
-
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
|
735
|
-
"""
|
|
736
|
-
await self.load_markets()
|
|
737
|
-
symbols = self.market_symbols(symbols)
|
|
738
|
-
marketIds = self.market_ids(symbols)
|
|
739
|
-
market = self.market(symbols[0])
|
|
740
|
-
messageType = self.get_type_by_market(market)
|
|
741
|
-
channel = messageType + '.trades'
|
|
742
|
-
subMessageHashes = []
|
|
743
|
-
messageHashes = []
|
|
744
|
-
for i in range(0, len(symbols)):
|
|
745
|
-
symbol = symbols[i]
|
|
746
|
-
subMessageHashes.append('trades:' + symbol)
|
|
747
|
-
messageHashes.append('unsubscribe:trades:' + symbol)
|
|
748
|
-
url = self.get_url_by_market(market)
|
|
749
|
-
return await self.un_subscribe_public_multiple(url, 'trades', symbols, messageHashes, subMessageHashes, marketIds, channel, params)
|
|
750
|
-
|
|
751
|
-
async def un_watch_trades(self, symbol: str, params={}) -> Any:
|
|
752
|
-
"""
|
|
753
|
-
get the list of most recent trades for a particular symbol
|
|
754
|
-
:param str symbol: unified symbol of the market to fetch trades for
|
|
755
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
756
|
-
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
|
757
|
-
"""
|
|
758
|
-
return await self.un_watch_trades_for_symbols([symbol], params)
|
|
759
|
-
|
|
760
|
-
def handle_trades(self, client: Client, message):
|
|
761
|
-
#
|
|
762
|
-
# {
|
|
763
|
-
# "time": 1648725035,
|
|
764
|
-
# "channel": "spot.trades",
|
|
765
|
-
# "event": "update",
|
|
766
|
-
# "result": [{
|
|
767
|
-
# "id": 3130257995,
|
|
768
|
-
# "create_time": 1648725035,
|
|
769
|
-
# "create_time_ms": "1648725035923.0",
|
|
770
|
-
# "side": "sell",
|
|
771
|
-
# "currency_pair": "LTC_USDT",
|
|
772
|
-
# "amount": "0.0116",
|
|
773
|
-
# "price": "130.11"
|
|
774
|
-
# }]
|
|
775
|
-
# }
|
|
776
|
-
#
|
|
777
|
-
result = self.safe_value(message, 'result')
|
|
778
|
-
if not isinstance(result, list):
|
|
779
|
-
result = [result]
|
|
780
|
-
parsedTrades = self.parse_trades(result)
|
|
781
|
-
for i in range(0, len(parsedTrades)):
|
|
782
|
-
trade = parsedTrades[i]
|
|
783
|
-
symbol = trade['symbol']
|
|
784
|
-
cachedTrades = self.safe_value(self.trades, symbol)
|
|
785
|
-
if cachedTrades is None:
|
|
786
|
-
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
|
787
|
-
cachedTrades = ArrayCache(limit)
|
|
788
|
-
self.trades[symbol] = cachedTrades
|
|
789
|
-
cachedTrades.append(trade)
|
|
790
|
-
hash = 'trades:' + symbol
|
|
791
|
-
client.resolve(cachedTrades, hash)
|
|
792
|
-
|
|
793
|
-
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
|
794
|
-
"""
|
|
795
|
-
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
796
|
-
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
|
797
|
-
:param str timeframe: the length of time each candle represents
|
|
798
|
-
:param int [since]: timestamp in ms of the earliest candle to fetch
|
|
799
|
-
:param int [limit]: the maximum amount of candles to fetch
|
|
800
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
801
|
-
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
|
802
|
-
"""
|
|
803
|
-
await self.load_markets()
|
|
804
|
-
market = self.market(symbol)
|
|
805
|
-
symbol = market['symbol']
|
|
806
|
-
marketId = market['id']
|
|
807
|
-
interval = self.safe_string(self.timeframes, timeframe, timeframe)
|
|
808
|
-
messageType = self.get_type_by_market(market)
|
|
809
|
-
channel = messageType + '.candlesticks'
|
|
810
|
-
messageHash = 'candles:' + interval + ':' + market['symbol']
|
|
811
|
-
url = self.get_url_by_market(market)
|
|
812
|
-
payload = [interval, marketId]
|
|
813
|
-
ohlcv = await self.subscribe_public(url, messageHash, payload, channel, params)
|
|
814
|
-
if self.newUpdates:
|
|
815
|
-
limit = ohlcv.getLimit(symbol, limit)
|
|
816
|
-
return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
|
|
817
|
-
|
|
818
|
-
def handle_ohlcv(self, client: Client, message):
|
|
819
|
-
#
|
|
820
|
-
# {
|
|
821
|
-
# "time": 1606292600,
|
|
822
|
-
# "channel": "spot.candlesticks",
|
|
823
|
-
# "event": "update",
|
|
824
|
-
# "result": {
|
|
825
|
-
# "t": "1606292580", # total volume
|
|
826
|
-
# "v": "2362.32035", # volume
|
|
827
|
-
# "c": "19128.1", # close
|
|
828
|
-
# "h": "19128.1", # high
|
|
829
|
-
# "l": "19128.1", # low
|
|
830
|
-
# "o": "19128.1", # open
|
|
831
|
-
# "n": "1m_BTC_USDT" # sub
|
|
832
|
-
# }
|
|
833
|
-
# }
|
|
834
|
-
#
|
|
835
|
-
channel = self.safe_string(message, 'channel')
|
|
836
|
-
channelParts = channel.split('.')
|
|
837
|
-
rawMarketType = self.safe_string(channelParts, 0)
|
|
838
|
-
marketType = 'spot' if (rawMarketType == 'spot') else 'contract'
|
|
839
|
-
result = self.safe_value(message, 'result')
|
|
840
|
-
if not isinstance(result, list):
|
|
841
|
-
result = [result]
|
|
842
|
-
marketIds: dict = {}
|
|
843
|
-
for i in range(0, len(result)):
|
|
844
|
-
ohlcv = result[i]
|
|
845
|
-
subscription = self.safe_string(ohlcv, 'n', '')
|
|
846
|
-
parts = subscription.split('_')
|
|
847
|
-
timeframe = self.safe_string(parts, 0)
|
|
848
|
-
timeframeId = self.find_timeframe(timeframe)
|
|
849
|
-
prefix = timeframe + '_'
|
|
850
|
-
marketId = subscription.replace(prefix, '')
|
|
851
|
-
symbol = self.safe_symbol(marketId, None, '_', marketType)
|
|
852
|
-
parsed = self.parse_ohlcv(ohlcv)
|
|
853
|
-
self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
|
|
854
|
-
stored = self.safe_value(self.ohlcvs[symbol], timeframe)
|
|
855
|
-
if stored is None:
|
|
856
|
-
limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
|
|
857
|
-
stored = ArrayCacheByTimestamp(limit)
|
|
858
|
-
self.ohlcvs[symbol][timeframeId] = stored
|
|
859
|
-
stored.append(parsed)
|
|
860
|
-
marketIds[symbol] = timeframe
|
|
861
|
-
keys = list(marketIds.keys())
|
|
862
|
-
for i in range(0, len(keys)):
|
|
863
|
-
symbol = keys[i]
|
|
864
|
-
timeframe = marketIds[symbol]
|
|
865
|
-
interval = self.find_timeframe(timeframe)
|
|
866
|
-
hash = 'candles' + ':' + interval + ':' + symbol
|
|
867
|
-
stored = self.safe_value(self.ohlcvs[symbol], interval)
|
|
868
|
-
client.resolve(stored, hash)
|
|
869
|
-
|
|
870
|
-
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
871
|
-
"""
|
|
872
|
-
watches information on multiple trades made by the user
|
|
873
|
-
:param str symbol: unified market symbol of the market trades were made in
|
|
874
|
-
:param int [since]: the earliest time in ms to fetch trades for
|
|
875
|
-
:param int [limit]: the maximum number of trade structures to retrieve
|
|
876
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
877
|
-
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
|
878
|
-
"""
|
|
879
|
-
await self.load_markets()
|
|
880
|
-
subType = None
|
|
881
|
-
type = None
|
|
882
|
-
marketId = '!' + 'all'
|
|
883
|
-
market = None
|
|
884
|
-
if symbol is not None:
|
|
885
|
-
market = self.market(symbol)
|
|
886
|
-
marketId = market['id']
|
|
887
|
-
type, params = self.handle_market_type_and_params('watchMyTrades', market, params)
|
|
888
|
-
subType, params = self.handle_sub_type_and_params('watchMyTrades', market, params)
|
|
889
|
-
messageType = self.get_supported_mapping(type, {
|
|
890
|
-
'spot': 'spot',
|
|
891
|
-
'margin': 'spot',
|
|
892
|
-
'future': 'futures',
|
|
893
|
-
'swap': 'futures',
|
|
894
|
-
'option': 'options',
|
|
895
|
-
})
|
|
896
|
-
channel = messageType + '.usertrades'
|
|
897
|
-
messageHash = 'myTrades'
|
|
898
|
-
if symbol is not None:
|
|
899
|
-
messageHash += ':' + symbol
|
|
900
|
-
isInverse = (subType == 'inverse')
|
|
901
|
-
url = self.get_url_by_market_type(type, isInverse)
|
|
902
|
-
payload = [marketId]
|
|
903
|
-
# uid required for non spot markets
|
|
904
|
-
requiresUid = (type != 'spot')
|
|
905
|
-
trades = await self.subscribe_private(url, messageHash, payload, channel, params, requiresUid)
|
|
906
|
-
if self.newUpdates:
|
|
907
|
-
limit = trades.getLimit(symbol, limit)
|
|
908
|
-
return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
|
|
909
|
-
|
|
910
|
-
def handle_my_trades(self, client: Client, message):
|
|
911
|
-
#
|
|
912
|
-
# {
|
|
913
|
-
# "time": 1543205083,
|
|
914
|
-
# "channel": "futures.usertrades",
|
|
915
|
-
# "event": "update",
|
|
916
|
-
# "error": null,
|
|
917
|
-
# "result": [
|
|
918
|
-
# {
|
|
919
|
-
# "id": "3335259",
|
|
920
|
-
# "create_time": 1628736848,
|
|
921
|
-
# "create_time_ms": 1628736848321,
|
|
922
|
-
# "contract": "BTC_USD",
|
|
923
|
-
# "order_id": "4872460",
|
|
924
|
-
# "size": 1,
|
|
925
|
-
# "price": "40000.4",
|
|
926
|
-
# "role": "maker"
|
|
927
|
-
# }
|
|
928
|
-
# ]
|
|
929
|
-
# }
|
|
930
|
-
#
|
|
931
|
-
result = self.safe_value(message, 'result', [])
|
|
932
|
-
tradesLength = len(result)
|
|
933
|
-
if tradesLength == 0:
|
|
934
|
-
return
|
|
935
|
-
cachedTrades = self.myTrades
|
|
936
|
-
if cachedTrades is None:
|
|
937
|
-
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
|
938
|
-
cachedTrades = ArrayCacheBySymbolById(limit)
|
|
939
|
-
self.myTrades = cachedTrades
|
|
940
|
-
parsed = self.parse_trades(result)
|
|
941
|
-
marketIds: dict = {}
|
|
942
|
-
for i in range(0, len(parsed)):
|
|
943
|
-
trade = parsed[i]
|
|
944
|
-
cachedTrades.append(trade)
|
|
945
|
-
symbol = trade['symbol']
|
|
946
|
-
marketIds[symbol] = True
|
|
947
|
-
keys = list(marketIds.keys())
|
|
948
|
-
for i in range(0, len(keys)):
|
|
949
|
-
market = keys[i]
|
|
950
|
-
hash = 'myTrades:' + market
|
|
951
|
-
client.resolve(cachedTrades, hash)
|
|
952
|
-
client.resolve(cachedTrades, 'myTrades')
|
|
953
|
-
|
|
954
|
-
async def watch_balance(self, params={}) -> Balances:
|
|
955
|
-
"""
|
|
956
|
-
watch balance and get the amount of funds available for trading or funds locked in orders
|
|
957
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
958
|
-
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
|
959
|
-
"""
|
|
960
|
-
await self.load_markets()
|
|
961
|
-
type = None
|
|
962
|
-
subType = None
|
|
963
|
-
type, params = self.handle_market_type_and_params('watchBalance', None, params)
|
|
964
|
-
subType, params = self.handle_sub_type_and_params('watchBalance', None, params)
|
|
965
|
-
isInverse = (subType == 'inverse')
|
|
966
|
-
url = self.get_url_by_market_type(type, isInverse)
|
|
967
|
-
requiresUid = (type != 'spot')
|
|
968
|
-
channelType = self.get_supported_mapping(type, {
|
|
969
|
-
'spot': 'spot',
|
|
970
|
-
'margin': 'spot',
|
|
971
|
-
'future': 'futures',
|
|
972
|
-
'swap': 'futures',
|
|
973
|
-
'option': 'options',
|
|
974
|
-
})
|
|
975
|
-
channel = channelType + '.balances'
|
|
976
|
-
messageHash = type + '.balance'
|
|
977
|
-
return await self.subscribe_private(url, messageHash, None, channel, params, requiresUid)
|
|
978
|
-
|
|
979
|
-
def handle_balance(self, client: Client, message):
|
|
980
|
-
#
|
|
981
|
-
# spot order fill
|
|
982
|
-
# {
|
|
983
|
-
# "time": 1653664351,
|
|
984
|
-
# "channel": "spot.balances",
|
|
985
|
-
# "event": "update",
|
|
986
|
-
# "result": [
|
|
987
|
-
# {
|
|
988
|
-
# "timestamp": "1653664351",
|
|
989
|
-
# "timestamp_ms": "1653664351017",
|
|
990
|
-
# "user": "10406147",
|
|
991
|
-
# "currency": "LTC",
|
|
992
|
-
# "change": "-0.0002000000000000",
|
|
993
|
-
# "total": "0.09986000000000000000",
|
|
994
|
-
# "available": "0.09986000000000000000"
|
|
995
|
-
# }
|
|
996
|
-
# ]
|
|
997
|
-
# }
|
|
998
|
-
#
|
|
999
|
-
# account transfer
|
|
1000
|
-
#
|
|
1001
|
-
# {
|
|
1002
|
-
# "id": null,
|
|
1003
|
-
# "time": 1653665088,
|
|
1004
|
-
# "channel": "futures.balances",
|
|
1005
|
-
# "event": "update",
|
|
1006
|
-
# "error": null,
|
|
1007
|
-
# "result": [
|
|
1008
|
-
# {
|
|
1009
|
-
# "balance": 25.035008537,
|
|
1010
|
-
# "change": 25,
|
|
1011
|
-
# "text": "-",
|
|
1012
|
-
# "time": 1653665088,
|
|
1013
|
-
# "time_ms": 1653665088286,
|
|
1014
|
-
# "type": "dnw",
|
|
1015
|
-
# "user": "10406147"
|
|
1016
|
-
# }
|
|
1017
|
-
# ]
|
|
1018
|
-
# }
|
|
1019
|
-
#
|
|
1020
|
-
# swap order fill
|
|
1021
|
-
# {
|
|
1022
|
-
# "id": null,
|
|
1023
|
-
# "time": 1653665311,
|
|
1024
|
-
# "channel": "futures.balances",
|
|
1025
|
-
# "event": "update",
|
|
1026
|
-
# "error": null,
|
|
1027
|
-
# "result": [
|
|
1028
|
-
# {
|
|
1029
|
-
# "balance": 20.031873037,
|
|
1030
|
-
# "change": -0.0031355,
|
|
1031
|
-
# "text": "LTC_USDT:165551103273",
|
|
1032
|
-
# "time": 1653665311,
|
|
1033
|
-
# "time_ms": 1653665311437,
|
|
1034
|
-
# "type": "fee",
|
|
1035
|
-
# "user": "10406147"
|
|
1036
|
-
# }
|
|
1037
|
-
# ]
|
|
1038
|
-
# }
|
|
1039
|
-
#
|
|
1040
|
-
result = self.safe_value(message, 'result', [])
|
|
1041
|
-
timestamp = self.safe_integer(message, 'time_ms')
|
|
1042
|
-
self.balance['info'] = result
|
|
1043
|
-
self.balance['timestamp'] = timestamp
|
|
1044
|
-
self.balance['datetime'] = self.iso8601(timestamp)
|
|
1045
|
-
for i in range(0, len(result)):
|
|
1046
|
-
rawBalance = result[i]
|
|
1047
|
-
account = self.account()
|
|
1048
|
-
currencyId = self.safe_string(rawBalance, 'currency', 'USDT') # when not present it is USDT
|
|
1049
|
-
code = self.safe_currency_code(currencyId)
|
|
1050
|
-
account['free'] = self.safe_string(rawBalance, 'available')
|
|
1051
|
-
account['total'] = self.safe_string_2(rawBalance, 'total', 'balance')
|
|
1052
|
-
self.balance[code] = account
|
|
1053
|
-
channel = self.safe_string(message, 'channel')
|
|
1054
|
-
parts = channel.split('.')
|
|
1055
|
-
rawType = self.safe_string(parts, 0)
|
|
1056
|
-
channelType = self.get_supported_mapping(rawType, {
|
|
1057
|
-
'spot': 'spot',
|
|
1058
|
-
'futures': 'swap',
|
|
1059
|
-
'options': 'option',
|
|
1060
|
-
})
|
|
1061
|
-
messageHash = channelType + '.balance'
|
|
1062
|
-
self.balance = self.safe_balance(self.balance)
|
|
1063
|
-
client.resolve(self.balance, messageHash)
|
|
1064
|
-
|
|
1065
|
-
async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
|
|
1066
|
-
"""
|
|
1067
|
-
|
|
1068
|
-
https://www.gate.io/docs/developers/futures/ws/en/#positions-subscription
|
|
1069
|
-
https://www.gate.io/docs/developers/delivery/ws/en/#positions-subscription
|
|
1070
|
-
https://www.gate.io/docs/developers/options/ws/en/#positions-channel
|
|
1071
|
-
|
|
1072
|
-
watch all open positions
|
|
1073
|
-
:param str[] [symbols]: list of unified market symbols to watch positions for
|
|
1074
|
-
:param int [since]: the earliest time in ms to fetch positions for
|
|
1075
|
-
:param int [limit]: the maximum number of positions to retrieve
|
|
1076
|
-
:param dict params: extra parameters specific to the exchange API endpoint
|
|
1077
|
-
:returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
|
|
1078
|
-
"""
|
|
1079
|
-
await self.load_markets()
|
|
1080
|
-
market = None
|
|
1081
|
-
symbols = self.market_symbols(symbols)
|
|
1082
|
-
payload = ['!' + 'all']
|
|
1083
|
-
if not self.is_empty(symbols):
|
|
1084
|
-
market = self.get_market_from_symbols(symbols)
|
|
1085
|
-
type = None
|
|
1086
|
-
query = None
|
|
1087
|
-
type, query = self.handle_market_type_and_params('watchPositions', market, params)
|
|
1088
|
-
if type == 'spot':
|
|
1089
|
-
type = 'swap'
|
|
1090
|
-
typeId = self.get_supported_mapping(type, {
|
|
1091
|
-
'future': 'futures',
|
|
1092
|
-
'swap': 'futures',
|
|
1093
|
-
'option': 'options',
|
|
1094
|
-
})
|
|
1095
|
-
messageHash = type + ':positions'
|
|
1096
|
-
if not self.is_empty(symbols):
|
|
1097
|
-
messageHash += '::' + ','.join(symbols)
|
|
1098
|
-
channel = typeId + '.positions'
|
|
1099
|
-
subType = None
|
|
1100
|
-
subType, query = self.handle_sub_type_and_params('watchPositions', market, query)
|
|
1101
|
-
isInverse = (subType == 'inverse')
|
|
1102
|
-
url = self.get_url_by_market_type(type, isInverse)
|
|
1103
|
-
client = self.client(url)
|
|
1104
|
-
self.set_positions_cache(client, type, symbols)
|
|
1105
|
-
fetchPositionsSnapshot = self.handle_option('watchPositions', 'fetchPositionsSnapshot', True)
|
|
1106
|
-
awaitPositionsSnapshot = self.handle_option('watchPositions', 'awaitPositionsSnapshot', True)
|
|
1107
|
-
cache = self.safe_value(self.positions, type)
|
|
1108
|
-
if fetchPositionsSnapshot and awaitPositionsSnapshot and cache is None:
|
|
1109
|
-
return await client.future(type + ':fetchPositionsSnapshot')
|
|
1110
|
-
positions = await self.subscribe_private(url, messageHash, payload, channel, query, True)
|
|
1111
|
-
if self.newUpdates:
|
|
1112
|
-
return positions
|
|
1113
|
-
return self.filter_by_symbols_since_limit(self.positions[type], symbols, since, limit, True)
|
|
1114
|
-
|
|
1115
|
-
def set_positions_cache(self, client: Client, type, symbols: Strings = None):
|
|
1116
|
-
if self.positions is None:
|
|
1117
|
-
self.positions = {}
|
|
1118
|
-
if type in self.positions:
|
|
1119
|
-
return
|
|
1120
|
-
fetchPositionsSnapshot = self.handle_option('watchPositions', 'fetchPositionsSnapshot', False)
|
|
1121
|
-
if fetchPositionsSnapshot:
|
|
1122
|
-
messageHash = type + ':fetchPositionsSnapshot'
|
|
1123
|
-
if not (messageHash in client.futures):
|
|
1124
|
-
client.future(messageHash)
|
|
1125
|
-
self.spawn(self.load_positions_snapshot, client, messageHash, type)
|
|
1126
|
-
else:
|
|
1127
|
-
self.positions[type] = ArrayCacheBySymbolBySide()
|
|
1128
|
-
|
|
1129
|
-
async def load_positions_snapshot(self, client, messageHash, type):
|
|
1130
|
-
positions = await self.fetch_positions(None, {'type': type})
|
|
1131
|
-
self.positions[type] = ArrayCacheBySymbolBySide()
|
|
1132
|
-
cache = self.positions[type]
|
|
1133
|
-
for i in range(0, len(positions)):
|
|
1134
|
-
position = positions[i]
|
|
1135
|
-
contracts = self.safe_number(position, 'contracts', 0)
|
|
1136
|
-
if contracts > 0:
|
|
1137
|
-
cache.append(position)
|
|
1138
|
-
# don't remove the future from the .futures cache
|
|
1139
|
-
future = client.futures[messageHash]
|
|
1140
|
-
future.resolve(cache)
|
|
1141
|
-
client.resolve(cache, type + ':position')
|
|
1142
|
-
|
|
1143
|
-
def handle_positions(self, client, message):
|
|
1144
|
-
#
|
|
1145
|
-
# {
|
|
1146
|
-
# time: 1693158497,
|
|
1147
|
-
# time_ms: 1693158497204,
|
|
1148
|
-
# channel: 'futures.positions',
|
|
1149
|
-
# event: 'update',
|
|
1150
|
-
# result: [{
|
|
1151
|
-
# contract: 'XRP_USDT',
|
|
1152
|
-
# cross_leverage_limit: 0,
|
|
1153
|
-
# entry_price: 0.5253,
|
|
1154
|
-
# history_pnl: 0,
|
|
1155
|
-
# history_point: 0,
|
|
1156
|
-
# last_close_pnl: 0,
|
|
1157
|
-
# leverage: 0,
|
|
1158
|
-
# leverage_max: 50,
|
|
1159
|
-
# liq_price: 0.0361,
|
|
1160
|
-
# maintenance_rate: 0.01,
|
|
1161
|
-
# margin: 4.89609962852,
|
|
1162
|
-
# mode: 'single',
|
|
1163
|
-
# realised_pnl: -0.0026265,
|
|
1164
|
-
# realised_point: 0,
|
|
1165
|
-
# risk_limit: 500000,
|
|
1166
|
-
# size: 1,
|
|
1167
|
-
# time: 1693158497,
|
|
1168
|
-
# time_ms: 1693158497195,
|
|
1169
|
-
# update_id: 1,
|
|
1170
|
-
# user: '10444586'
|
|
1171
|
-
# }]
|
|
1172
|
-
# }
|
|
1173
|
-
#
|
|
1174
|
-
type = self.get_market_type_by_url(client.url)
|
|
1175
|
-
data = self.safe_value(message, 'result', [])
|
|
1176
|
-
cache = self.positions[type]
|
|
1177
|
-
newPositions = []
|
|
1178
|
-
for i in range(0, len(data)):
|
|
1179
|
-
rawPosition = data[i]
|
|
1180
|
-
position = self.parse_position(rawPosition)
|
|
1181
|
-
newPositions.append(position)
|
|
1182
|
-
cache.append(position)
|
|
1183
|
-
messageHashes = self.find_message_hashes(client, type + ':positions::')
|
|
1184
|
-
for i in range(0, len(messageHashes)):
|
|
1185
|
-
messageHash = messageHashes[i]
|
|
1186
|
-
parts = messageHash.split('::')
|
|
1187
|
-
symbolsString = parts[1]
|
|
1188
|
-
symbols = symbolsString.split(',')
|
|
1189
|
-
positions = self.filter_by_array(newPositions, 'symbol', symbols, False)
|
|
1190
|
-
if not self.is_empty(positions):
|
|
1191
|
-
client.resolve(positions, messageHash)
|
|
1192
|
-
client.resolve(newPositions, type + ':positions')
|
|
1193
|
-
|
|
1194
|
-
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
1195
|
-
"""
|
|
1196
|
-
watches information on multiple orders made by the user
|
|
1197
|
-
:param str symbol: unified market symbol of the market orders were made in
|
|
1198
|
-
:param int [since]: the earliest time in ms to fetch orders for
|
|
1199
|
-
:param int [limit]: the maximum number of order structures to retrieve
|
|
1200
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1201
|
-
:param str [params.type]: spot, margin, swap, future, or option. Required if listening to all symbols.
|
|
1202
|
-
:param boolean [params.isInverse]: if future, listen to inverse or linear contracts
|
|
1203
|
-
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
1204
|
-
"""
|
|
1205
|
-
await self.load_markets()
|
|
1206
|
-
market = None
|
|
1207
|
-
if symbol is not None:
|
|
1208
|
-
market = self.market(symbol)
|
|
1209
|
-
symbol = market['symbol']
|
|
1210
|
-
type = None
|
|
1211
|
-
query = None
|
|
1212
|
-
type, query = self.handle_market_type_and_params('watchOrders', market, params)
|
|
1213
|
-
typeId = self.get_supported_mapping(type, {
|
|
1214
|
-
'spot': 'spot',
|
|
1215
|
-
'margin': 'spot',
|
|
1216
|
-
'future': 'futures',
|
|
1217
|
-
'swap': 'futures',
|
|
1218
|
-
'option': 'options',
|
|
1219
|
-
})
|
|
1220
|
-
channel = typeId + '.orders'
|
|
1221
|
-
messageHash = 'orders'
|
|
1222
|
-
payload = ['!' + 'all']
|
|
1223
|
-
if symbol is not None:
|
|
1224
|
-
messageHash += ':' + market['id']
|
|
1225
|
-
payload = [market['id']]
|
|
1226
|
-
subType = None
|
|
1227
|
-
subType, query = self.handle_sub_type_and_params('watchOrders', market, query)
|
|
1228
|
-
isInverse = (subType == 'inverse')
|
|
1229
|
-
url = self.get_url_by_market_type(type, isInverse)
|
|
1230
|
-
# uid required for non spot markets
|
|
1231
|
-
requiresUid = (type != 'spot')
|
|
1232
|
-
orders = await self.subscribe_private(url, messageHash, payload, channel, query, requiresUid)
|
|
1233
|
-
if self.newUpdates:
|
|
1234
|
-
limit = orders.getLimit(symbol, limit)
|
|
1235
|
-
return self.filter_by_since_limit(orders, since, limit, 'timestamp', True)
|
|
1236
|
-
|
|
1237
|
-
def handle_order(self, client: Client, message):
|
|
1238
|
-
#
|
|
1239
|
-
# {
|
|
1240
|
-
# "time": 1605175506,
|
|
1241
|
-
# "channel": "spot.orders",
|
|
1242
|
-
# "event": "update",
|
|
1243
|
-
# "result": [
|
|
1244
|
-
# {
|
|
1245
|
-
# "id": "30784435",
|
|
1246
|
-
# "user": 123456,
|
|
1247
|
-
# "text": "t-abc",
|
|
1248
|
-
# "create_time": "1605175506",
|
|
1249
|
-
# "create_time_ms": "1605175506123",
|
|
1250
|
-
# "update_time": "1605175506",
|
|
1251
|
-
# "update_time_ms": "1605175506123",
|
|
1252
|
-
# "event": "put",
|
|
1253
|
-
# "currency_pair": "BTC_USDT",
|
|
1254
|
-
# "type": "limit",
|
|
1255
|
-
# "account": "spot",
|
|
1256
|
-
# "side": "sell",
|
|
1257
|
-
# "amount": "1",
|
|
1258
|
-
# "price": "10001",
|
|
1259
|
-
# "time_in_force": "gtc",
|
|
1260
|
-
# "left": "1",
|
|
1261
|
-
# "filled_total": "0",
|
|
1262
|
-
# "fee": "0",
|
|
1263
|
-
# "fee_currency": "USDT",
|
|
1264
|
-
# "point_fee": "0",
|
|
1265
|
-
# "gt_fee": "0",
|
|
1266
|
-
# "gt_discount": True,
|
|
1267
|
-
# "rebated_fee": "0",
|
|
1268
|
-
# "rebated_fee_currency": "USDT"
|
|
1269
|
-
# }
|
|
1270
|
-
# ]
|
|
1271
|
-
# }
|
|
1272
|
-
#
|
|
1273
|
-
orders = self.safe_value(message, 'result', [])
|
|
1274
|
-
limit = self.safe_integer(self.options, 'ordersLimit', 1000)
|
|
1275
|
-
if self.orders is None:
|
|
1276
|
-
self.orders = ArrayCacheBySymbolById(limit)
|
|
1277
|
-
stored = self.orders
|
|
1278
|
-
marketIds: dict = {}
|
|
1279
|
-
parsedOrders = self.parse_orders(orders)
|
|
1280
|
-
for i in range(0, len(parsedOrders)):
|
|
1281
|
-
parsed = parsedOrders[i]
|
|
1282
|
-
# inject order status
|
|
1283
|
-
info = self.safe_value(parsed, 'info')
|
|
1284
|
-
event = self.safe_string(info, 'event')
|
|
1285
|
-
if event == 'put' or event == 'update':
|
|
1286
|
-
parsed['status'] = 'open'
|
|
1287
|
-
elif event == 'finish':
|
|
1288
|
-
status = self.safe_string(parsed, 'status')
|
|
1289
|
-
if status is None:
|
|
1290
|
-
left = self.safe_integer(info, 'left')
|
|
1291
|
-
parsed['status'] = 'closed' if (left == 0) else 'canceled'
|
|
1292
|
-
stored.append(parsed)
|
|
1293
|
-
symbol = parsed['symbol']
|
|
1294
|
-
market = self.market(symbol)
|
|
1295
|
-
marketIds[market['id']] = True
|
|
1296
|
-
keys = list(marketIds.keys())
|
|
1297
|
-
for i in range(0, len(keys)):
|
|
1298
|
-
messageHash = 'orders:' + keys[i]
|
|
1299
|
-
client.resolve(self.orders, messageHash)
|
|
1300
|
-
client.resolve(self.orders, 'orders')
|
|
1301
|
-
|
|
1302
|
-
async def watch_my_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
|
1303
|
-
"""
|
|
1304
|
-
watch the public liquidations of a trading pair
|
|
1305
|
-
|
|
1306
|
-
https://www.gate.io/docs/developers/futures/ws/en/#liquidates-api
|
|
1307
|
-
https://www.gate.io/docs/developers/delivery/ws/en/#liquidates-api
|
|
1308
|
-
https://www.gate.io/docs/developers/options/ws/en/#liquidates-channel
|
|
1309
|
-
|
|
1310
|
-
:param str symbol: unified CCXT market symbol
|
|
1311
|
-
:param int [since]: the earliest time in ms to fetch liquidations for
|
|
1312
|
-
:param int [limit]: the maximum number of liquidation structures to retrieve
|
|
1313
|
-
:param dict [params]: exchange specific parameters for the bitmex api endpoint
|
|
1314
|
-
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
|
1315
|
-
"""
|
|
1316
|
-
return self.watch_my_liquidations_for_symbols([symbol], since, limit, params)
|
|
1317
|
-
|
|
1318
|
-
async def watch_my_liquidations_for_symbols(self, symbols: List[str] = None, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
|
1319
|
-
"""
|
|
1320
|
-
watch the private liquidations of a trading pair
|
|
1321
|
-
|
|
1322
|
-
https://www.gate.io/docs/developers/futures/ws/en/#liquidates-api
|
|
1323
|
-
https://www.gate.io/docs/developers/delivery/ws/en/#liquidates-api
|
|
1324
|
-
https://www.gate.io/docs/developers/options/ws/en/#liquidates-channel
|
|
1325
|
-
|
|
1326
|
-
:param str[] symbols: unified CCXT market symbols
|
|
1327
|
-
:param int [since]: the earliest time in ms to fetch liquidations for
|
|
1328
|
-
:param int [limit]: the maximum number of liquidation structures to retrieve
|
|
1329
|
-
:param dict [params]: exchange specific parameters for the gate api endpoint
|
|
1330
|
-
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
|
1331
|
-
"""
|
|
1332
|
-
await self.load_markets()
|
|
1333
|
-
symbols = self.market_symbols(symbols, None, True, True)
|
|
1334
|
-
market = self.get_market_from_symbols(symbols)
|
|
1335
|
-
type = None
|
|
1336
|
-
query = None
|
|
1337
|
-
type, query = self.handle_market_type_and_params('watchMyLiquidationsForSymbols', market, params)
|
|
1338
|
-
typeId = self.get_supported_mapping(type, {
|
|
1339
|
-
'future': 'futures',
|
|
1340
|
-
'swap': 'futures',
|
|
1341
|
-
'option': 'options',
|
|
1342
|
-
})
|
|
1343
|
-
subType = None
|
|
1344
|
-
subType, query = self.handle_sub_type_and_params('watchMyLiquidationsForSymbols', market, query)
|
|
1345
|
-
isInverse = (subType == 'inverse')
|
|
1346
|
-
url = self.get_url_by_market_type(type, isInverse)
|
|
1347
|
-
payload = []
|
|
1348
|
-
messageHash = ''
|
|
1349
|
-
if self.is_empty(symbols):
|
|
1350
|
-
if typeId != 'futures' and not isInverse:
|
|
1351
|
-
raise BadRequest(self.id + ' watchMyLiquidationsForSymbols() does not support listening to all symbols, you must call watchMyLiquidations() instead for each symbol you wish to watch.')
|
|
1352
|
-
messageHash = 'myLiquidations'
|
|
1353
|
-
payload.append('not all')
|
|
1354
|
-
else:
|
|
1355
|
-
symbolsLength = len(symbols)
|
|
1356
|
-
if symbolsLength != 1:
|
|
1357
|
-
raise BadRequest(self.id + ' watchMyLiquidationsForSymbols() only allows one symbol at a time. To listen to several symbols call watchMyLiquidationsForSymbols() several times.')
|
|
1358
|
-
messageHash = 'myLiquidations::' + symbols[0]
|
|
1359
|
-
payload.append(market['id'])
|
|
1360
|
-
channel = typeId + '.liquidates'
|
|
1361
|
-
newLiquidations = await self.subscribe_private(url, messageHash, payload, channel, query, True)
|
|
1362
|
-
if self.newUpdates:
|
|
1363
|
-
return newLiquidations
|
|
1364
|
-
return self.filter_by_symbols_since_limit(self.liquidations, symbols, since, limit, True)
|
|
1365
|
-
|
|
1366
|
-
def handle_liquidation(self, client: Client, message):
|
|
1367
|
-
#
|
|
1368
|
-
# future / delivery
|
|
1369
|
-
# {
|
|
1370
|
-
# "channel":"futures.liquidates",
|
|
1371
|
-
# "event":"update",
|
|
1372
|
-
# "time":1541505434,
|
|
1373
|
-
# "time_ms":1541505434123,
|
|
1374
|
-
# "result":[
|
|
1375
|
-
# {
|
|
1376
|
-
# "entry_price":209,
|
|
1377
|
-
# "fill_price":215.1,
|
|
1378
|
-
# "left":0,
|
|
1379
|
-
# "leverage":0.0,
|
|
1380
|
-
# "liq_price":213,
|
|
1381
|
-
# "margin":0.007816722941,
|
|
1382
|
-
# "mark_price":213,
|
|
1383
|
-
# "order_id":4093362,
|
|
1384
|
-
# "order_price":215.1,
|
|
1385
|
-
# "size":-124,
|
|
1386
|
-
# "time":1541486601,
|
|
1387
|
-
# "time_ms":1541486601123,
|
|
1388
|
-
# "contract":"BTC_USD",
|
|
1389
|
-
# "user":"1040xxxx"
|
|
1390
|
-
# }
|
|
1391
|
-
# ]
|
|
1392
|
-
# }
|
|
1393
|
-
# option
|
|
1394
|
-
# {
|
|
1395
|
-
# "channel":"options.liquidates",
|
|
1396
|
-
# "event":"update",
|
|
1397
|
-
# "time":1630654851,
|
|
1398
|
-
# "result":[
|
|
1399
|
-
# {
|
|
1400
|
-
# "user":"1xxxx",
|
|
1401
|
-
# "init_margin":1190,
|
|
1402
|
-
# "maint_margin":1042.5,
|
|
1403
|
-
# "order_margin":0,
|
|
1404
|
-
# "time":1639051907,
|
|
1405
|
-
# "time_ms":1639051907000
|
|
1406
|
-
# }
|
|
1407
|
-
# ]
|
|
1408
|
-
# }
|
|
1409
|
-
#
|
|
1410
|
-
rawLiquidations = self.safe_list(message, 'result', [])
|
|
1411
|
-
newLiquidations = []
|
|
1412
|
-
for i in range(0, len(rawLiquidations)):
|
|
1413
|
-
rawLiquidation = rawLiquidations[i]
|
|
1414
|
-
liquidation = self.parse_ws_liquidation(rawLiquidation)
|
|
1415
|
-
symbol = self.safe_string(liquidation, 'symbol')
|
|
1416
|
-
liquidations = self.safe_value(self.liquidations, symbol)
|
|
1417
|
-
if liquidations is None:
|
|
1418
|
-
limit = self.safe_integer(self.options, 'liquidationsLimit', 1000)
|
|
1419
|
-
liquidations = ArrayCache(limit)
|
|
1420
|
-
liquidations.append(liquidation)
|
|
1421
|
-
self.liquidations[symbol] = liquidations
|
|
1422
|
-
client.resolve(liquidations, 'myLiquidations::' + symbol)
|
|
1423
|
-
client.resolve(newLiquidations, 'myLiquidations')
|
|
1424
|
-
|
|
1425
|
-
def parse_ws_liquidation(self, liquidation, market=None):
|
|
1426
|
-
#
|
|
1427
|
-
# future / delivery
|
|
1428
|
-
# {
|
|
1429
|
-
# "entry_price": 209,
|
|
1430
|
-
# "fill_price": 215.1,
|
|
1431
|
-
# "left": 0,
|
|
1432
|
-
# "leverage": 0.0,
|
|
1433
|
-
# "liq_price": 213,
|
|
1434
|
-
# "margin": 0.007816722941,
|
|
1435
|
-
# "mark_price": 213,
|
|
1436
|
-
# "order_id": 4093362,
|
|
1437
|
-
# "order_price": 215.1,
|
|
1438
|
-
# "size": -124,
|
|
1439
|
-
# "time": 1541486601,
|
|
1440
|
-
# "time_ms": 1541486601123,
|
|
1441
|
-
# "contract": "BTC_USD",
|
|
1442
|
-
# "user": "1040xxxx"
|
|
1443
|
-
# }
|
|
1444
|
-
# option
|
|
1445
|
-
# {
|
|
1446
|
-
# "user": "1xxxx",
|
|
1447
|
-
# "init_margin": 1190,
|
|
1448
|
-
# "maint_margin": 1042.5,
|
|
1449
|
-
# "order_margin": 0,
|
|
1450
|
-
# "time": 1639051907,
|
|
1451
|
-
# "time_ms": 1639051907000
|
|
1452
|
-
# }
|
|
1453
|
-
#
|
|
1454
|
-
marketId = self.safe_string(liquidation, 'contract')
|
|
1455
|
-
market = self.safe_market(marketId, market)
|
|
1456
|
-
timestamp = self.safe_integer(liquidation, 'time_ms')
|
|
1457
|
-
originalSize = self.safe_string(liquidation, 'size')
|
|
1458
|
-
left = self.safe_string(liquidation, 'left')
|
|
1459
|
-
amount = Precise.string_abs(Precise.string_sub(originalSize, left))
|
|
1460
|
-
return self.safe_liquidation({
|
|
1461
|
-
'info': liquidation,
|
|
1462
|
-
'symbol': self.safe_symbol(marketId, market),
|
|
1463
|
-
'contracts': self.parse_number(amount),
|
|
1464
|
-
'contractSize': self.safe_number(market, 'contractSize'),
|
|
1465
|
-
'price': self.safe_number(liquidation, 'fill_price'),
|
|
1466
|
-
'baseValue': None,
|
|
1467
|
-
'quoteValue': None,
|
|
1468
|
-
'timestamp': timestamp,
|
|
1469
|
-
'datetime': self.iso8601(timestamp),
|
|
1470
|
-
})
|
|
1471
|
-
|
|
1472
|
-
def handle_error_message(self, client: Client, message):
|
|
1473
|
-
#
|
|
1474
|
-
# {
|
|
1475
|
-
# "time": 1647274664,
|
|
1476
|
-
# "channel": "futures.orders",
|
|
1477
|
-
# "event": "subscribe",
|
|
1478
|
-
# "error": {code: 2, message: "unknown contract BTC_USDT_20220318"},
|
|
1479
|
-
# }
|
|
1480
|
-
# {
|
|
1481
|
-
# "time": 1647276473,
|
|
1482
|
-
# "channel": "futures.orders",
|
|
1483
|
-
# "event": "subscribe",
|
|
1484
|
-
# "error": {
|
|
1485
|
-
# "code": 4,
|
|
1486
|
-
# "message": "{"label":"INVALID_KEY","message":"Invalid key provided"}\n"
|
|
1487
|
-
# },
|
|
1488
|
-
# "result": null
|
|
1489
|
-
# }
|
|
1490
|
-
# {
|
|
1491
|
-
# header: {
|
|
1492
|
-
# response_time: '1718551891329',
|
|
1493
|
-
# status: '400',
|
|
1494
|
-
# channel: 'spot.order_place',
|
|
1495
|
-
# event: 'api',
|
|
1496
|
-
# client_id: '81.34.68.6-0xc16375e2c0',
|
|
1497
|
-
# conn_id: '9539116e0e09678f'
|
|
1498
|
-
# },
|
|
1499
|
-
# data: {errs: {label: 'AUTHENTICATION_FAILED', message: 'Not login'}},
|
|
1500
|
-
# request_id: '10406147'
|
|
1501
|
-
# }
|
|
1502
|
-
# {
|
|
1503
|
-
# "time": 1739853211,
|
|
1504
|
-
# "time_ms": 1739853211201,
|
|
1505
|
-
# "id": 1,
|
|
1506
|
-
# "conn_id": "62f2c1dabbe186d7",
|
|
1507
|
-
# "trace_id": "cdb02a8c0b61086b2fe6f8fad2f98c54",
|
|
1508
|
-
# "channel": "spot.trades",
|
|
1509
|
-
# "event": "subscribe",
|
|
1510
|
-
# "payload": [
|
|
1511
|
-
# "LUNARLENS_USDT",
|
|
1512
|
-
# "ETH_USDT"
|
|
1513
|
-
# ],
|
|
1514
|
-
# "error": {
|
|
1515
|
-
# "code": 2,
|
|
1516
|
-
# "message": "unknown currency pair: LUNARLENS_USDT"
|
|
1517
|
-
# },
|
|
1518
|
-
# "result": {
|
|
1519
|
-
# "status": "fail"
|
|
1520
|
-
# },
|
|
1521
|
-
# "requestId": "cdb02a8c0b61086b2fe6f8fad2f98c54"
|
|
1522
|
-
# }
|
|
1523
|
-
#
|
|
1524
|
-
data = self.safe_dict(message, 'data')
|
|
1525
|
-
errs = self.safe_dict(data, 'errs')
|
|
1526
|
-
error = self.safe_dict(message, 'error', errs)
|
|
1527
|
-
code = self.safe_string_2(error, 'code', 'label')
|
|
1528
|
-
id = self.safe_string_n(message, ['id', 'requestId', 'request_id'])
|
|
1529
|
-
if error is not None:
|
|
1530
|
-
messageHash = self.safe_string(client.subscriptions, id)
|
|
1531
|
-
try:
|
|
1532
|
-
self.throw_exactly_matched_exception(self.exceptions['ws']['exact'], code, self.json(message))
|
|
1533
|
-
self.throw_exactly_matched_exception(self.exceptions['exact'], code, self.json(errs))
|
|
1534
|
-
errorMessage = self.safe_string(error, 'message', self.safe_string(errs, 'message'))
|
|
1535
|
-
self.throw_broadly_matched_exception(self.exceptions['ws']['broad'], errorMessage, self.json(message))
|
|
1536
|
-
raise ExchangeError(self.json(message))
|
|
1537
|
-
except Exception as e:
|
|
1538
|
-
client.reject(e, messageHash)
|
|
1539
|
-
if (messageHash is not None) and (messageHash in client.subscriptions):
|
|
1540
|
-
del client.subscriptions[messageHash]
|
|
1541
|
-
# remove subscriptions for watchSymbols
|
|
1542
|
-
channel = self.safe_string(message, 'channel')
|
|
1543
|
-
if (channel is not None) and (channel.find('.') > 0):
|
|
1544
|
-
parsedChannel = channel.split('.')
|
|
1545
|
-
payload = self.safe_list(message, 'payload', [])
|
|
1546
|
-
for i in range(0, len(payload)):
|
|
1547
|
-
marketType = parsedChannel[0] == 'swap' if 'futures' else parsedChannel[0]
|
|
1548
|
-
symbol = self.safe_symbol(payload[i], None, '_', marketType)
|
|
1549
|
-
messageHashSymbol = parsedChannel[1] + ':' + symbol
|
|
1550
|
-
if (messageHashSymbol is not None) and (messageHashSymbol in client.subscriptions):
|
|
1551
|
-
del client.subscriptions[messageHashSymbol]
|
|
1552
|
-
if (id is not None) and (id in client.subscriptions):
|
|
1553
|
-
del client.subscriptions[id]
|
|
1554
|
-
return True
|
|
1555
|
-
return False
|
|
1556
|
-
|
|
1557
|
-
def handle_balance_subscription(self, client: Client, message, subscription=None):
|
|
1558
|
-
self.balance = {}
|
|
1559
|
-
|
|
1560
|
-
def handle_subscription_status(self, client: Client, message):
|
|
1561
|
-
channel = self.safe_string(message, 'channel')
|
|
1562
|
-
methods: dict = {
|
|
1563
|
-
'balance': self.handle_balance_subscription,
|
|
1564
|
-
'spot.order_book_update': self.handle_order_book_subscription,
|
|
1565
|
-
'futures.order_book_update': self.handle_order_book_subscription,
|
|
1566
|
-
}
|
|
1567
|
-
id = self.safe_string(message, 'id')
|
|
1568
|
-
if channel in methods:
|
|
1569
|
-
subscriptionHash = self.safe_string(client.subscriptions, id)
|
|
1570
|
-
subscription = self.safe_value(client.subscriptions, subscriptionHash)
|
|
1571
|
-
method = methods[channel]
|
|
1572
|
-
method(client, message, subscription)
|
|
1573
|
-
if id in client.subscriptions:
|
|
1574
|
-
del client.subscriptions[id]
|
|
1575
|
-
|
|
1576
|
-
def handle_un_subscribe(self, client: Client, message):
|
|
1577
|
-
#
|
|
1578
|
-
# {
|
|
1579
|
-
# "time":1725534679,
|
|
1580
|
-
# "time_ms":1725534679786,
|
|
1581
|
-
# "id":2,
|
|
1582
|
-
# "conn_id":"fac539b443fd7002",
|
|
1583
|
-
# "trace_id":"efe1d282b630b4aa266b84bee177791a",
|
|
1584
|
-
# "channel":"spot.trades",
|
|
1585
|
-
# "event":"unsubscribe",
|
|
1586
|
-
# "payload":[
|
|
1587
|
-
# "LTC_USDT"
|
|
1588
|
-
# ],
|
|
1589
|
-
# "result":{
|
|
1590
|
-
# "status":"success"
|
|
1591
|
-
# },
|
|
1592
|
-
# "requestId":"efe1d282b630b4aa266b84bee177791a"
|
|
1593
|
-
# }
|
|
1594
|
-
#
|
|
1595
|
-
id = self.safe_string(message, 'id')
|
|
1596
|
-
keys = list(client.subscriptions.keys())
|
|
1597
|
-
for i in range(0, len(keys)):
|
|
1598
|
-
messageHash = keys[i]
|
|
1599
|
-
if not (messageHash in client.subscriptions):
|
|
1600
|
-
continue
|
|
1601
|
-
# the previous iteration can have deleted the messageHash from the subscriptions
|
|
1602
|
-
if messageHash.startswith('unsubscribe'):
|
|
1603
|
-
subscription = client.subscriptions[messageHash]
|
|
1604
|
-
subId = self.safe_string(subscription, 'id')
|
|
1605
|
-
if id != subId:
|
|
1606
|
-
continue
|
|
1607
|
-
messageHashes = self.safe_list(subscription, 'messageHashes', [])
|
|
1608
|
-
subMessageHashes = self.safe_list(subscription, 'subMessageHashes', [])
|
|
1609
|
-
for j in range(0, len(messageHashes)):
|
|
1610
|
-
unsubHash = messageHashes[j]
|
|
1611
|
-
subHash = subMessageHashes[j]
|
|
1612
|
-
self.clean_unsubscription(client, subHash, unsubHash)
|
|
1613
|
-
self.clean_cache(subscription)
|
|
1614
|
-
|
|
1615
|
-
def clean_cache(self, subscription: dict):
|
|
1616
|
-
topic = self.safe_string(subscription, 'topic', '')
|
|
1617
|
-
symbols = self.safe_list(subscription, 'symbols', [])
|
|
1618
|
-
symbolsLength = len(symbols)
|
|
1619
|
-
if topic == 'ohlcv':
|
|
1620
|
-
symbolsAndTimeFrames = self.safe_list(subscription, 'symbolsAndTimeframes', [])
|
|
1621
|
-
for i in range(0, len(symbolsAndTimeFrames)):
|
|
1622
|
-
symbolAndTimeFrame = symbolsAndTimeFrames[i]
|
|
1623
|
-
symbol = self.safe_string(symbolAndTimeFrame, 0)
|
|
1624
|
-
timeframe = self.safe_string(symbolAndTimeFrame, 1)
|
|
1625
|
-
del self.ohlcvs[symbol][timeframe]
|
|
1626
|
-
elif symbolsLength > 0:
|
|
1627
|
-
for i in range(0, len(symbols)):
|
|
1628
|
-
symbol = symbols[i]
|
|
1629
|
-
if topic.endswith('trades'):
|
|
1630
|
-
del self.trades[symbol]
|
|
1631
|
-
elif topic == 'orderbook':
|
|
1632
|
-
del self.orderbooks[symbol]
|
|
1633
|
-
elif topic == 'ticker':
|
|
1634
|
-
del self.tickers[symbol]
|
|
1635
|
-
else:
|
|
1636
|
-
if topic.endswith('trades'):
|
|
1637
|
-
# don't reset self.myTrades directly here
|
|
1638
|
-
# because in c# we need to use a different object
|
|
1639
|
-
keys = list(self.trades.keys())
|
|
1640
|
-
for i in range(0, len(keys)):
|
|
1641
|
-
del self.trades[keys[i]]
|
|
1642
|
-
|
|
1643
|
-
def handle_message(self, client: Client, message):
|
|
1644
|
-
#
|
|
1645
|
-
# subscribe
|
|
1646
|
-
# {
|
|
1647
|
-
# "time": 1649062304,
|
|
1648
|
-
# "id": 1649062303,
|
|
1649
|
-
# "channel": "spot.candlesticks",
|
|
1650
|
-
# "event": "subscribe",
|
|
1651
|
-
# "result": {status: "success"}
|
|
1652
|
-
# }
|
|
1653
|
-
#
|
|
1654
|
-
# candlestick
|
|
1655
|
-
# {
|
|
1656
|
-
# "time": 1649063328,
|
|
1657
|
-
# "channel": "spot.candlesticks",
|
|
1658
|
-
# "event": "update",
|
|
1659
|
-
# "result": {
|
|
1660
|
-
# "t": "1649063280",
|
|
1661
|
-
# "v": "58932.23174896",
|
|
1662
|
-
# "c": "45966.47",
|
|
1663
|
-
# "h": "45997.24",
|
|
1664
|
-
# "l": "45966.47",
|
|
1665
|
-
# "o": "45975.18",
|
|
1666
|
-
# "n": "1m_BTC_USDT",
|
|
1667
|
-
# "a": "1.281699"
|
|
1668
|
-
# }
|
|
1669
|
-
# }
|
|
1670
|
-
#
|
|
1671
|
-
# orders
|
|
1672
|
-
# {
|
|
1673
|
-
# "time": 1630654851,
|
|
1674
|
-
# "channel": "options.orders", or futures.orders or spot.orders
|
|
1675
|
-
# "event": "update",
|
|
1676
|
-
# "result": [
|
|
1677
|
-
# {
|
|
1678
|
-
# "contract": "BTC_USDT-20211130-65000-C",
|
|
1679
|
-
# "create_time": 1637897000,
|
|
1680
|
-
# (...)
|
|
1681
|
-
# ]
|
|
1682
|
-
# }
|
|
1683
|
-
# orderbook
|
|
1684
|
-
# {
|
|
1685
|
-
# "time": 1649770525,
|
|
1686
|
-
# "channel": "spot.order_book_update",
|
|
1687
|
-
# "event": "update",
|
|
1688
|
-
# "result": {
|
|
1689
|
-
# "t": 1649770525653,
|
|
1690
|
-
# "e": "depthUpdate",
|
|
1691
|
-
# "E": 1649770525,
|
|
1692
|
-
# "s": "LTC_USDT",
|
|
1693
|
-
# "U": 2622525645,
|
|
1694
|
-
# "u": 2622525665,
|
|
1695
|
-
# "b": [
|
|
1696
|
-
# [Array], [Array],
|
|
1697
|
-
# [Array], [Array],
|
|
1698
|
-
# [Array], [Array],
|
|
1699
|
-
# [Array], [Array],
|
|
1700
|
-
# [Array], [Array],
|
|
1701
|
-
# [Array]
|
|
1702
|
-
# ],
|
|
1703
|
-
# "a": [
|
|
1704
|
-
# [Array], [Array],
|
|
1705
|
-
# [Array], [Array],
|
|
1706
|
-
# [Array], [Array],
|
|
1707
|
-
# [Array], [Array],
|
|
1708
|
-
# [Array], [Array],
|
|
1709
|
-
# [Array]
|
|
1710
|
-
# ]
|
|
1711
|
-
# }
|
|
1712
|
-
# }
|
|
1713
|
-
#
|
|
1714
|
-
# balance update
|
|
1715
|
-
#
|
|
1716
|
-
# {
|
|
1717
|
-
# "time": 1653664351,
|
|
1718
|
-
# "channel": "spot.balances",
|
|
1719
|
-
# "event": "update",
|
|
1720
|
-
# "result": [
|
|
1721
|
-
# {
|
|
1722
|
-
# "timestamp": "1653664351",
|
|
1723
|
-
# "timestamp_ms": "1653664351017",
|
|
1724
|
-
# "user": "10406147",
|
|
1725
|
-
# "currency": "LTC",
|
|
1726
|
-
# "change": "-0.0002000000000000",
|
|
1727
|
-
# "total": "0.09986000000000000000",
|
|
1728
|
-
# "available": "0.09986000000000000000"
|
|
1729
|
-
# }
|
|
1730
|
-
# ]
|
|
1731
|
-
# }
|
|
1732
|
-
#
|
|
1733
|
-
if self.handle_error_message(client, message):
|
|
1734
|
-
return
|
|
1735
|
-
event = self.safe_string(message, 'event')
|
|
1736
|
-
if event == 'subscribe':
|
|
1737
|
-
self.handle_subscription_status(client, message)
|
|
1738
|
-
return
|
|
1739
|
-
if event == 'unsubscribe':
|
|
1740
|
-
self.handle_un_subscribe(client, message)
|
|
1741
|
-
return
|
|
1742
|
-
channel = self.safe_string(message, 'channel', '')
|
|
1743
|
-
channelParts = channel.split('.')
|
|
1744
|
-
channelType = self.safe_value(channelParts, 1)
|
|
1745
|
-
v4Methods: dict = {
|
|
1746
|
-
'usertrades': self.handle_my_trades,
|
|
1747
|
-
'candlesticks': self.handle_ohlcv,
|
|
1748
|
-
'orders': self.handle_order,
|
|
1749
|
-
'positions': self.handle_positions,
|
|
1750
|
-
'tickers': self.handle_ticker,
|
|
1751
|
-
'book_ticker': self.handle_bid_ask,
|
|
1752
|
-
'trades': self.handle_trades,
|
|
1753
|
-
'order_book_update': self.handle_order_book,
|
|
1754
|
-
'balances': self.handle_balance,
|
|
1755
|
-
'liquidates': self.handle_liquidation,
|
|
1756
|
-
}
|
|
1757
|
-
method = self.safe_value(v4Methods, channelType)
|
|
1758
|
-
if method is not None:
|
|
1759
|
-
method(client, message)
|
|
1760
|
-
requestId = self.safe_string(message, 'request_id')
|
|
1761
|
-
if requestId == 'authenticated':
|
|
1762
|
-
self.handle_authentication_message(client, message)
|
|
1763
|
-
return
|
|
1764
|
-
if requestId is not None:
|
|
1765
|
-
data = self.safe_dict(message, 'data')
|
|
1766
|
-
# use safeValue may be Array or an Object
|
|
1767
|
-
result = self.safe_value(data, 'result')
|
|
1768
|
-
ack = self.safe_bool(message, 'ack')
|
|
1769
|
-
if ack is not True:
|
|
1770
|
-
client.resolve(result, requestId)
|
|
1771
|
-
|
|
1772
|
-
def get_url_by_market(self, market):
|
|
1773
|
-
baseUrl = self.urls['api'][market['type']]
|
|
1774
|
-
if market['contract']:
|
|
1775
|
-
return baseUrl['usdt'] if market['linear'] else baseUrl['btc']
|
|
1776
|
-
else:
|
|
1777
|
-
return baseUrl
|
|
1778
|
-
|
|
1779
|
-
def get_type_by_market(self, market: Market):
|
|
1780
|
-
if market['spot']:
|
|
1781
|
-
return 'spot'
|
|
1782
|
-
elif market['option']:
|
|
1783
|
-
return 'options'
|
|
1784
|
-
else:
|
|
1785
|
-
return 'futures'
|
|
1786
|
-
|
|
1787
|
-
def get_url_by_market_type(self, type: MarketType, isInverse=False):
|
|
1788
|
-
api = self.urls['api']
|
|
1789
|
-
url = api[type]
|
|
1790
|
-
if (type == 'swap') or (type == 'future'):
|
|
1791
|
-
return url['btc'] if isInverse else url['usdt']
|
|
1792
|
-
else:
|
|
1793
|
-
return url
|
|
1794
|
-
|
|
1795
|
-
def get_market_type_by_url(self, url: str):
|
|
1796
|
-
findBy: dict = {
|
|
1797
|
-
'op-': 'option',
|
|
1798
|
-
'delivery': 'future',
|
|
1799
|
-
'fx': 'swap',
|
|
1800
|
-
}
|
|
1801
|
-
keys = list(findBy.keys())
|
|
1802
|
-
for i in range(0, len(keys)):
|
|
1803
|
-
key = keys[i]
|
|
1804
|
-
value = findBy[key]
|
|
1805
|
-
if url.find(key) >= 0:
|
|
1806
|
-
return value
|
|
1807
|
-
return 'spot'
|
|
1808
|
-
|
|
1809
|
-
def request_id(self):
|
|
1810
|
-
# their support said that reqid must be an int32, not documented
|
|
1811
|
-
reqid = self.sum(self.safe_integer(self.options, 'reqid', 0), 1)
|
|
1812
|
-
self.options['reqid'] = reqid
|
|
1813
|
-
return reqid
|
|
1814
|
-
|
|
1815
|
-
async def subscribe_public(self, url, messageHash, payload, channel, params={}, subscription=None):
|
|
1816
|
-
requestId = self.request_id()
|
|
1817
|
-
time = self.seconds()
|
|
1818
|
-
request: dict = {
|
|
1819
|
-
'id': requestId,
|
|
1820
|
-
'time': time,
|
|
1821
|
-
'channel': channel,
|
|
1822
|
-
'event': 'subscribe',
|
|
1823
|
-
'payload': payload,
|
|
1824
|
-
}
|
|
1825
|
-
if subscription is not None:
|
|
1826
|
-
client = self.client(url)
|
|
1827
|
-
if not (messageHash in client.subscriptions):
|
|
1828
|
-
tempSubscriptionHash = str(requestId)
|
|
1829
|
-
client.subscriptions[tempSubscriptionHash] = messageHash
|
|
1830
|
-
message = self.extend(request, params)
|
|
1831
|
-
return await self.watch(url, messageHash, message, messageHash, subscription)
|
|
1832
|
-
|
|
1833
|
-
async def subscribe_public_multiple(self, url, messageHashes, payload, channel, params={}):
|
|
1834
|
-
requestId = self.request_id()
|
|
1835
|
-
time = self.seconds()
|
|
1836
|
-
request: dict = {
|
|
1837
|
-
'id': requestId,
|
|
1838
|
-
'time': time,
|
|
1839
|
-
'channel': channel,
|
|
1840
|
-
'event': 'subscribe',
|
|
1841
|
-
'payload': payload,
|
|
1842
|
-
}
|
|
1843
|
-
message = self.extend(request, params)
|
|
1844
|
-
return await self.watch_multiple(url, messageHashes, message, messageHashes)
|
|
1845
|
-
|
|
1846
|
-
async def un_subscribe_public_multiple(self, url, topic, symbols, messageHashes, subMessageHashes, payload, channel, params={}):
|
|
1847
|
-
requestId = self.request_id()
|
|
1848
|
-
time = self.seconds()
|
|
1849
|
-
request: dict = {
|
|
1850
|
-
'id': requestId,
|
|
1851
|
-
'time': time,
|
|
1852
|
-
'channel': channel,
|
|
1853
|
-
'event': 'unsubscribe',
|
|
1854
|
-
'payload': payload,
|
|
1855
|
-
}
|
|
1856
|
-
sub = {
|
|
1857
|
-
'id': str(requestId),
|
|
1858
|
-
'topic': topic,
|
|
1859
|
-
'unsubscribe': True,
|
|
1860
|
-
'messageHashes': messageHashes,
|
|
1861
|
-
'subMessageHashes': subMessageHashes,
|
|
1862
|
-
'symbols': symbols,
|
|
1863
|
-
}
|
|
1864
|
-
message = self.extend(request, params)
|
|
1865
|
-
return await self.watch_multiple(url, messageHashes, message, messageHashes, sub)
|
|
1866
|
-
|
|
1867
|
-
async def authenticate(self, url, messageType):
|
|
1868
|
-
channel = messageType + '.login'
|
|
1869
|
-
client = self.client(url)
|
|
1870
|
-
messageHash = 'authenticated'
|
|
1871
|
-
future = client.future(messageHash)
|
|
1872
|
-
authenticated = self.safe_value(client.subscriptions, messageHash)
|
|
1873
|
-
if authenticated is None:
|
|
1874
|
-
return await self.request_private(url, {}, channel, messageHash)
|
|
1875
|
-
return future
|
|
1876
|
-
|
|
1877
|
-
def handle_authentication_message(self, client: Client, message):
|
|
1878
|
-
messageHash = 'authenticated'
|
|
1879
|
-
future = self.safe_value(client.futures, messageHash)
|
|
1880
|
-
future.resolve(True)
|
|
1881
|
-
|
|
1882
|
-
async def request_private(self, url, reqParams, channel, requestId: Str = None):
|
|
1883
|
-
self.check_required_credentials()
|
|
1884
|
-
# uid is required for some subscriptions only so it's not a part of required credentials
|
|
1885
|
-
event = 'api'
|
|
1886
|
-
if requestId is None:
|
|
1887
|
-
reqId = self.request_id()
|
|
1888
|
-
requestId = str(reqId)
|
|
1889
|
-
messageHash = requestId
|
|
1890
|
-
time = self.seconds()
|
|
1891
|
-
# unfortunately, PHP demands double quotes for the escaped newline symbol
|
|
1892
|
-
signatureString = "\n".join([event, channel, self.json(reqParams), str(time)]) # eslint-disable-line quotes
|
|
1893
|
-
signature = self.hmac(self.encode(signatureString), self.encode(self.secret), hashlib.sha512, 'hex')
|
|
1894
|
-
payload: dict = {
|
|
1895
|
-
'req_id': requestId,
|
|
1896
|
-
'timestamp': str(time),
|
|
1897
|
-
'api_key': self.apiKey,
|
|
1898
|
-
'signature': signature,
|
|
1899
|
-
'req_param': reqParams,
|
|
1900
|
-
}
|
|
1901
|
-
if (channel == 'spot.order_place') or (channel == 'futures.order_place'):
|
|
1902
|
-
payload['req_header'] = {
|
|
1903
|
-
'X-Gate-Channel-Id': 'ccxt',
|
|
1904
|
-
}
|
|
1905
|
-
request: dict = {
|
|
1906
|
-
'id': requestId,
|
|
1907
|
-
'time': time,
|
|
1908
|
-
'channel': channel,
|
|
1909
|
-
'event': event,
|
|
1910
|
-
'payload': payload,
|
|
1911
|
-
}
|
|
1912
|
-
return await self.watch(url, messageHash, request, messageHash, requestId)
|
|
1913
|
-
|
|
1914
|
-
async def subscribe_private(self, url, messageHash, payload, channel, params, requiresUid=False):
|
|
1915
|
-
self.check_required_credentials()
|
|
1916
|
-
# uid is required for some subscriptions only so it's not a part of required credentials
|
|
1917
|
-
if requiresUid:
|
|
1918
|
-
if self.uid is None or len(self.uid) == 0:
|
|
1919
|
-
raise ArgumentsRequired(self.id + ' requires uid to subscribe')
|
|
1920
|
-
idArray = [self.uid]
|
|
1921
|
-
if payload is None:
|
|
1922
|
-
payload = idArray
|
|
1923
|
-
else:
|
|
1924
|
-
payload = self.array_concat(idArray, payload)
|
|
1925
|
-
time = self.seconds()
|
|
1926
|
-
event = 'subscribe'
|
|
1927
|
-
signaturePayload = 'channel=' + channel + '&' + 'event=' + event + '&' + 'time=' + str(time)
|
|
1928
|
-
signature = self.hmac(self.encode(signaturePayload), self.encode(self.secret), hashlib.sha512, 'hex')
|
|
1929
|
-
auth: dict = {
|
|
1930
|
-
'method': 'api_key',
|
|
1931
|
-
'KEY': self.apiKey,
|
|
1932
|
-
'SIGN': signature,
|
|
1933
|
-
}
|
|
1934
|
-
requestId = self.request_id()
|
|
1935
|
-
request: dict = {
|
|
1936
|
-
'id': requestId,
|
|
1937
|
-
'time': time,
|
|
1938
|
-
'channel': channel,
|
|
1939
|
-
'event': event,
|
|
1940
|
-
'auth': auth,
|
|
1941
|
-
}
|
|
1942
|
-
if payload is not None:
|
|
1943
|
-
request['payload'] = payload
|
|
1944
|
-
client = self.client(url)
|
|
1945
|
-
if not (messageHash in client.subscriptions):
|
|
1946
|
-
tempSubscriptionHash = str(requestId)
|
|
1947
|
-
# in case of authenticationError we will throw
|
|
1948
|
-
client.subscriptions[tempSubscriptionHash] = messageHash
|
|
1949
|
-
message = self.extend(request, params)
|
|
1950
|
-
return await self.watch(url, messageHash, message, messageHash, messageHash)
|