bitmex-api 0.0.12__py3-none-any.whl → 0.0.13__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.
Files changed (289) hide show
  1. bitmex/__init__.py +7 -0
  2. bitmex/ccxt/__init__.py +101 -0
  3. bitmex/ccxt/abstract/bitmex.py +97 -0
  4. bitmex/ccxt/async_support/__init__.py +80 -0
  5. bitmex/ccxt/async_support/base/__init__.py +1 -0
  6. bitmex/ccxt/async_support/base/exchange.py +2100 -0
  7. bitmex/ccxt/async_support/base/throttler.py +50 -0
  8. bitmex/ccxt/async_support/base/ws/__init__.py +38 -0
  9. bitmex/ccxt/async_support/base/ws/aiohttp_client.py +147 -0
  10. bitmex/ccxt/async_support/base/ws/cache.py +213 -0
  11. bitmex/ccxt/async_support/base/ws/client.py +214 -0
  12. bitmex/ccxt/async_support/base/ws/fast_client.py +97 -0
  13. bitmex/ccxt/async_support/base/ws/functions.py +59 -0
  14. bitmex/ccxt/async_support/base/ws/future.py +69 -0
  15. bitmex/ccxt/async_support/base/ws/order_book.py +78 -0
  16. bitmex/ccxt/async_support/base/ws/order_book_side.py +174 -0
  17. bitmex/ccxt/async_support/bitmex.py +2932 -0
  18. bitmex/ccxt/base/__init__.py +27 -0
  19. bitmex/ccxt/base/decimal_to_precision.py +174 -0
  20. bitmex/ccxt/base/errors.py +267 -0
  21. bitmex/ccxt/base/exchange.py +6769 -0
  22. bitmex/ccxt/base/precise.py +297 -0
  23. bitmex/ccxt/base/types.py +577 -0
  24. bitmex/ccxt/bitmex.py +2932 -0
  25. bitmex/ccxt/pro/__init__.py +21 -0
  26. bitmex/ccxt/pro/bitmex.py +1697 -0
  27. bitmex/ccxt/static_dependencies/README.md +1 -0
  28. bitmex/ccxt/static_dependencies/__init__.py +1 -0
  29. bitmex/ccxt/static_dependencies/ecdsa/__init__.py +14 -0
  30. bitmex/ccxt/static_dependencies/ecdsa/_version.py +520 -0
  31. bitmex/ccxt/static_dependencies/ecdsa/curves.py +56 -0
  32. bitmex/ccxt/static_dependencies/ecdsa/der.py +221 -0
  33. bitmex/ccxt/static_dependencies/ecdsa/ecdsa.py +310 -0
  34. bitmex/ccxt/static_dependencies/ecdsa/ellipticcurve.py +197 -0
  35. bitmex/ccxt/static_dependencies/ecdsa/keys.py +332 -0
  36. bitmex/ccxt/static_dependencies/ecdsa/numbertheory.py +531 -0
  37. bitmex/ccxt/static_dependencies/ecdsa/rfc6979.py +100 -0
  38. bitmex/ccxt/static_dependencies/ecdsa/util.py +266 -0
  39. bitmex/ccxt/static_dependencies/ethereum/__init__.py +7 -0
  40. bitmex/ccxt/static_dependencies/ethereum/abi/__init__.py +16 -0
  41. bitmex/ccxt/static_dependencies/ethereum/abi/abi.py +19 -0
  42. bitmex/ccxt/static_dependencies/ethereum/abi/base.py +152 -0
  43. bitmex/ccxt/static_dependencies/ethereum/abi/codec.py +217 -0
  44. bitmex/ccxt/static_dependencies/ethereum/abi/constants.py +3 -0
  45. bitmex/ccxt/static_dependencies/ethereum/abi/decoding.py +565 -0
  46. bitmex/ccxt/static_dependencies/ethereum/abi/encoding.py +720 -0
  47. bitmex/ccxt/static_dependencies/ethereum/abi/exceptions.py +139 -0
  48. bitmex/ccxt/static_dependencies/ethereum/abi/grammar.py +443 -0
  49. bitmex/ccxt/static_dependencies/ethereum/abi/packed.py +13 -0
  50. bitmex/ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
  51. bitmex/ccxt/static_dependencies/ethereum/abi/registry.py +643 -0
  52. bitmex/ccxt/static_dependencies/ethereum/abi/tools/__init__.py +3 -0
  53. bitmex/ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +230 -0
  54. bitmex/ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
  55. bitmex/ccxt/static_dependencies/ethereum/abi/utils/numeric.py +83 -0
  56. bitmex/ccxt/static_dependencies/ethereum/abi/utils/padding.py +27 -0
  57. bitmex/ccxt/static_dependencies/ethereum/abi/utils/string.py +19 -0
  58. bitmex/ccxt/static_dependencies/ethereum/account/__init__.py +3 -0
  59. bitmex/ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +4 -0
  60. bitmex/ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +239 -0
  61. bitmex/ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +40 -0
  62. bitmex/ccxt/static_dependencies/ethereum/account/messages.py +263 -0
  63. bitmex/ccxt/static_dependencies/ethereum/account/py.typed +0 -0
  64. bitmex/ccxt/static_dependencies/ethereum/hexbytes/__init__.py +5 -0
  65. bitmex/ccxt/static_dependencies/ethereum/hexbytes/_utils.py +54 -0
  66. bitmex/ccxt/static_dependencies/ethereum/hexbytes/main.py +65 -0
  67. bitmex/ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
  68. bitmex/ccxt/static_dependencies/ethereum/typing/__init__.py +63 -0
  69. bitmex/ccxt/static_dependencies/ethereum/typing/abi.py +6 -0
  70. bitmex/ccxt/static_dependencies/ethereum/typing/bls.py +7 -0
  71. bitmex/ccxt/static_dependencies/ethereum/typing/discovery.py +5 -0
  72. bitmex/ccxt/static_dependencies/ethereum/typing/encoding.py +7 -0
  73. bitmex/ccxt/static_dependencies/ethereum/typing/enums.py +17 -0
  74. bitmex/ccxt/static_dependencies/ethereum/typing/ethpm.py +9 -0
  75. bitmex/ccxt/static_dependencies/ethereum/typing/evm.py +20 -0
  76. bitmex/ccxt/static_dependencies/ethereum/typing/networks.py +1122 -0
  77. bitmex/ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
  78. bitmex/ccxt/static_dependencies/ethereum/utils/__init__.py +115 -0
  79. bitmex/ccxt/static_dependencies/ethereum/utils/abi.py +72 -0
  80. bitmex/ccxt/static_dependencies/ethereum/utils/address.py +171 -0
  81. bitmex/ccxt/static_dependencies/ethereum/utils/applicators.py +151 -0
  82. bitmex/ccxt/static_dependencies/ethereum/utils/conversions.py +190 -0
  83. bitmex/ccxt/static_dependencies/ethereum/utils/currency.py +107 -0
  84. bitmex/ccxt/static_dependencies/ethereum/utils/curried/__init__.py +269 -0
  85. bitmex/ccxt/static_dependencies/ethereum/utils/debug.py +20 -0
  86. bitmex/ccxt/static_dependencies/ethereum/utils/decorators.py +132 -0
  87. bitmex/ccxt/static_dependencies/ethereum/utils/encoding.py +6 -0
  88. bitmex/ccxt/static_dependencies/ethereum/utils/exceptions.py +4 -0
  89. bitmex/ccxt/static_dependencies/ethereum/utils/functional.py +75 -0
  90. bitmex/ccxt/static_dependencies/ethereum/utils/hexadecimal.py +74 -0
  91. bitmex/ccxt/static_dependencies/ethereum/utils/humanize.py +188 -0
  92. bitmex/ccxt/static_dependencies/ethereum/utils/logging.py +159 -0
  93. bitmex/ccxt/static_dependencies/ethereum/utils/module_loading.py +31 -0
  94. bitmex/ccxt/static_dependencies/ethereum/utils/numeric.py +43 -0
  95. bitmex/ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
  96. bitmex/ccxt/static_dependencies/ethereum/utils/toolz.py +76 -0
  97. bitmex/ccxt/static_dependencies/ethereum/utils/types.py +54 -0
  98. bitmex/ccxt/static_dependencies/ethereum/utils/typing/__init__.py +18 -0
  99. bitmex/ccxt/static_dependencies/ethereum/utils/typing/misc.py +14 -0
  100. bitmex/ccxt/static_dependencies/ethereum/utils/units.py +31 -0
  101. bitmex/ccxt/static_dependencies/keccak/__init__.py +3 -0
  102. bitmex/ccxt/static_dependencies/keccak/keccak.py +197 -0
  103. bitmex/ccxt/static_dependencies/lark/__init__.py +38 -0
  104. bitmex/ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  105. bitmex/ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  106. bitmex/ccxt/static_dependencies/lark/ast_utils.py +59 -0
  107. bitmex/ccxt/static_dependencies/lark/common.py +86 -0
  108. bitmex/ccxt/static_dependencies/lark/exceptions.py +292 -0
  109. bitmex/ccxt/static_dependencies/lark/grammar.py +130 -0
  110. bitmex/ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  111. bitmex/ccxt/static_dependencies/lark/grammars/common.lark +59 -0
  112. bitmex/ccxt/static_dependencies/lark/grammars/lark.lark +62 -0
  113. bitmex/ccxt/static_dependencies/lark/grammars/python.lark +302 -0
  114. bitmex/ccxt/static_dependencies/lark/grammars/unicode.lark +7 -0
  115. bitmex/ccxt/static_dependencies/lark/indenter.py +143 -0
  116. bitmex/ccxt/static_dependencies/lark/lark.py +658 -0
  117. bitmex/ccxt/static_dependencies/lark/lexer.py +678 -0
  118. bitmex/ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  119. bitmex/ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  120. bitmex/ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  121. bitmex/ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  122. bitmex/ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  123. bitmex/ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  124. bitmex/ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  125. bitmex/ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  126. bitmex/ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  127. bitmex/ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  128. bitmex/ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  129. bitmex/ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  130. bitmex/ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  131. bitmex/ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  132. bitmex/ccxt/static_dependencies/lark/py.typed +0 -0
  133. bitmex/ccxt/static_dependencies/lark/reconstruct.py +107 -0
  134. bitmex/ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  135. bitmex/ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  136. bitmex/ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  137. bitmex/ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  138. bitmex/ccxt/static_dependencies/lark/tree.py +267 -0
  139. bitmex/ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  140. bitmex/ccxt/static_dependencies/lark/tree_templates.py +180 -0
  141. bitmex/ccxt/static_dependencies/lark/utils.py +343 -0
  142. bitmex/ccxt/static_dependencies/lark/visitors.py +596 -0
  143. bitmex/ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  144. bitmex/ccxt/static_dependencies/marshmallow/base.py +65 -0
  145. bitmex/ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  146. bitmex/ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  147. bitmex/ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  148. bitmex/ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  149. bitmex/ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  150. bitmex/ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  151. bitmex/ccxt/static_dependencies/marshmallow/py.typed +0 -0
  152. bitmex/ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  153. bitmex/ccxt/static_dependencies/marshmallow/types.py +12 -0
  154. bitmex/ccxt/static_dependencies/marshmallow/utils.py +378 -0
  155. bitmex/ccxt/static_dependencies/marshmallow/validate.py +678 -0
  156. bitmex/ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  157. bitmex/ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  158. bitmex/ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  159. bitmex/ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  160. bitmex/ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  161. bitmex/ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  162. bitmex/ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  163. bitmex/ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  164. bitmex/ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  165. bitmex/ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  166. bitmex/ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  167. bitmex/ccxt/static_dependencies/msgpack/__init__.py +55 -0
  168. bitmex/ccxt/static_dependencies/msgpack/_cmsgpack.pyx +11 -0
  169. bitmex/ccxt/static_dependencies/msgpack/_packer.pyx +374 -0
  170. bitmex/ccxt/static_dependencies/msgpack/_unpacker.pyx +547 -0
  171. bitmex/ccxt/static_dependencies/msgpack/buff_converter.h +8 -0
  172. bitmex/ccxt/static_dependencies/msgpack/exceptions.py +48 -0
  173. bitmex/ccxt/static_dependencies/msgpack/ext.py +168 -0
  174. bitmex/ccxt/static_dependencies/msgpack/fallback.py +951 -0
  175. bitmex/ccxt/static_dependencies/msgpack/pack.h +89 -0
  176. bitmex/ccxt/static_dependencies/msgpack/pack_template.h +820 -0
  177. bitmex/ccxt/static_dependencies/msgpack/sysdep.h +194 -0
  178. bitmex/ccxt/static_dependencies/msgpack/unpack.h +391 -0
  179. bitmex/ccxt/static_dependencies/msgpack/unpack_define.h +95 -0
  180. bitmex/ccxt/static_dependencies/msgpack/unpack_template.h +464 -0
  181. bitmex/ccxt/static_dependencies/parsimonious/__init__.py +10 -0
  182. bitmex/ccxt/static_dependencies/parsimonious/exceptions.py +105 -0
  183. bitmex/ccxt/static_dependencies/parsimonious/expressions.py +479 -0
  184. bitmex/ccxt/static_dependencies/parsimonious/grammar.py +487 -0
  185. bitmex/ccxt/static_dependencies/parsimonious/nodes.py +325 -0
  186. bitmex/ccxt/static_dependencies/parsimonious/utils.py +40 -0
  187. bitmex/ccxt/static_dependencies/starknet/__init__.py +0 -0
  188. bitmex/ccxt/static_dependencies/starknet/abi/v0/__init__.py +2 -0
  189. bitmex/ccxt/static_dependencies/starknet/abi/v0/model.py +44 -0
  190. bitmex/ccxt/static_dependencies/starknet/abi/v0/parser.py +216 -0
  191. bitmex/ccxt/static_dependencies/starknet/abi/v0/schemas.py +72 -0
  192. bitmex/ccxt/static_dependencies/starknet/abi/v0/shape.py +63 -0
  193. bitmex/ccxt/static_dependencies/starknet/abi/v1/__init__.py +2 -0
  194. bitmex/ccxt/static_dependencies/starknet/abi/v1/core_structures.json +14 -0
  195. bitmex/ccxt/static_dependencies/starknet/abi/v1/model.py +39 -0
  196. bitmex/ccxt/static_dependencies/starknet/abi/v1/parser.py +220 -0
  197. bitmex/ccxt/static_dependencies/starknet/abi/v1/parser_transformer.py +179 -0
  198. bitmex/ccxt/static_dependencies/starknet/abi/v1/schemas.py +66 -0
  199. bitmex/ccxt/static_dependencies/starknet/abi/v1/shape.py +47 -0
  200. bitmex/ccxt/static_dependencies/starknet/abi/v2/__init__.py +2 -0
  201. bitmex/ccxt/static_dependencies/starknet/abi/v2/model.py +89 -0
  202. bitmex/ccxt/static_dependencies/starknet/abi/v2/parser.py +293 -0
  203. bitmex/ccxt/static_dependencies/starknet/abi/v2/parser_transformer.py +192 -0
  204. bitmex/ccxt/static_dependencies/starknet/abi/v2/schemas.py +132 -0
  205. bitmex/ccxt/static_dependencies/starknet/abi/v2/shape.py +107 -0
  206. bitmex/ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  207. bitmex/ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  208. bitmex/ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  209. bitmex/ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  210. bitmex/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  211. bitmex/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  212. bitmex/ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  213. bitmex/ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  214. bitmex/ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  215. bitmex/ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  216. bitmex/ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  217. bitmex/ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  218. bitmex/ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  219. bitmex/ccxt/static_dependencies/starknet/common.py +15 -0
  220. bitmex/ccxt/static_dependencies/starknet/constants.py +39 -0
  221. bitmex/ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  222. bitmex/ccxt/static_dependencies/starknet/hash/address.py +79 -0
  223. bitmex/ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  224. bitmex/ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  225. bitmex/ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  226. bitmex/ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  227. bitmex/ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  228. bitmex/ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  229. bitmex/ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  230. bitmex/ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  231. bitmex/ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  232. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  233. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  234. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  235. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  236. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  237. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  238. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  239. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  240. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  241. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  242. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  243. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  244. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  245. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  246. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  247. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  248. bitmex/ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  249. bitmex/ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  250. bitmex/ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  251. bitmex/ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  252. bitmex/ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  253. bitmex/ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  254. bitmex/ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  255. bitmex/ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  256. bitmex/ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  257. bitmex/ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  258. bitmex/ccxt/static_dependencies/starkware/__init__.py +0 -0
  259. bitmex/ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  260. bitmex/ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  261. bitmex/ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  262. bitmex/ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  263. bitmex/ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  264. bitmex/ccxt/static_dependencies/sympy/__init__.py +0 -0
  265. bitmex/ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  266. bitmex/ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  267. bitmex/ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  268. bitmex/ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  269. bitmex/ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  270. bitmex/ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  271. bitmex/ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  272. bitmex/ccxt/static_dependencies/toolz/__init__.py +26 -0
  273. bitmex/ccxt/static_dependencies/toolz/_signatures.py +784 -0
  274. bitmex/ccxt/static_dependencies/toolz/_version.py +520 -0
  275. bitmex/ccxt/static_dependencies/toolz/compatibility.py +30 -0
  276. bitmex/ccxt/static_dependencies/toolz/curried/__init__.py +101 -0
  277. bitmex/ccxt/static_dependencies/toolz/curried/exceptions.py +22 -0
  278. bitmex/ccxt/static_dependencies/toolz/curried/operator.py +22 -0
  279. bitmex/ccxt/static_dependencies/toolz/dicttoolz.py +339 -0
  280. bitmex/ccxt/static_dependencies/toolz/functoolz.py +1049 -0
  281. bitmex/ccxt/static_dependencies/toolz/itertoolz.py +1057 -0
  282. bitmex/ccxt/static_dependencies/toolz/recipes.py +46 -0
  283. bitmex/ccxt/static_dependencies/toolz/utils.py +9 -0
  284. bitmex/ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  285. bitmex/ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  286. {bitmex_api-0.0.12.dist-info → bitmex_api-0.0.13.dist-info}/METADATA +1 -1
  287. bitmex_api-0.0.13.dist-info/RECORD +288 -0
  288. bitmex_api-0.0.12.dist-info/RECORD +0 -3
  289. {bitmex_api-0.0.12.dist-info → bitmex_api-0.0.13.dist-info}/WHEEL +0 -0
@@ -0,0 +1,1697 @@
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, Order, OrderBook, 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 RateLimitExceeded
15
+
16
+
17
+ from ccxt.async_support import bitmex as bitmexAsync
18
+
19
+
20
+ class bitmex(bitmexAsync):
21
+
22
+ def describe(self) -> Any:
23
+ return self.deep_extend(super(bitmex, self).describe(), {
24
+ 'has': {
25
+ 'ws': True,
26
+ 'watchBalance': True,
27
+ 'watchLiquidations': True,
28
+ 'watchLiquidationsForSymbols': True,
29
+ 'watchMyLiquidations': None,
30
+ 'watchMyLiquidationsForSymbols': None,
31
+ 'watchMyTrades': True,
32
+ 'watchOHLCV': True,
33
+ 'watchOrderBook': True,
34
+ 'watchOrderBookForSymbols': True,
35
+ 'watchOrders': True,
36
+ 'watchPostions': True,
37
+ 'watchTicker': True,
38
+ 'watchTickers': True,
39
+ 'watchTrades': True,
40
+ 'watchTradesForSymbols': True,
41
+ },
42
+ 'urls': {
43
+ 'test': {
44
+ 'ws': 'wss://ws.testnet.bitmex.com/realtime',
45
+ },
46
+ 'api': {
47
+ 'ws': 'wss://ws.bitmex.com/realtime',
48
+ },
49
+ },
50
+ # 'versions': {
51
+ # 'ws': '0.2.0',
52
+ # },
53
+ 'options': {
54
+ 'watchOrderBookLevel': 'orderBookL2', # 'orderBookL2' = L2 full order book, 'orderBookL2_25' = L2 top 25, 'orderBook10' L3 top 10
55
+ 'tradesLimit': 1000,
56
+ 'OHLCVLimit': 1000,
57
+ },
58
+ 'exceptions': {
59
+ 'ws': {
60
+ 'exact': {
61
+ },
62
+ 'broad': {
63
+ 'Rate limit exceeded': RateLimitExceeded,
64
+ },
65
+ },
66
+ },
67
+ })
68
+
69
+ async def watch_ticker(self, symbol: str, params={}) -> Ticker:
70
+ """
71
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
72
+
73
+ https://www.bitmex.com/app/wsAPI#Subscriptions
74
+
75
+ :param str symbol: unified symbol of the market to fetch the ticker for
76
+ :param dict [params]: extra parameters specific to the exchange API endpoint
77
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
78
+ """
79
+ await self.load_markets()
80
+ symbol = self.symbol(symbol)
81
+ tickers = await self.watch_tickers([symbol], params)
82
+ return tickers[symbol]
83
+
84
+ async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
85
+ """
86
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
87
+
88
+ https://www.bitmex.com/app/wsAPI#Subscriptions
89
+
90
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
91
+ :param dict [params]: extra parameters specific to the exchange API endpoint
92
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
93
+ """
94
+ await self.load_markets()
95
+ symbols = self.market_symbols(symbols, None, True)
96
+ name = 'instrument'
97
+ url = self.urls['api']['ws']
98
+ messageHashes = []
99
+ rawSubscriptions = []
100
+ if symbols is not None:
101
+ for i in range(0, len(symbols)):
102
+ symbol = symbols[i]
103
+ market = self.market(symbol)
104
+ subscription = name + ':' + market['id']
105
+ rawSubscriptions.append(subscription)
106
+ messageHash = 'ticker:' + symbol
107
+ messageHashes.append(messageHash)
108
+ else:
109
+ rawSubscriptions.append(name)
110
+ messageHashes.append('alltickers')
111
+ request: dict = {
112
+ 'op': 'subscribe',
113
+ 'args': rawSubscriptions,
114
+ }
115
+ ticker = await self.watch_multiple(url, messageHashes, self.extend(request, params), rawSubscriptions)
116
+ if self.newUpdates:
117
+ result: dict = {}
118
+ result[ticker['symbol']] = ticker
119
+ return result
120
+ return self.filter_by_array(self.tickers, 'symbol', symbols)
121
+
122
+ def handle_ticker(self, client: Client, message):
123
+ #
124
+ # {
125
+ # "table": "instrument",
126
+ # "action": "partial",
127
+ # "keys": ["symbol"],
128
+ # "types": {
129
+ # "symbol": "symbol",
130
+ # "rootSymbol": "symbol",
131
+ # "state": "symbol",
132
+ # "typ": "symbol",
133
+ # "listing": "timestamp",
134
+ # "front": "timestamp",
135
+ # "expiry": "timestamp",
136
+ # "settle": "timestamp",
137
+ # "relistInterval": "timespan",
138
+ # "inverseLeg": "symbol",
139
+ # "sellLeg": "symbol",
140
+ # "buyLeg": "symbol",
141
+ # "optionStrikePcnt": "float",
142
+ # "optionStrikeRound": "float",
143
+ # "optionStrikePrice": "float",
144
+ # "optionMultiplier": "float",
145
+ # "positionCurrency": "symbol",
146
+ # "underlying": "symbol",
147
+ # "quoteCurrency": "symbol",
148
+ # "underlyingSymbol": "symbol",
149
+ # "reference": "symbol",
150
+ # "referenceSymbol": "symbol",
151
+ # "calcInterval": "timespan",
152
+ # "publishInterval": "timespan",
153
+ # "publishTime": "timespan",
154
+ # "maxOrderQty": "long",
155
+ # "maxPrice": "float",
156
+ # "lotSize": "long",
157
+ # "tickSize": "float",
158
+ # "multiplier": "long",
159
+ # "settlCurrency": "symbol",
160
+ # "underlyingToPositionMultiplier": "long",
161
+ # "underlyingToSettleMultiplier": "long",
162
+ # "quoteToSettleMultiplier": "long",
163
+ # "isQuanto": "boolean",
164
+ # "isInverse": "boolean",
165
+ # "initMargin": "float",
166
+ # "maintMargin": "float",
167
+ # "riskLimit": "long",
168
+ # "riskStep": "long",
169
+ # "limit": "float",
170
+ # "capped": "boolean",
171
+ # "taxed": "boolean",
172
+ # "deleverage": "boolean",
173
+ # "makerFee": "float",
174
+ # "takerFee": "float",
175
+ # "settlementFee": "float",
176
+ # "insuranceFee": "float",
177
+ # "fundingBaseSymbol": "symbol",
178
+ # "fundingQuoteSymbol": "symbol",
179
+ # "fundingPremiumSymbol": "symbol",
180
+ # "fundingTimestamp": "timestamp",
181
+ # "fundingInterval": "timespan",
182
+ # "fundingRate": "float",
183
+ # "indicativeFundingRate": "float",
184
+ # "rebalanceTimestamp": "timestamp",
185
+ # "rebalanceInterval": "timespan",
186
+ # "openingTimestamp": "timestamp",
187
+ # "closingTimestamp": "timestamp",
188
+ # "sessionInterval": "timespan",
189
+ # "prevClosePrice": "float",
190
+ # "limitDownPrice": "float",
191
+ # "limitUpPrice": "float",
192
+ # "bankruptLimitDownPrice": "float",
193
+ # "bankruptLimitUpPrice": "float",
194
+ # "prevTotalVolume": "long",
195
+ # "totalVolume": "long",
196
+ # "volume": "long",
197
+ # "volume24h": "long",
198
+ # "prevTotalTurnover": "long",
199
+ # "totalTurnover": "long",
200
+ # "turnover": "long",
201
+ # "turnover24h": "long",
202
+ # "homeNotional24h": "float",
203
+ # "foreignNotional24h": "float",
204
+ # "prevPrice24h": "float",
205
+ # "vwap": "float",
206
+ # "highPrice": "float",
207
+ # "lowPrice": "float",
208
+ # "lastPrice": "float",
209
+ # "lastPriceProtected": "float",
210
+ # "lastTickDirection": "symbol",
211
+ # "lastChangePcnt": "float",
212
+ # "bidPrice": "float",
213
+ # "midPrice": "float",
214
+ # "askPrice": "float",
215
+ # "impactBidPrice": "float",
216
+ # "impactMidPrice": "float",
217
+ # "impactAskPrice": "float",
218
+ # "hasLiquidity": "boolean",
219
+ # "openInterest": "long",
220
+ # "openValue": "long",
221
+ # "fairMethod": "symbol",
222
+ # "fairBasisRate": "float",
223
+ # "fairBasis": "float",
224
+ # "fairPrice": "float",
225
+ # "markMethod": "symbol",
226
+ # "markPrice": "float",
227
+ # "indicativeTaxRate": "float",
228
+ # "indicativeSettlePrice": "float",
229
+ # "optionUnderlyingPrice": "float",
230
+ # "settledPrice": "float",
231
+ # "timestamp": "timestamp"
232
+ # },
233
+ # "foreignKeys": {
234
+ # "inverseLeg": "instrument",
235
+ # "sellLeg": "instrument",
236
+ # "buyLeg": "instrument"
237
+ # },
238
+ # "attributes": {symbol: "unique"},
239
+ # "filter": {symbol: "XBTUSD"},
240
+ # "data": [
241
+ # {
242
+ # "symbol": "XBTUSD",
243
+ # "rootSymbol": "XBT",
244
+ # "state": "Open",
245
+ # "typ": "FFWCSX",
246
+ # "listing": "2016-05-13T12:00:00.000Z",
247
+ # "front": "2016-05-13T12:00:00.000Z",
248
+ # "expiry": null,
249
+ # "settle": null,
250
+ # "relistInterval": null,
251
+ # "inverseLeg": '',
252
+ # "sellLeg": '',
253
+ # "buyLeg": '',
254
+ # "optionStrikePcnt": null,
255
+ # "optionStrikeRound": null,
256
+ # "optionStrikePrice": null,
257
+ # "optionMultiplier": null,
258
+ # "positionCurrency": "USD",
259
+ # "underlying": "XBT",
260
+ # "quoteCurrency": "USD",
261
+ # "underlyingSymbol": "XBT=",
262
+ # "reference": "BMEX",
263
+ # "referenceSymbol": ".BXBT",
264
+ # "calcInterval": null,
265
+ # "publishInterval": null,
266
+ # "publishTime": null,
267
+ # "maxOrderQty": 10000000,
268
+ # "maxPrice": 1000000,
269
+ # "lotSize": 1,
270
+ # "tickSize": 0.5,
271
+ # "multiplier": -100000000,
272
+ # "settlCurrency": "XBt",
273
+ # "underlyingToPositionMultiplier": null,
274
+ # "underlyingToSettleMultiplier": -100000000,
275
+ # "quoteToSettleMultiplier": null,
276
+ # "isQuanto": False,
277
+ # "isInverse": True,
278
+ # "initMargin": 0.01,
279
+ # "maintMargin": 0.005,
280
+ # "riskLimit": 20000000000,
281
+ # "riskStep": 10000000000,
282
+ # "limit": null,
283
+ # "capped": False,
284
+ # "taxed": True,
285
+ # "deleverage": True,
286
+ # "makerFee": -0.00025,
287
+ # "takerFee": 0.00075,
288
+ # "settlementFee": 0,
289
+ # "insuranceFee": 0,
290
+ # "fundingBaseSymbol": ".XBTBON8H",
291
+ # "fundingQuoteSymbol": ".USDBON8H",
292
+ # "fundingPremiumSymbol": ".XBTUSDPI8H",
293
+ # "fundingTimestamp": "2020-01-29T12:00:00.000Z",
294
+ # "fundingInterval": "2000-01-01T08:00:00.000Z",
295
+ # "fundingRate": 0.000597,
296
+ # "indicativeFundingRate": 0.000652,
297
+ # "rebalanceTimestamp": null,
298
+ # "rebalanceInterval": null,
299
+ # "openingTimestamp": "2020-01-29T11:00:00.000Z",
300
+ # "closingTimestamp": "2020-01-29T12:00:00.000Z",
301
+ # "sessionInterval": "2000-01-01T01:00:00.000Z",
302
+ # "prevClosePrice": 9063.96,
303
+ # "limitDownPrice": null,
304
+ # "limitUpPrice": null,
305
+ # "bankruptLimitDownPrice": null,
306
+ # "bankruptLimitUpPrice": null,
307
+ # "prevTotalVolume": 1989881049026,
308
+ # "totalVolume": 1990196740950,
309
+ # "volume": 315691924,
310
+ # "volume24h": 4491824765,
311
+ # "prevTotalTurnover": 27865497128425564,
312
+ # "totalTurnover": 27868891594857150,
313
+ # "turnover": 3394466431587,
314
+ # "turnover24h": 48863390064843,
315
+ # "homeNotional24h": 488633.9006484273,
316
+ # "foreignNotional24h": 4491824765,
317
+ # "prevPrice24h": 9091,
318
+ # "vwap": 9192.8663,
319
+ # "highPrice": 9440,
320
+ # "lowPrice": 8886,
321
+ # "lastPrice": 9287,
322
+ # "lastPriceProtected": 9287,
323
+ # "lastTickDirection": "PlusTick",
324
+ # "lastChangePcnt": 0.0216,
325
+ # "bidPrice": 9286,
326
+ # "midPrice": 9286.25,
327
+ # "askPrice": 9286.5,
328
+ # "impactBidPrice": 9285.9133,
329
+ # "impactMidPrice": 9286.75,
330
+ # "impactAskPrice": 9287.6382,
331
+ # "hasLiquidity": True,
332
+ # "openInterest": 967826984,
333
+ # "openValue": 10432207060536,
334
+ # "fairMethod": "FundingRate",
335
+ # "fairBasisRate": 0.6537149999999999,
336
+ # "fairBasis": 0.33,
337
+ # "fairPrice": 9277.2,
338
+ # "markMethod": "FairPrice",
339
+ # "markPrice": 9277.2,
340
+ # "indicativeTaxRate": 0,
341
+ # "indicativeSettlePrice": 9276.87,
342
+ # "optionUnderlyingPrice": null,
343
+ # "settledPrice": null,
344
+ # "timestamp": "2020-01-29T11:31:37.114Z"
345
+ # }
346
+ # ]
347
+ # }
348
+ #
349
+ data = self.safe_list(message, 'data', [])
350
+ tickers: dict = {}
351
+ for i in range(0, len(data)):
352
+ update = data[i]
353
+ marketId = self.safe_string(update, 'symbol')
354
+ symbol = self.safe_symbol(marketId)
355
+ if not (symbol in self.tickers):
356
+ self.tickers[symbol] = self.parse_ticker({})
357
+ updatedTicker = self.parse_ticker(update)
358
+ fullParsedTicker = self.deep_extend(self.tickers[symbol], updatedTicker)
359
+ tickers[symbol] = fullParsedTicker
360
+ self.tickers[symbol] = fullParsedTicker
361
+ messageHash = 'ticker:' + symbol
362
+ client.resolve(fullParsedTicker, messageHash)
363
+ client.resolve(fullParsedTicker, 'alltickers')
364
+ return message
365
+
366
+ async def watch_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
367
+ """
368
+ watch the public liquidations of a trading pair
369
+
370
+ https://www.bitmex.com/app/wsAPI#Liquidation
371
+
372
+ :param str symbol: unified CCXT market symbol
373
+ :param int [since]: the earliest time in ms to fetch liquidations for
374
+ :param int [limit]: the maximum number of liquidation structures to retrieve
375
+ :param dict [params]: exchange specific parameters for the bitmex api endpoint
376
+ :returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
377
+ """
378
+ return self.watch_liquidations_for_symbols([symbol], since, limit, params)
379
+
380
+ async def watch_liquidations_for_symbols(self, symbols: List[str] = None, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
381
+ """
382
+ watch the public liquidations of a trading pair
383
+
384
+ https://www.bitmex.com/app/wsAPI#Liquidation
385
+
386
+ :param str[] symbols:
387
+ :param int [since]: the earliest time in ms to fetch liquidations for
388
+ :param int [limit]: the maximum number of liquidation structures to retrieve
389
+ :param dict [params]: exchange specific parameters for the bitmex api endpoint
390
+ :returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
391
+ """
392
+ await self.load_markets()
393
+ symbols = self.market_symbols(symbols, None, True, True)
394
+ messageHashes = []
395
+ subscriptionHashes = []
396
+ if self.is_empty(symbols):
397
+ subscriptionHashes.append('liquidation')
398
+ messageHashes.append('liquidations')
399
+ else:
400
+ for i in range(0, len(symbols)):
401
+ symbol = symbols[i]
402
+ market = self.market(symbol)
403
+ subscriptionHashes.append('liquidation:' + market['id'])
404
+ messageHashes.append('liquidations::' + symbol)
405
+ url = self.urls['api']['ws']
406
+ request = {
407
+ 'op': 'subscribe',
408
+ 'args': subscriptionHashes,
409
+ }
410
+ newLiquidations = await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), subscriptionHashes)
411
+ if self.newUpdates:
412
+ return newLiquidations
413
+ return self.filter_by_symbols_since_limit(self.liquidations, symbols, since, limit, True)
414
+
415
+ def handle_liquidation(self, client: Client, message):
416
+ #
417
+ # {
418
+ # "table":"liquidation",
419
+ # "action":"partial",
420
+ # "keys":[
421
+ # "orderID"
422
+ # ],
423
+ # "types":{
424
+ # "orderID":"guid",
425
+ # "symbol":"symbol",
426
+ # "side":"symbol",
427
+ # "price":"float",
428
+ # "leavesQty":"long"
429
+ # },
430
+ # "filter":{},
431
+ # "data":[
432
+ # {
433
+ # "orderID":"e0a568ee-7830-4428-92c3-73e82b9576ce",
434
+ # "symbol":"XPLAUSDT",
435
+ # "side":"Sell",
436
+ # "price":0.206,
437
+ # "leavesQty":340
438
+ # }
439
+ # ]
440
+ # }
441
+ #
442
+ rawLiquidations = self.safe_value(message, 'data', [])
443
+ newLiquidations = []
444
+ for i in range(0, len(rawLiquidations)):
445
+ rawLiquidation = rawLiquidations[i]
446
+ liquidation = self.parse_liquidation(rawLiquidation)
447
+ symbol = liquidation['symbol']
448
+ liquidations = self.safe_value(self.liquidations, symbol)
449
+ if liquidations is None:
450
+ limit = self.safe_integer(self.options, 'liquidationsLimit', 1000)
451
+ liquidations = ArrayCache(limit)
452
+ liquidations.append(liquidation)
453
+ self.liquidations[symbol] = liquidations
454
+ newLiquidations.append(liquidation)
455
+ client.resolve(newLiquidations, 'liquidations')
456
+ liquidationsBySymbol = self.index_by(newLiquidations, 'symbol')
457
+ symbols = list(liquidationsBySymbol.keys())
458
+ for i in range(0, len(symbols)):
459
+ symbol = symbols[i]
460
+ client.resolve(liquidationsBySymbol[symbol], 'liquidations::' + symbol)
461
+
462
+ async def watch_balance(self, params={}) -> Balances:
463
+ """
464
+ watch balance and get the amount of funds available for trading or funds locked in orders
465
+
466
+ https://www.bitmex.com/app/wsAPI#Subscriptions
467
+
468
+ :param dict [params]: extra parameters specific to the exchange API endpoint
469
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
470
+ """
471
+ await self.load_markets()
472
+ await self.authenticate()
473
+ messageHash = 'margin'
474
+ url = self.urls['api']['ws']
475
+ request: dict = {
476
+ 'op': 'subscribe',
477
+ 'args': [
478
+ messageHash,
479
+ ],
480
+ }
481
+ return await self.watch(url, messageHash, self.extend(request, params), messageHash)
482
+
483
+ def handle_balance(self, client: Client, message):
484
+ #
485
+ # {
486
+ # "table": "margin",
487
+ # "action": "partial",
488
+ # "keys": ["account"],
489
+ # "types": {
490
+ # "account": "long",
491
+ # "currency": "symbol",
492
+ # "riskLimit": "long",
493
+ # "prevState": "symbol",
494
+ # "state": "symbol",
495
+ # "action": "symbol",
496
+ # "amount": "long",
497
+ # "pendingCredit": "long",
498
+ # "pendingDebit": "long",
499
+ # "confirmedDebit": "long",
500
+ # "prevRealisedPnl": "long",
501
+ # "prevUnrealisedPnl": "long",
502
+ # "grossComm": "long",
503
+ # "grossOpenCost": "long",
504
+ # "grossOpenPremium": "long",
505
+ # "grossExecCost": "long",
506
+ # "grossMarkValue": "long",
507
+ # "riskValue": "long",
508
+ # "taxableMargin": "long",
509
+ # "initMargin": "long",
510
+ # "maintMargin": "long",
511
+ # "sessionMargin": "long",
512
+ # "targetExcessMargin": "long",
513
+ # "varMargin": "long",
514
+ # "realisedPnl": "long",
515
+ # "unrealisedPnl": "long",
516
+ # "indicativeTax": "long",
517
+ # "unrealisedProfit": "long",
518
+ # "syntheticMargin": "long",
519
+ # "walletBalance": "long",
520
+ # "marginBalance": "long",
521
+ # "marginBalancePcnt": "float",
522
+ # "marginLeverage": "float",
523
+ # "marginUsedPcnt": "float",
524
+ # "excessMargin": "long",
525
+ # "excessMarginPcnt": "float",
526
+ # "availableMargin": "long",
527
+ # "withdrawableMargin": "long",
528
+ # "timestamp": "timestamp",
529
+ # "grossLastValue": "long",
530
+ # "commission": "float"
531
+ # },
532
+ # "foreignKeys": {},
533
+ # "attributes": {account: "sorted"},
534
+ # "filter": {account: 1455728},
535
+ # "data": [
536
+ # {
537
+ # "account": 1455728,
538
+ # "currency": "XBt",
539
+ # "riskLimit": 1000000000000,
540
+ # "prevState": '',
541
+ # "state": '',
542
+ # "action": '',
543
+ # "amount": 263542,
544
+ # "pendingCredit": 0,
545
+ # "pendingDebit": 0,
546
+ # "confirmedDebit": 0,
547
+ # "prevRealisedPnl": 0,
548
+ # "prevUnrealisedPnl": 0,
549
+ # "grossComm": 0,
550
+ # "grossOpenCost": 0,
551
+ # "grossOpenPremium": 0,
552
+ # "grossExecCost": 0,
553
+ # "grossMarkValue": 0,
554
+ # "riskValue": 0,
555
+ # "taxableMargin": 0,
556
+ # "initMargin": 0,
557
+ # "maintMargin": 0,
558
+ # "sessionMargin": 0,
559
+ # "targetExcessMargin": 0,
560
+ # "varMargin": 0,
561
+ # "realisedPnl": 0,
562
+ # "unrealisedPnl": 0,
563
+ # "indicativeTax": 0,
564
+ # "unrealisedProfit": 0,
565
+ # "syntheticMargin": null,
566
+ # "walletBalance": 263542,
567
+ # "marginBalance": 263542,
568
+ # "marginBalancePcnt": 1,
569
+ # "marginLeverage": 0,
570
+ # "marginUsedPcnt": 0,
571
+ # "excessMargin": 263542,
572
+ # "excessMarginPcnt": 1,
573
+ # "availableMargin": 263542,
574
+ # "withdrawableMargin": 263542,
575
+ # "timestamp": "2020-08-03T12:01:01.246Z",
576
+ # "grossLastValue": 0,
577
+ # "commission": null
578
+ # }
579
+ # ]
580
+ # }
581
+ #
582
+ data = self.safe_value(message, 'data')
583
+ balance = self.parse_balance(data)
584
+ self.balance = self.extend(self.balance, balance)
585
+ messageHash = self.safe_string(message, 'table')
586
+ client.resolve(self.balance, messageHash)
587
+
588
+ def handle_trades(self, client: Client, message):
589
+ #
590
+ # initial snapshot
591
+ #
592
+ # {
593
+ # "table": "trade",
594
+ # "action": "partial",
595
+ # "keys": [],
596
+ # "types": {
597
+ # "timestamp": "timestamp",
598
+ # "symbol": "symbol",
599
+ # "side": "symbol",
600
+ # "size": "long",
601
+ # "price": "float",
602
+ # "tickDirection": "symbol",
603
+ # "trdMatchID": "guid",
604
+ # "grossValue": "long",
605
+ # "homeNotional": "float",
606
+ # "foreignNotional": "float"
607
+ # },
608
+ # "foreignKeys": {symbol: "instrument", side: "side"},
609
+ # "attributes": {timestamp: "sorted", symbol: "grouped"},
610
+ # "filter": {symbol: "XBTUSD"},
611
+ # "data": [
612
+ # {
613
+ # "timestamp": "2020-01-30T17:03:07.854Z",
614
+ # "symbol": "XBTUSD",
615
+ # "side": "Buy",
616
+ # "size": 15000,
617
+ # "price": 9378,
618
+ # "tickDirection": "ZeroPlusTick",
619
+ # "trdMatchID": "5b426e7f-83d1-2c80-295d-ee995b8ceb4a",
620
+ # "grossValue": 159945000,
621
+ # "homeNotional": 1.59945,
622
+ # "foreignNotional": 15000
623
+ # }
624
+ # ]
625
+ # }
626
+ #
627
+ # updates
628
+ #
629
+ # {
630
+ # "table": "trade",
631
+ # "action": "insert",
632
+ # "data": [
633
+ # {
634
+ # "timestamp": "2020-01-30T17:31:40.160Z",
635
+ # "symbol": "XBTUSD",
636
+ # "side": "Sell",
637
+ # "size": 37412,
638
+ # "price": 9521.5,
639
+ # "tickDirection": "ZeroMinusTick",
640
+ # "trdMatchID": "a4bfc6bc-6cf1-1a11-622e-270eef8ca5c7",
641
+ # "grossValue": 392938236,
642
+ # "homeNotional": 3.92938236,
643
+ # "foreignNotional": 37412
644
+ # }
645
+ # ]
646
+ # }
647
+ #
648
+ table = 'trade'
649
+ data = self.safe_value(message, 'data', [])
650
+ dataByMarketIds = self.group_by(data, 'symbol')
651
+ marketIds = list(dataByMarketIds.keys())
652
+ for i in range(0, len(marketIds)):
653
+ marketId = marketIds[i]
654
+ market = self.safe_market(marketId)
655
+ symbol = market['symbol']
656
+ messageHash = table + ':' + symbol
657
+ trades = self.parse_trades(dataByMarketIds[marketId], market)
658
+ stored = self.safe_value(self.trades, symbol)
659
+ if stored is None:
660
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
661
+ stored = ArrayCache(limit)
662
+ self.trades[symbol] = stored
663
+ for j in range(0, len(trades)):
664
+ stored.append(trades[j])
665
+ client.resolve(stored, messageHash)
666
+
667
+ async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
668
+ """
669
+ get the list of most recent trades for a particular symbol
670
+
671
+ https://www.bitmex.com/app/wsAPI#Subscriptions
672
+
673
+ :param str symbol: unified symbol of the market to fetch trades for
674
+ :param int [since]: timestamp in ms of the earliest trade to fetch
675
+ :param int [limit]: the maximum amount of trades to fetch
676
+ :param dict [params]: extra parameters specific to the exchange API endpoint
677
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
678
+ """
679
+ return await self.watch_trades_for_symbols([symbol], since, limit, params)
680
+
681
+ async def authenticate(self, params={}):
682
+ url = self.urls['api']['ws']
683
+ client = self.client(url)
684
+ messageHash = 'authenticated'
685
+ future = client.future(messageHash)
686
+ authenticated = self.safe_value(client.subscriptions, messageHash)
687
+ if authenticated is None:
688
+ self.check_required_credentials()
689
+ timestamp = self.milliseconds()
690
+ payload = 'GET' + '/realtime' + str(timestamp)
691
+ signature = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha256)
692
+ request: dict = {
693
+ 'op': 'authKeyExpires',
694
+ 'args': [
695
+ self.apiKey,
696
+ timestamp,
697
+ signature,
698
+ ],
699
+ }
700
+ message = self.extend(request, params)
701
+ self.watch(url, messageHash, message, messageHash)
702
+ return await future
703
+
704
+ def handle_authentication_message(self, client: Client, message):
705
+ authenticated = self.safe_bool(message, 'success', False)
706
+ messageHash = 'authenticated'
707
+ if authenticated:
708
+ # we resolve the future here permanently so authentication only happens once
709
+ future = self.safe_value(client.futures, messageHash)
710
+ future.resolve(True)
711
+ else:
712
+ error = AuthenticationError(self.json(message))
713
+ client.reject(error, messageHash)
714
+ if messageHash in client.subscriptions:
715
+ del client.subscriptions[messageHash]
716
+
717
+ async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
718
+ """
719
+ watch all open positions
720
+
721
+ https://www.bitmex.com/app/wsAPI#Subscriptions
722
+
723
+ :param str[]|None symbols: list of unified market symbols
724
+ :param int [since]: the earliest time in ms to watch positions for
725
+ :param int [limit]: the maximum number of positions to retrieve
726
+ :param dict params: extra parameters specific to the exchange API endpoint
727
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
728
+ """
729
+ await self.load_markets()
730
+ await self.authenticate()
731
+ subscriptionHash = 'position'
732
+ messageHash = 'positions'
733
+ if not self.is_empty(symbols):
734
+ messageHash = '::' + ','.join(symbols)
735
+ url = self.urls['api']['ws']
736
+ request: dict = {
737
+ 'op': 'subscribe',
738
+ 'args': [
739
+ subscriptionHash,
740
+ ],
741
+ }
742
+ newPositions = await self.watch(url, messageHash, request, subscriptionHash)
743
+ if self.newUpdates:
744
+ return newPositions
745
+ return self.filter_by_symbols_since_limit(self.positions, symbols, since, limit, True)
746
+
747
+ def handle_positions(self, client, message):
748
+ #
749
+ # partial
750
+ # {
751
+ # table: 'position',
752
+ # action: 'partial',
753
+ # keys: ['account', 'symbol'],
754
+ # types: {
755
+ # account: 'long',
756
+ # symbol: 'symbol',
757
+ # currency: 'symbol',
758
+ # underlying: 'symbol',
759
+ # quoteCurrency: 'symbol',
760
+ # commission: 'float',
761
+ # initMarginReq: 'float',
762
+ # maintMarginReq: 'float',
763
+ # riskLimit: 'long',
764
+ # leverage: 'float',
765
+ # crossMargin: 'boolean',
766
+ # deleveragePercentile: 'float',
767
+ # rebalancedPnl: 'long',
768
+ # prevRealisedPnl: 'long',
769
+ # prevUnrealisedPnl: 'long',
770
+ # openingQty: 'long',
771
+ # openOrderBuyQty: 'long',
772
+ # openOrderBuyCost: 'long',
773
+ # openOrderBuyPremium: 'long',
774
+ # openOrderSellQty: 'long',
775
+ # openOrderSellCost: 'long',
776
+ # openOrderSellPremium: 'long',
777
+ # currentQty: 'long',
778
+ # currentCost: 'long',
779
+ # currentComm: 'long',
780
+ # realisedCost: 'long',
781
+ # unrealisedCost: 'long',
782
+ # grossOpenPremium: 'long',
783
+ # isOpen: 'boolean',
784
+ # markPrice: 'float',
785
+ # markValue: 'long',
786
+ # riskValue: 'long',
787
+ # homeNotional: 'float',
788
+ # foreignNotional: 'float',
789
+ # posState: 'symbol',
790
+ # posCost: 'long',
791
+ # posCross: 'long',
792
+ # posComm: 'long',
793
+ # posLoss: 'long',
794
+ # posMargin: 'long',
795
+ # posMaint: 'long',
796
+ # initMargin: 'long',
797
+ # maintMargin: 'long',
798
+ # realisedPnl: 'long',
799
+ # unrealisedPnl: 'long',
800
+ # unrealisedPnlPcnt: 'float',
801
+ # unrealisedRoePcnt: 'float',
802
+ # avgCostPrice: 'float',
803
+ # avgEntryPrice: 'float',
804
+ # breakEvenPrice: 'float',
805
+ # marginCallPrice: 'float',
806
+ # liquidationPrice: 'float',
807
+ # bankruptPrice: 'float',
808
+ # timestamp: 'timestamp'
809
+ # },
810
+ # filter: {account: 412475},
811
+ # data: [
812
+ # {
813
+ # account: 412475,
814
+ # symbol: 'XBTUSD',
815
+ # currency: 'XBt',
816
+ # underlying: 'XBT',
817
+ # quoteCurrency: 'USD',
818
+ # commission: 0.00075,
819
+ # initMarginReq: 0.01,
820
+ # maintMarginReq: 0.0035,
821
+ # riskLimit: 20000000000,
822
+ # leverage: 100,
823
+ # crossMargin: True,
824
+ # deleveragePercentile: 1,
825
+ # rebalancedPnl: 0,
826
+ # prevRealisedPnl: 0,
827
+ # prevUnrealisedPnl: 0,
828
+ # openingQty: 400,
829
+ # openOrderBuyQty: 0,
830
+ # openOrderBuyCost: 0,
831
+ # openOrderBuyPremium: 0,
832
+ # openOrderSellQty: 0,
833
+ # openOrderSellCost: 0,
834
+ # openOrderSellPremium: 0,
835
+ # currentQty: 400,
836
+ # currentCost: -912269,
837
+ # currentComm: 684,
838
+ # realisedCost: 0,
839
+ # unrealisedCost: -912269,
840
+ # grossOpenPremium: 0,
841
+ # isOpen: True,
842
+ # markPrice: 43772,
843
+ # markValue: -913828,
844
+ # riskValue: 913828,
845
+ # homeNotional: 0.00913828,
846
+ # foreignNotional: -400,
847
+ # posCost: -912269,
848
+ # posCross: 1559,
849
+ # posComm: 694,
850
+ # posLoss: 0,
851
+ # posMargin: 11376,
852
+ # posMaint: 3887,
853
+ # initMargin: 0,
854
+ # maintMargin: 9817,
855
+ # realisedPnl: -684,
856
+ # unrealisedPnl: -1559,
857
+ # unrealisedPnlPcnt: -0.0017,
858
+ # unrealisedRoePcnt: -0.1709,
859
+ # avgCostPrice: 43846.7643,
860
+ # avgEntryPrice: 43846.7643,
861
+ # breakEvenPrice: 43880,
862
+ # marginCallPrice: 20976,
863
+ # liquidationPrice: 20976,
864
+ # bankruptPrice: 20941,
865
+ # timestamp: '2023-12-07T00:09:00.709Z'
866
+ # }
867
+ # ]
868
+ # }
869
+ # update
870
+ # {
871
+ # table: 'position',
872
+ # action: 'update',
873
+ # data: [
874
+ # {
875
+ # account: 412475,
876
+ # symbol: 'XBTUSD',
877
+ # currency: 'XBt',
878
+ # currentQty: 400,
879
+ # markPrice: 43772.75,
880
+ # markValue: -913812,
881
+ # riskValue: 913812,
882
+ # homeNotional: 0.00913812,
883
+ # posCross: 1543,
884
+ # posComm: 693,
885
+ # posMargin: 11359,
886
+ # posMaint: 3886,
887
+ # maintMargin: 9816,
888
+ # unrealisedPnl: -1543,
889
+ # unrealisedRoePcnt: -0.1691,
890
+ # liquidationPrice: 20976,
891
+ # timestamp: '2023-12-07T00:09:10.760Z'
892
+ # }
893
+ # ]
894
+ # }
895
+ #
896
+ if self.positions is None:
897
+ self.positions = ArrayCacheBySymbolBySide()
898
+ cache = self.positions
899
+ rawPositions = self.safe_value(message, 'data', [])
900
+ newPositions = []
901
+ for i in range(0, len(rawPositions)):
902
+ rawPosition = rawPositions[i]
903
+ position = self.parse_position(rawPosition)
904
+ newPositions.append(position)
905
+ cache.append(position)
906
+ messageHashes = self.find_message_hashes(client, 'positions::')
907
+ for i in range(0, len(messageHashes)):
908
+ messageHash = messageHashes[i]
909
+ parts = messageHash.split('::')
910
+ symbolsString = parts[1]
911
+ symbols = symbolsString.split(',')
912
+ positions = self.filter_by_array(newPositions, 'symbol', symbols, False)
913
+ if not self.is_empty(positions):
914
+ client.resolve(positions, messageHash)
915
+ client.resolve(newPositions, 'positions')
916
+
917
+ async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
918
+ """
919
+ watches information on multiple orders made by the user
920
+
921
+ https://www.bitmex.com/app/wsAPI#Subscriptions
922
+
923
+ :param str symbol: unified market symbol of the market orders were made in
924
+ :param int [since]: the earliest time in ms to fetch orders for
925
+ :param int [limit]: the maximum number of order structures to retrieve
926
+ :param dict [params]: extra parameters specific to the exchange API endpoint
927
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
928
+ """
929
+ await self.load_markets()
930
+ await self.authenticate()
931
+ name = 'order'
932
+ subscriptionHash = name
933
+ messageHash = name
934
+ if symbol is not None:
935
+ symbol = self.symbol(symbol)
936
+ messageHash += ':' + symbol
937
+ url = self.urls['api']['ws']
938
+ request: dict = {
939
+ 'op': 'subscribe',
940
+ 'args': [
941
+ subscriptionHash,
942
+ ],
943
+ }
944
+ orders = await self.watch(url, messageHash, request, subscriptionHash)
945
+ if self.newUpdates:
946
+ limit = orders.getLimit(symbol, limit)
947
+ return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
948
+
949
+ def handle_orders(self, client: Client, message):
950
+ #
951
+ # {
952
+ # "table": "order",
953
+ # "action": "partial",
954
+ # "keys": ["orderID"],
955
+ # "types": {
956
+ # "orderID": "guid",
957
+ # "clOrdID": "string",
958
+ # "clOrdLinkID": "symbol",
959
+ # "account": "long",
960
+ # "symbol": "symbol",
961
+ # "side": "symbol",
962
+ # "simpleOrderQty": "float",
963
+ # "orderQty": "long",
964
+ # "price": "float",
965
+ # "displayQty": "long",
966
+ # "stopPx": "float",
967
+ # "pegOffsetValue": "float",
968
+ # "pegPriceType": "symbol",
969
+ # "currency": "symbol",
970
+ # "settlCurrency": "symbol",
971
+ # "ordType": "symbol",
972
+ # "timeInForce": "symbol",
973
+ # "execInst": "symbol",
974
+ # "contingencyType": "symbol",
975
+ # "exDestination": "symbol",
976
+ # "ordStatus": "symbol",
977
+ # "triggered": "symbol",
978
+ # "workingIndicator": "boolean",
979
+ # "ordRejReason": "symbol",
980
+ # "simpleLeavesQty": "float",
981
+ # "leavesQty": "long",
982
+ # "simpleCumQty": "float",
983
+ # "cumQty": "long",
984
+ # "avgPx": "float",
985
+ # "multiLegReportingType": "symbol",
986
+ # "text": "string",
987
+ # "transactTime": "timestamp",
988
+ # "timestamp": "timestamp"
989
+ # },
990
+ # "foreignKeys": {symbol: 'instrument', side: "side", ordStatus: "ordStatus"},
991
+ # "attributes": {
992
+ # "orderID": "grouped",
993
+ # "account": "grouped",
994
+ # "ordStatus": "grouped",
995
+ # "workingIndicator": "grouped"
996
+ # },
997
+ # "filter": {account: 1455728},
998
+ # "data": [
999
+ # {
1000
+ # "orderID": "56222c7a-9956-413a-82cf-99f4812c214b",
1001
+ # "clOrdID": '',
1002
+ # "clOrdLinkID": '',
1003
+ # "account": 1455728,
1004
+ # "symbol": "XBTUSD",
1005
+ # "side": "Sell",
1006
+ # "simpleOrderQty": null,
1007
+ # "orderQty": 1,
1008
+ # "price": 40000,
1009
+ # "displayQty": null,
1010
+ # "stopPx": null,
1011
+ # "pegOffsetValue": null,
1012
+ # "pegPriceType": '',
1013
+ # "currency": "USD",
1014
+ # "settlCurrency": "XBt",
1015
+ # "ordType": "Limit",
1016
+ # "timeInForce": "GoodTillCancel",
1017
+ # "execInst": '',
1018
+ # "contingencyType": '',
1019
+ # "exDestination": "XBME",
1020
+ # "ordStatus": "New",
1021
+ # "triggered": '',
1022
+ # "workingIndicator": True,
1023
+ # "ordRejReason": '',
1024
+ # "simpleLeavesQty": null,
1025
+ # "leavesQty": 1,
1026
+ # "simpleCumQty": null,
1027
+ # "cumQty": 0,
1028
+ # "avgPx": null,
1029
+ # "multiLegReportingType": "SingleSecurity",
1030
+ # "text": "Submitted via API.",
1031
+ # "transactTime": "2021-01-02T21:38:49.246Z",
1032
+ # "timestamp": "2021-01-02T21:38:49.246Z"
1033
+ # }
1034
+ # ]
1035
+ # }
1036
+ #
1037
+ # {
1038
+ # "table": "order",
1039
+ # "action": "insert",
1040
+ # "data": [
1041
+ # {
1042
+ # "orderID": "fa993d8e-f7e4-46ed-8097-04f8e9393585",
1043
+ # "clOrdID": '',
1044
+ # "clOrdLinkID": '',
1045
+ # "account": 1455728,
1046
+ # "symbol": "XBTUSD",
1047
+ # "side": "Sell",
1048
+ # "simpleOrderQty": null,
1049
+ # "orderQty": 1,
1050
+ # "price": 40000,
1051
+ # "displayQty": null,
1052
+ # "stopPx": null,
1053
+ # "pegOffsetValue": null,
1054
+ # "pegPriceType": '',
1055
+ # "currency": "USD",
1056
+ # "settlCurrency": "XBt",
1057
+ # "ordType": "Limit",
1058
+ # "timeInForce": "GoodTillCancel",
1059
+ # "execInst": '',
1060
+ # "contingencyType": '',
1061
+ # "exDestination": "XBME",
1062
+ # "ordStatus": "New",
1063
+ # "triggered": '',
1064
+ # "workingIndicator": True,
1065
+ # "ordRejReason": '',
1066
+ # "simpleLeavesQty": null,
1067
+ # "leavesQty": 1,
1068
+ # "simpleCumQty": null,
1069
+ # "cumQty": 0,
1070
+ # "avgPx": null,
1071
+ # "multiLegReportingType": "SingleSecurity",
1072
+ # "text": "Submitted via API.",
1073
+ # "transactTime": "2021-01-02T23:49:02.286Z",
1074
+ # "timestamp": "2021-01-02T23:49:02.286Z"
1075
+ # }
1076
+ # ]
1077
+ # }
1078
+ #
1079
+ #
1080
+ #
1081
+ # {
1082
+ # "table": "order",
1083
+ # "action": "update",
1084
+ # "data": [
1085
+ # {
1086
+ # "orderID": "fa993d8e-f7e4-46ed-8097-04f8e9393585",
1087
+ # "ordStatus": "Canceled",
1088
+ # "workingIndicator": False,
1089
+ # "leavesQty": 0,
1090
+ # "text": "Canceled: Canceled via API.\nSubmitted via API.",
1091
+ # "timestamp": "2021-01-02T23:50:51.272Z",
1092
+ # "clOrdID": '',
1093
+ # "account": 1455728,
1094
+ # "symbol": "XBTUSD"
1095
+ # }
1096
+ # ]
1097
+ # }
1098
+ #
1099
+ data = self.safe_value(message, 'data', [])
1100
+ messageHash = 'order'
1101
+ # initial subscription response with multiple orders
1102
+ dataLength = len(data)
1103
+ if dataLength > 0:
1104
+ if self.orders is None:
1105
+ limit = self.safe_integer(self.options, 'ordersLimit', 1000)
1106
+ self.orders = ArrayCacheBySymbolById(limit)
1107
+ stored = self.orders
1108
+ symbols: dict = {}
1109
+ for i in range(0, dataLength):
1110
+ currentOrder = data[i]
1111
+ orderId = self.safe_string(currentOrder, 'orderID')
1112
+ previousOrder = self.safe_value(stored.hashmap, orderId)
1113
+ rawOrder = currentOrder
1114
+ if previousOrder is not None:
1115
+ rawOrder = self.extend(previousOrder['info'], currentOrder)
1116
+ order = self.parse_order(rawOrder)
1117
+ stored.append(order)
1118
+ symbol = order['symbol']
1119
+ symbols[symbol] = True
1120
+ client.resolve(self.orders, messageHash)
1121
+ keys = list(symbols.keys())
1122
+ for i in range(0, len(keys)):
1123
+ symbol = keys[i]
1124
+ client.resolve(self.orders, messageHash + ':' + symbol)
1125
+
1126
+ async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
1127
+ """
1128
+ watches information on multiple trades made by the user
1129
+
1130
+ https://www.bitmex.com/app/wsAPI#Subscriptions
1131
+
1132
+ :param str symbol: unified market symbol of the market trades were made in
1133
+ :param int [since]: the earliest time in ms to fetch trades for
1134
+ :param int [limit]: the maximum number of trade structures to retrieve
1135
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1136
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1137
+ """
1138
+ await self.load_markets()
1139
+ await self.authenticate()
1140
+ name = 'execution'
1141
+ subscriptionHash = name
1142
+ messageHash = name
1143
+ if symbol is not None:
1144
+ symbol = self.symbol(symbol)
1145
+ messageHash += ':' + symbol
1146
+ url = self.urls['api']['ws']
1147
+ request: dict = {
1148
+ 'op': 'subscribe',
1149
+ 'args': [
1150
+ subscriptionHash,
1151
+ ],
1152
+ }
1153
+ trades = await self.watch(url, messageHash, request, subscriptionHash)
1154
+ if self.newUpdates:
1155
+ limit = trades.getLimit(symbol, limit)
1156
+ return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
1157
+
1158
+ def handle_my_trades(self, client: Client, message):
1159
+ #
1160
+ # {
1161
+ # "table":"execution",
1162
+ # "action":"insert",
1163
+ # "data":[
1164
+ # {
1165
+ # "execID":"0193e879-cb6f-2891-d099-2c4eb40fee21",
1166
+ # "orderID":"00000000-0000-0000-0000-000000000000",
1167
+ # "clOrdID":"",
1168
+ # "clOrdLinkID":"",
1169
+ # "account":2,
1170
+ # "symbol":"XBTUSD",
1171
+ # "side":"Sell",
1172
+ # "lastQty":1,
1173
+ # "lastPx":1134.37,
1174
+ # "underlyingLastPx":null,
1175
+ # "lastMkt":"XBME",
1176
+ # "lastLiquidityInd":"RemovedLiquidity",
1177
+ # "simpleOrderQty":null,
1178
+ # "orderQty":1,
1179
+ # "price":1134.37,
1180
+ # "displayQty":null,
1181
+ # "stopPx":null,
1182
+ # "pegOffsetValue":null,
1183
+ # "pegPriceType":"",
1184
+ # "currency":"USD",
1185
+ # "settlCurrency":"XBt",
1186
+ # "execType":"Trade",
1187
+ # "ordType":"Limit",
1188
+ # "timeInForce":"ImmediateOrCancel",
1189
+ # "execInst":"",
1190
+ # "contingencyType":"",
1191
+ # "exDestination":"XBME",
1192
+ # "ordStatus":"Filled",
1193
+ # "triggered":"",
1194
+ # "workingIndicator":false,
1195
+ # "ordRejReason":"",
1196
+ # "simpleLeavesQty":0,
1197
+ # "leavesQty":0,
1198
+ # "simpleCumQty":0.001,
1199
+ # "cumQty":1,
1200
+ # "avgPx":1134.37,
1201
+ # "commission":0.00075,
1202
+ # "tradePublishIndicator":"DoNotPublishTrade",
1203
+ # "multiLegReportingType":"SingleSecurity",
1204
+ # "text":"Liquidation",
1205
+ # "trdMatchID":"7f4ab7f6-0006-3234-76f4-ae1385aad00f",
1206
+ # "execCost":88155,
1207
+ # "execComm":66,
1208
+ # "homeNotional":-0.00088155,
1209
+ # "foreignNotional":1,
1210
+ # "transactTime":"2017-04-04T22:07:46.035Z",
1211
+ # "timestamp":"2017-04-04T22:07:46.035Z"
1212
+ # }
1213
+ # ]
1214
+ # }
1215
+ #
1216
+ messageHash = self.safe_string(message, 'table')
1217
+ data = self.safe_value(message, 'data', [])
1218
+ dataByExecType = self.group_by(data, 'execType')
1219
+ rawTrades = self.safe_value(dataByExecType, 'Trade', [])
1220
+ trades = self.parse_trades(rawTrades)
1221
+ if self.myTrades is None:
1222
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
1223
+ self.myTrades = ArrayCacheBySymbolById(limit)
1224
+ stored = self.myTrades
1225
+ symbols: dict = {}
1226
+ for j in range(0, len(trades)):
1227
+ trade = trades[j]
1228
+ symbol = trade['symbol']
1229
+ stored.append(trade)
1230
+ symbols[symbol] = trade
1231
+ numTrades = len(trades)
1232
+ if numTrades > 0:
1233
+ client.resolve(stored, messageHash)
1234
+ keys = list(symbols.keys())
1235
+ for i in range(0, len(keys)):
1236
+ client.resolve(stored, messageHash + ':' + keys[i])
1237
+
1238
+ async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
1239
+ """
1240
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
1241
+
1242
+ https://www.bitmex.com/app/wsAPI#OrderBookL2
1243
+
1244
+ :param str symbol: unified symbol of the market to fetch the order book for
1245
+ :param int [limit]: the maximum amount of order book entries to return
1246
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1247
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
1248
+ """
1249
+ return await self.watch_order_book_for_symbols([symbol], limit, params)
1250
+
1251
+ async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
1252
+ """
1253
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
1254
+
1255
+ https://www.bitmex.com/app/wsAPI#OrderBookL2
1256
+
1257
+ :param str[] symbols: unified array of symbols
1258
+ :param int [limit]: the maximum amount of order book entries to return
1259
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1260
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
1261
+ """
1262
+ table = None
1263
+ if limit is None:
1264
+ table = self.safe_string(self.options, 'watchOrderBookLevel', 'orderBookL2')
1265
+ elif limit == 25:
1266
+ table = 'orderBookL2_25'
1267
+ elif limit == 10:
1268
+ table = 'orderBookL10'
1269
+ else:
1270
+ raise ExchangeError(self.id + ' watchOrderBookForSymbols limit argument must be None(L2), 25(L2) or 10(L3)')
1271
+ await self.load_markets()
1272
+ symbols = self.market_symbols(symbols)
1273
+ topics = []
1274
+ messageHashes = []
1275
+ for i in range(0, len(symbols)):
1276
+ symbol = symbols[i]
1277
+ market = self.market(symbol)
1278
+ topic = table + ':' + market['id']
1279
+ topics.append(topic)
1280
+ messageHash = table + ':' + symbol
1281
+ messageHashes.append(messageHash)
1282
+ url = self.urls['api']['ws']
1283
+ request: dict = {
1284
+ 'op': 'subscribe',
1285
+ 'args': topics,
1286
+ }
1287
+ orderbook = await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), topics)
1288
+ return orderbook.limit()
1289
+
1290
+ async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
1291
+ """
1292
+ get the list of most recent trades for a list of symbols
1293
+
1294
+ https://www.bitmex.com/app/wsAPI#Subscriptions
1295
+
1296
+ :param str[] symbols: unified symbol of the market to fetch trades for
1297
+ :param int [since]: timestamp in ms of the earliest trade to fetch
1298
+ :param int [limit]: the maximum amount of trades to fetch
1299
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1300
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
1301
+ """
1302
+ await self.load_markets()
1303
+ symbols = self.market_symbols(symbols, None, False)
1304
+ table = 'trade'
1305
+ topics = []
1306
+ messageHashes = []
1307
+ for i in range(0, len(symbols)):
1308
+ symbol = symbols[i]
1309
+ market = self.market(symbol)
1310
+ topic = table + ':' + market['id']
1311
+ topics.append(topic)
1312
+ messageHash = table + ':' + symbol
1313
+ messageHashes.append(messageHash)
1314
+ url = self.urls['api']['ws']
1315
+ request: dict = {
1316
+ 'op': 'subscribe',
1317
+ 'args': topics,
1318
+ }
1319
+ trades = await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), topics)
1320
+ if self.newUpdates:
1321
+ first = self.safe_value(trades, 0)
1322
+ tradeSymbol = self.safe_string(first, 'symbol')
1323
+ limit = trades.getLimit(tradeSymbol, limit)
1324
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
1325
+
1326
+ async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
1327
+ """
1328
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1329
+
1330
+ https://www.bitmex.com/app/wsAPI#Subscriptions
1331
+
1332
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
1333
+ :param str timeframe: the length of time each candle represents
1334
+ :param int [since]: timestamp in ms of the earliest candle to fetch
1335
+ :param int [limit]: the maximum amount of candles to fetch
1336
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1337
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
1338
+ """
1339
+ await self.load_markets()
1340
+ market = self.market(symbol)
1341
+ symbol = market['symbol']
1342
+ table = 'tradeBin' + self.safe_string(self.timeframes, timeframe, timeframe)
1343
+ messageHash = table + ':' + market['id']
1344
+ url = self.urls['api']['ws']
1345
+ request: dict = {
1346
+ 'op': 'subscribe',
1347
+ 'args': [
1348
+ messageHash,
1349
+ ],
1350
+ }
1351
+ ohlcv = await self.watch(url, messageHash, self.extend(request, params), messageHash)
1352
+ if self.newUpdates:
1353
+ limit = ohlcv.getLimit(symbol, limit)
1354
+ return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
1355
+
1356
+ def handle_ohlcv(self, client: Client, message):
1357
+ #
1358
+ # {
1359
+ # "table": "tradeBin1m",
1360
+ # "action": "partial",
1361
+ # "keys": [],
1362
+ # "types": {
1363
+ # "timestamp": "timestamp",
1364
+ # "symbol": "symbol",
1365
+ # "open": "float",
1366
+ # "high": "float",
1367
+ # "low": "float",
1368
+ # "close": "float",
1369
+ # "trades": "long",
1370
+ # "volume": "long",
1371
+ # "vwap": "float",
1372
+ # "lastSize": "long",
1373
+ # "turnover": "long",
1374
+ # "homeNotional": "float",
1375
+ # "foreignNotional": "float"
1376
+ # },
1377
+ # "foreignKeys": {symbol: "instrument"},
1378
+ # "attributes": {timestamp: "sorted", symbol: "grouped"},
1379
+ # "filter": {symbol: "XBTUSD"},
1380
+ # "data": [
1381
+ # {
1382
+ # "timestamp": "2020-02-03T01:13:00.000Z",
1383
+ # "symbol": "XBTUSD",
1384
+ # "open": 9395,
1385
+ # "high": 9395.5,
1386
+ # "low": 9394.5,
1387
+ # "close": 9395,
1388
+ # "trades": 221,
1389
+ # "volume": 839204,
1390
+ # "vwap": 9394.9643,
1391
+ # "lastSize": 1874,
1392
+ # "turnover": 8932641535,
1393
+ # "homeNotional": 89.32641534999999,
1394
+ # "foreignNotional": 839204
1395
+ # }
1396
+ # ]
1397
+ # }
1398
+ #
1399
+ #
1400
+ # {
1401
+ # "table": "tradeBin1m",
1402
+ # "action": "insert",
1403
+ # "data": [
1404
+ # {
1405
+ # "timestamp": "2020-02-03T18:28:00.000Z",
1406
+ # "symbol": "XBTUSD",
1407
+ # "open": 9256,
1408
+ # "high": 9256.5,
1409
+ # "low": 9256,
1410
+ # "close": 9256,
1411
+ # "trades": 29,
1412
+ # "volume": 79057,
1413
+ # "vwap": 9256.688,
1414
+ # "lastSize": 100,
1415
+ # "turnover": 854077082,
1416
+ # "homeNotional": 8.540770820000002,
1417
+ # "foreignNotional": 79057
1418
+ # }
1419
+ # ]
1420
+ # }
1421
+ #
1422
+ table = self.safe_string(message, 'table')
1423
+ interval = table.replace('tradeBin', '')
1424
+ timeframe = self.find_timeframe(interval)
1425
+ duration = self.parse_timeframe(timeframe)
1426
+ candles = self.safe_value(message, 'data', [])
1427
+ results: dict = {}
1428
+ for i in range(0, len(candles)):
1429
+ candle = candles[i]
1430
+ marketId = self.safe_string(candle, 'symbol')
1431
+ market = self.safe_market(marketId)
1432
+ symbol = market['symbol']
1433
+ messageHash = table + ':' + market['id']
1434
+ result = [
1435
+ self.parse8601(self.safe_string(candle, 'timestamp')) - duration * 1000,
1436
+ None, # set open price to None, see: https://github.com/ccxt/ccxt/pull/21356#issuecomment-1969565862
1437
+ self.safe_float(candle, 'high'),
1438
+ self.safe_float(candle, 'low'),
1439
+ self.safe_float(candle, 'close'),
1440
+ self.safe_float(candle, 'volume'),
1441
+ ]
1442
+ self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
1443
+ stored = self.safe_value(self.ohlcvs[symbol], timeframe)
1444
+ if stored is None:
1445
+ limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
1446
+ stored = ArrayCacheByTimestamp(limit)
1447
+ self.ohlcvs[symbol][timeframe] = stored
1448
+ stored.append(result)
1449
+ results[messageHash] = stored
1450
+ messageHashes = list(results.keys())
1451
+ for i in range(0, len(messageHashes)):
1452
+ messageHash = messageHashes[i]
1453
+ client.resolve(results[messageHash], messageHash)
1454
+
1455
+ async def watch_heartbeat(self, params={}):
1456
+ await self.load_markets()
1457
+ event = 'heartbeat'
1458
+ url = self.urls['api']['ws']
1459
+ return await self.watch(url, event)
1460
+
1461
+ def handle_order_book(self, client: Client, message):
1462
+ #
1463
+ # first snapshot
1464
+ #
1465
+ # {
1466
+ # "table": "orderBookL2",
1467
+ # "action": "partial",
1468
+ # "keys": ['symbol', "id", "side"],
1469
+ # "types": {
1470
+ # "symbol": "symbol",
1471
+ # "id": "long",
1472
+ # "side": "symbol",
1473
+ # "size": "long",
1474
+ # "price": "float"
1475
+ # },
1476
+ # "foreignKeys": {symbol: "instrument", side: "side"},
1477
+ # "attributes": {symbol: "parted", id: "sorted"},
1478
+ # "filter": {symbol: "XBTUSD"},
1479
+ # "data": [
1480
+ # {symbol: "XBTUSD", id: 8700000100, side: "Sell", size: 1, price: 999999},
1481
+ # {symbol: "XBTUSD", id: 8700000200, side: "Sell", size: 3, price: 999998},
1482
+ # {symbol: "XBTUSD", id: 8716991250, side: "Sell", size: 26, price: 830087.5},
1483
+ # {symbol: "XBTUSD", id: 8728701950, side: "Sell", size: 1720, price: 712980.5},
1484
+ # ]
1485
+ # }
1486
+ #
1487
+ # subsequent updates
1488
+ #
1489
+ # {
1490
+ # "table": "orderBookL2",
1491
+ # "action": "update",
1492
+ # "data": [
1493
+ # {
1494
+ # "table": "orderBookL2",
1495
+ # "action": "insert",
1496
+ # "data": [
1497
+ # {
1498
+ # "symbol": "ETH_USDT",
1499
+ # "id": 85499965912,
1500
+ # "side": "Buy",
1501
+ # "size": 83000000,
1502
+ # "price": 1704.4,
1503
+ # "timestamp": "2023-03-26T22:29:00.299Z"
1504
+ # }
1505
+ # ]
1506
+ # }
1507
+ # ...
1508
+ # ]
1509
+ # }
1510
+ #
1511
+ action = self.safe_string(message, 'action')
1512
+ table = self.safe_string(message, 'table')
1513
+ if table is None:
1514
+ return # protecting from weird updates
1515
+ data = self.safe_value(message, 'data', [])
1516
+ # if it's an initial snapshot
1517
+ if action == 'partial':
1518
+ filter = self.safe_dict(message, 'filter', {})
1519
+ marketId = self.safe_value(filter, 'symbol')
1520
+ if marketId is None:
1521
+ return # protecting from weird update
1522
+ market = self.safe_market(marketId)
1523
+ symbol = market['symbol']
1524
+ if table == 'orderBookL2':
1525
+ self.orderbooks[symbol] = self.indexed_order_book()
1526
+ elif table == 'orderBookL2_25':
1527
+ self.orderbooks[symbol] = self.indexed_order_book({}, 25)
1528
+ elif table == 'orderBook10':
1529
+ self.orderbooks[symbol] = self.indexed_order_book({}, 10)
1530
+ orderbook = self.orderbooks[symbol]
1531
+ orderbook['symbol'] = symbol
1532
+ for i in range(0, len(data)):
1533
+ price = self.safe_float(data[i], 'price')
1534
+ size = self.convertFromRawQuantity(symbol, self.safe_string(data[i], 'size'))
1535
+ id = self.safe_string(data[i], 'id')
1536
+ side = self.safe_string(data[i], 'side')
1537
+ side = 'bids' if (side == 'Buy') else 'asks'
1538
+ bookside = orderbook[side]
1539
+ bookside.storeArray([price, size, id])
1540
+ datetime = self.safe_string(data[i], 'timestamp')
1541
+ orderbook['timestamp'] = self.parse8601(datetime)
1542
+ orderbook['datetime'] = datetime
1543
+ messageHash = table + ':' + symbol
1544
+ client.resolve(orderbook, messageHash)
1545
+ else:
1546
+ numUpdatesByMarketId: dict = {}
1547
+ for i in range(0, len(data)):
1548
+ marketId = self.safe_value(data[i], 'symbol')
1549
+ if marketId is None:
1550
+ return # protecting from weird update
1551
+ if not (marketId in numUpdatesByMarketId):
1552
+ numUpdatesByMarketId[marketId] = 0
1553
+ numUpdatesByMarketId[marketId] = self.sum(numUpdatesByMarketId, 1)
1554
+ market = self.safe_market(marketId)
1555
+ symbol = market['symbol']
1556
+ orderbook = self.orderbooks[symbol]
1557
+ price = self.safe_number(data[i], 'price')
1558
+ size = 0 if (action == 'delete') else self.convertFromRawQuantity(symbol, self.safe_string(data[i], 'size', '0'))
1559
+ id = self.safe_string(data[i], 'id')
1560
+ side = self.safe_string(data[i], 'side')
1561
+ side = 'bids' if (side == 'Buy') else 'asks'
1562
+ bookside = orderbook[side]
1563
+ bookside.storeArray([price, size, id])
1564
+ datetime = self.safe_string(data[i], 'timestamp')
1565
+ orderbook['timestamp'] = self.parse8601(datetime)
1566
+ orderbook['datetime'] = datetime
1567
+ marketIds = list(numUpdatesByMarketId.keys())
1568
+ for i in range(0, len(marketIds)):
1569
+ marketId = marketIds[i]
1570
+ market = self.safe_market(marketId)
1571
+ symbol = market['symbol']
1572
+ messageHash = table + ':' + symbol
1573
+ orderbook = self.orderbooks[symbol]
1574
+ client.resolve(orderbook, messageHash)
1575
+
1576
+ def handle_system_status(self, client: Client, message):
1577
+ #
1578
+ # todo answer the question whether handleSystemStatus should be renamed
1579
+ # and unified for any usage pattern that
1580
+ # involves system status and maintenance updates
1581
+ #
1582
+ # {
1583
+ # "info": "Welcome to the BitMEX Realtime API.",
1584
+ # "version": "2019-11-22T00:24:37.000Z",
1585
+ # "timestamp": "2019-11-23T09:02:27.771Z",
1586
+ # "docs": "https://www.bitmex.com/app/wsAPI",
1587
+ # "limit": {remaining: 39}
1588
+ # }
1589
+ #
1590
+ return message
1591
+
1592
+ def handle_subscription_status(self, client: Client, message):
1593
+ #
1594
+ # {
1595
+ # "success": True,
1596
+ # "subscribe": "orderBookL2:XBTUSD",
1597
+ # "request": {op: "subscribe", args: ["orderBookL2:XBTUSD"]}
1598
+ # }
1599
+ #
1600
+ return message
1601
+
1602
+ def handle_error_message(self, client: Client, message):
1603
+ #
1604
+ # generic error format
1605
+ #
1606
+ # {"error": errorMessage}
1607
+ #
1608
+ # examples
1609
+ #
1610
+ # {
1611
+ # "status": 429,
1612
+ # "error": "Rate limit exceeded, retry in 1 seconds.",
1613
+ # "meta": {"retryAfter": 1},
1614
+ # "request": {"op": "subscribe", "args": "orderBook"},
1615
+ # }
1616
+ #
1617
+ # {"error": "Rate limit exceeded, retry in 29 seconds."}
1618
+ #
1619
+ error = self.safe_string(message, 'error')
1620
+ if error is not None:
1621
+ request = self.safe_value(message, 'request', {})
1622
+ args = self.safe_value(request, 'args', [])
1623
+ numArgs = len(args)
1624
+ if numArgs > 0:
1625
+ messageHash = args[0]
1626
+ broad = self.exceptions['ws']['broad']
1627
+ broadKey = self.find_broadly_matched_key(broad, error)
1628
+ exception = None
1629
+ if broadKey is None:
1630
+ exception = ExchangeError(error) # c# requirement for now
1631
+ else:
1632
+ exception = broad[broadKey](error)
1633
+ client.reject(exception, messageHash)
1634
+ return False
1635
+ return True
1636
+
1637
+ def handle_message(self, client: Client, message):
1638
+ #
1639
+ # {
1640
+ # "info": "Welcome to the BitMEX Realtime API.",
1641
+ # "version": "2019-11-22T00:24:37.000Z",
1642
+ # "timestamp": "2019-11-23T09:04:42.569Z",
1643
+ # "docs": "https://www.bitmex.com/app/wsAPI",
1644
+ # "limit": {remaining: 38}
1645
+ # }
1646
+ #
1647
+ # {
1648
+ # "success": True,
1649
+ # "subscribe": "orderBookL2:XBTUSD",
1650
+ # "request": {op: "subscribe", args: ["orderBookL2:XBTUSD"]}
1651
+ # }
1652
+ #
1653
+ # {
1654
+ # "table": "orderBookL2",
1655
+ # "action": "update",
1656
+ # "data": [
1657
+ # {symbol: "XBTUSD", id: 8799284800, side: "Sell", size: 721000},
1658
+ # {symbol: "XBTUSD", id: 8799285100, side: "Sell", size: 70590},
1659
+ # {symbol: "XBTUSD", id: 8799285550, side: "Sell", size: 217652},
1660
+ # {symbol: "XBTUSD", id: 8799285850, side: "Sell", size: 105578},
1661
+ # {symbol: "XBTUSD", id: 8799286350, side: "Sell", size: 172093},
1662
+ # {symbol: "XBTUSD", id: 8799286650, side: "Sell", size: 201125},
1663
+ # {symbol: "XBTUSD", id: 8799288950, side: "Buy", size: 47552},
1664
+ # {symbol: "XBTUSD", id: 8799289250, side: "Buy", size: 78217},
1665
+ # {symbol: "XBTUSD", id: 8799289700, side: "Buy", size: 193677},
1666
+ # {symbol: "XBTUSD", id: 8799290000, side: "Buy", size: 818161},
1667
+ # {symbol: "XBTUSD", id: 8799290500, side: "Buy", size: 218806},
1668
+ # {symbol: "XBTUSD", id: 8799290800, side: "Buy", size: 102946}
1669
+ # ]
1670
+ # }
1671
+ #
1672
+ if self.handle_error_message(client, message):
1673
+ table = self.safe_string(message, 'table')
1674
+ methods: dict = {
1675
+ 'orderBookL2': self.handle_order_book,
1676
+ 'orderBookL2_25': self.handle_order_book,
1677
+ 'orderBook10': self.handle_order_book,
1678
+ 'instrument': self.handle_ticker,
1679
+ 'trade': self.handle_trades,
1680
+ 'tradeBin1m': self.handle_ohlcv,
1681
+ 'tradeBin5m': self.handle_ohlcv,
1682
+ 'tradeBin1h': self.handle_ohlcv,
1683
+ 'tradeBin1d': self.handle_ohlcv,
1684
+ 'order': self.handle_orders,
1685
+ 'execution': self.handle_my_trades,
1686
+ 'margin': self.handle_balance,
1687
+ 'liquidation': self.handle_liquidation,
1688
+ 'position': self.handle_positions,
1689
+ }
1690
+ method = self.safe_value(methods, table)
1691
+ if method is None:
1692
+ request = self.safe_value(message, 'request', {})
1693
+ op = self.safe_value(request, 'op')
1694
+ if op == 'authKeyExpires':
1695
+ self.handle_authentication_message(client, message)
1696
+ else:
1697
+ method(client, message)