kucoin-api 0.0.11__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.

Potentially problematic release.


This version of kucoin-api might be problematic. Click here for more details.

Files changed (290) hide show
  1. kucoin_api-0.0.13.dist-info/METADATA +81 -0
  2. kucoin_api-0.0.13.dist-info/RECORD +3 -0
  3. kucoin_api/__init__.py +0 -7
  4. kucoin_api/ccxt/__init__.py +0 -101
  5. kucoin_api/ccxt/abstract/kucoin.py +0 -224
  6. kucoin_api/ccxt/async_support/__init__.py +0 -80
  7. kucoin_api/ccxt/async_support/base/__init__.py +0 -1
  8. kucoin_api/ccxt/async_support/base/exchange.py +0 -2100
  9. kucoin_api/ccxt/async_support/base/throttler.py +0 -50
  10. kucoin_api/ccxt/async_support/base/ws/__init__.py +0 -38
  11. kucoin_api/ccxt/async_support/base/ws/aiohttp_client.py +0 -147
  12. kucoin_api/ccxt/async_support/base/ws/cache.py +0 -213
  13. kucoin_api/ccxt/async_support/base/ws/client.py +0 -214
  14. kucoin_api/ccxt/async_support/base/ws/fast_client.py +0 -97
  15. kucoin_api/ccxt/async_support/base/ws/functions.py +0 -59
  16. kucoin_api/ccxt/async_support/base/ws/future.py +0 -69
  17. kucoin_api/ccxt/async_support/base/ws/order_book.py +0 -78
  18. kucoin_api/ccxt/async_support/base/ws/order_book_side.py +0 -174
  19. kucoin_api/ccxt/async_support/kucoin.py +0 -4920
  20. kucoin_api/ccxt/base/__init__.py +0 -27
  21. kucoin_api/ccxt/base/decimal_to_precision.py +0 -174
  22. kucoin_api/ccxt/base/errors.py +0 -267
  23. kucoin_api/ccxt/base/exchange.py +0 -6770
  24. kucoin_api/ccxt/base/precise.py +0 -297
  25. kucoin_api/ccxt/base/types.py +0 -577
  26. kucoin_api/ccxt/kucoin.py +0 -4919
  27. kucoin_api/ccxt/pro/__init__.py +0 -21
  28. kucoin_api/ccxt/pro/kucoin.py +0 -1356
  29. kucoin_api/ccxt/static_dependencies/README.md +0 -1
  30. kucoin_api/ccxt/static_dependencies/__init__.py +0 -1
  31. kucoin_api/ccxt/static_dependencies/ecdsa/__init__.py +0 -14
  32. kucoin_api/ccxt/static_dependencies/ecdsa/_version.py +0 -520
  33. kucoin_api/ccxt/static_dependencies/ecdsa/curves.py +0 -56
  34. kucoin_api/ccxt/static_dependencies/ecdsa/der.py +0 -221
  35. kucoin_api/ccxt/static_dependencies/ecdsa/ecdsa.py +0 -310
  36. kucoin_api/ccxt/static_dependencies/ecdsa/ellipticcurve.py +0 -197
  37. kucoin_api/ccxt/static_dependencies/ecdsa/keys.py +0 -332
  38. kucoin_api/ccxt/static_dependencies/ecdsa/numbertheory.py +0 -531
  39. kucoin_api/ccxt/static_dependencies/ecdsa/rfc6979.py +0 -100
  40. kucoin_api/ccxt/static_dependencies/ecdsa/util.py +0 -266
  41. kucoin_api/ccxt/static_dependencies/ethereum/__init__.py +0 -7
  42. kucoin_api/ccxt/static_dependencies/ethereum/abi/__init__.py +0 -16
  43. kucoin_api/ccxt/static_dependencies/ethereum/abi/abi.py +0 -19
  44. kucoin_api/ccxt/static_dependencies/ethereum/abi/base.py +0 -152
  45. kucoin_api/ccxt/static_dependencies/ethereum/abi/codec.py +0 -217
  46. kucoin_api/ccxt/static_dependencies/ethereum/abi/constants.py +0 -3
  47. kucoin_api/ccxt/static_dependencies/ethereum/abi/decoding.py +0 -565
  48. kucoin_api/ccxt/static_dependencies/ethereum/abi/encoding.py +0 -720
  49. kucoin_api/ccxt/static_dependencies/ethereum/abi/exceptions.py +0 -139
  50. kucoin_api/ccxt/static_dependencies/ethereum/abi/grammar.py +0 -443
  51. kucoin_api/ccxt/static_dependencies/ethereum/abi/packed.py +0 -13
  52. kucoin_api/ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
  53. kucoin_api/ccxt/static_dependencies/ethereum/abi/registry.py +0 -643
  54. kucoin_api/ccxt/static_dependencies/ethereum/abi/tools/__init__.py +0 -3
  55. kucoin_api/ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +0 -230
  56. kucoin_api/ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
  57. kucoin_api/ccxt/static_dependencies/ethereum/abi/utils/numeric.py +0 -83
  58. kucoin_api/ccxt/static_dependencies/ethereum/abi/utils/padding.py +0 -27
  59. kucoin_api/ccxt/static_dependencies/ethereum/abi/utils/string.py +0 -19
  60. kucoin_api/ccxt/static_dependencies/ethereum/account/__init__.py +0 -3
  61. kucoin_api/ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +0 -4
  62. kucoin_api/ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +0 -239
  63. kucoin_api/ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +0 -40
  64. kucoin_api/ccxt/static_dependencies/ethereum/account/messages.py +0 -263
  65. kucoin_api/ccxt/static_dependencies/ethereum/account/py.typed +0 -0
  66. kucoin_api/ccxt/static_dependencies/ethereum/hexbytes/__init__.py +0 -5
  67. kucoin_api/ccxt/static_dependencies/ethereum/hexbytes/_utils.py +0 -54
  68. kucoin_api/ccxt/static_dependencies/ethereum/hexbytes/main.py +0 -65
  69. kucoin_api/ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
  70. kucoin_api/ccxt/static_dependencies/ethereum/typing/__init__.py +0 -63
  71. kucoin_api/ccxt/static_dependencies/ethereum/typing/abi.py +0 -6
  72. kucoin_api/ccxt/static_dependencies/ethereum/typing/bls.py +0 -7
  73. kucoin_api/ccxt/static_dependencies/ethereum/typing/discovery.py +0 -5
  74. kucoin_api/ccxt/static_dependencies/ethereum/typing/encoding.py +0 -7
  75. kucoin_api/ccxt/static_dependencies/ethereum/typing/enums.py +0 -17
  76. kucoin_api/ccxt/static_dependencies/ethereum/typing/ethpm.py +0 -9
  77. kucoin_api/ccxt/static_dependencies/ethereum/typing/evm.py +0 -20
  78. kucoin_api/ccxt/static_dependencies/ethereum/typing/networks.py +0 -1122
  79. kucoin_api/ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
  80. kucoin_api/ccxt/static_dependencies/ethereum/utils/__init__.py +0 -115
  81. kucoin_api/ccxt/static_dependencies/ethereum/utils/abi.py +0 -72
  82. kucoin_api/ccxt/static_dependencies/ethereum/utils/address.py +0 -171
  83. kucoin_api/ccxt/static_dependencies/ethereum/utils/applicators.py +0 -151
  84. kucoin_api/ccxt/static_dependencies/ethereum/utils/conversions.py +0 -190
  85. kucoin_api/ccxt/static_dependencies/ethereum/utils/currency.py +0 -107
  86. kucoin_api/ccxt/static_dependencies/ethereum/utils/curried/__init__.py +0 -269
  87. kucoin_api/ccxt/static_dependencies/ethereum/utils/debug.py +0 -20
  88. kucoin_api/ccxt/static_dependencies/ethereum/utils/decorators.py +0 -132
  89. kucoin_api/ccxt/static_dependencies/ethereum/utils/encoding.py +0 -6
  90. kucoin_api/ccxt/static_dependencies/ethereum/utils/exceptions.py +0 -4
  91. kucoin_api/ccxt/static_dependencies/ethereum/utils/functional.py +0 -75
  92. kucoin_api/ccxt/static_dependencies/ethereum/utils/hexadecimal.py +0 -74
  93. kucoin_api/ccxt/static_dependencies/ethereum/utils/humanize.py +0 -188
  94. kucoin_api/ccxt/static_dependencies/ethereum/utils/logging.py +0 -159
  95. kucoin_api/ccxt/static_dependencies/ethereum/utils/module_loading.py +0 -31
  96. kucoin_api/ccxt/static_dependencies/ethereum/utils/numeric.py +0 -43
  97. kucoin_api/ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
  98. kucoin_api/ccxt/static_dependencies/ethereum/utils/toolz.py +0 -76
  99. kucoin_api/ccxt/static_dependencies/ethereum/utils/types.py +0 -54
  100. kucoin_api/ccxt/static_dependencies/ethereum/utils/typing/__init__.py +0 -18
  101. kucoin_api/ccxt/static_dependencies/ethereum/utils/typing/misc.py +0 -14
  102. kucoin_api/ccxt/static_dependencies/ethereum/utils/units.py +0 -31
  103. kucoin_api/ccxt/static_dependencies/keccak/__init__.py +0 -3
  104. kucoin_api/ccxt/static_dependencies/keccak/keccak.py +0 -197
  105. kucoin_api/ccxt/static_dependencies/lark/__init__.py +0 -38
  106. kucoin_api/ccxt/static_dependencies/lark/__pyinstaller/__init__.py +0 -6
  107. kucoin_api/ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +0 -14
  108. kucoin_api/ccxt/static_dependencies/lark/ast_utils.py +0 -59
  109. kucoin_api/ccxt/static_dependencies/lark/common.py +0 -86
  110. kucoin_api/ccxt/static_dependencies/lark/exceptions.py +0 -292
  111. kucoin_api/ccxt/static_dependencies/lark/grammar.py +0 -130
  112. kucoin_api/ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  113. kucoin_api/ccxt/static_dependencies/lark/grammars/common.lark +0 -59
  114. kucoin_api/ccxt/static_dependencies/lark/grammars/lark.lark +0 -62
  115. kucoin_api/ccxt/static_dependencies/lark/grammars/python.lark +0 -302
  116. kucoin_api/ccxt/static_dependencies/lark/grammars/unicode.lark +0 -7
  117. kucoin_api/ccxt/static_dependencies/lark/indenter.py +0 -143
  118. kucoin_api/ccxt/static_dependencies/lark/lark.py +0 -658
  119. kucoin_api/ccxt/static_dependencies/lark/lexer.py +0 -678
  120. kucoin_api/ccxt/static_dependencies/lark/load_grammar.py +0 -1428
  121. kucoin_api/ccxt/static_dependencies/lark/parse_tree_builder.py +0 -391
  122. kucoin_api/ccxt/static_dependencies/lark/parser_frontends.py +0 -257
  123. kucoin_api/ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  124. kucoin_api/ccxt/static_dependencies/lark/parsers/cyk.py +0 -340
  125. kucoin_api/ccxt/static_dependencies/lark/parsers/earley.py +0 -314
  126. kucoin_api/ccxt/static_dependencies/lark/parsers/earley_common.py +0 -42
  127. kucoin_api/ccxt/static_dependencies/lark/parsers/earley_forest.py +0 -801
  128. kucoin_api/ccxt/static_dependencies/lark/parsers/grammar_analysis.py +0 -203
  129. kucoin_api/ccxt/static_dependencies/lark/parsers/lalr_analysis.py +0 -332
  130. kucoin_api/ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +0 -158
  131. kucoin_api/ccxt/static_dependencies/lark/parsers/lalr_parser.py +0 -122
  132. kucoin_api/ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +0 -110
  133. kucoin_api/ccxt/static_dependencies/lark/parsers/xearley.py +0 -165
  134. kucoin_api/ccxt/static_dependencies/lark/py.typed +0 -0
  135. kucoin_api/ccxt/static_dependencies/lark/reconstruct.py +0 -107
  136. kucoin_api/ccxt/static_dependencies/lark/tools/__init__.py +0 -70
  137. kucoin_api/ccxt/static_dependencies/lark/tools/nearley.py +0 -202
  138. kucoin_api/ccxt/static_dependencies/lark/tools/serialize.py +0 -32
  139. kucoin_api/ccxt/static_dependencies/lark/tools/standalone.py +0 -196
  140. kucoin_api/ccxt/static_dependencies/lark/tree.py +0 -267
  141. kucoin_api/ccxt/static_dependencies/lark/tree_matcher.py +0 -186
  142. kucoin_api/ccxt/static_dependencies/lark/tree_templates.py +0 -180
  143. kucoin_api/ccxt/static_dependencies/lark/utils.py +0 -343
  144. kucoin_api/ccxt/static_dependencies/lark/visitors.py +0 -596
  145. kucoin_api/ccxt/static_dependencies/marshmallow/__init__.py +0 -81
  146. kucoin_api/ccxt/static_dependencies/marshmallow/base.py +0 -65
  147. kucoin_api/ccxt/static_dependencies/marshmallow/class_registry.py +0 -94
  148. kucoin_api/ccxt/static_dependencies/marshmallow/decorators.py +0 -231
  149. kucoin_api/ccxt/static_dependencies/marshmallow/error_store.py +0 -60
  150. kucoin_api/ccxt/static_dependencies/marshmallow/exceptions.py +0 -71
  151. kucoin_api/ccxt/static_dependencies/marshmallow/fields.py +0 -2114
  152. kucoin_api/ccxt/static_dependencies/marshmallow/orderedset.py +0 -89
  153. kucoin_api/ccxt/static_dependencies/marshmallow/py.typed +0 -0
  154. kucoin_api/ccxt/static_dependencies/marshmallow/schema.py +0 -1228
  155. kucoin_api/ccxt/static_dependencies/marshmallow/types.py +0 -12
  156. kucoin_api/ccxt/static_dependencies/marshmallow/utils.py +0 -378
  157. kucoin_api/ccxt/static_dependencies/marshmallow/validate.py +0 -678
  158. kucoin_api/ccxt/static_dependencies/marshmallow/warnings.py +0 -2
  159. kucoin_api/ccxt/static_dependencies/marshmallow_dataclass/__init__.py +0 -1047
  160. kucoin_api/ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +0 -51
  161. kucoin_api/ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +0 -45
  162. kucoin_api/ccxt/static_dependencies/marshmallow_dataclass/mypy.py +0 -71
  163. kucoin_api/ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  164. kucoin_api/ccxt/static_dependencies/marshmallow_dataclass/typing.py +0 -14
  165. kucoin_api/ccxt/static_dependencies/marshmallow_dataclass/union_field.py +0 -82
  166. kucoin_api/ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +0 -1
  167. kucoin_api/ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +0 -193
  168. kucoin_api/ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  169. kucoin_api/ccxt/static_dependencies/msgpack/__init__.py +0 -55
  170. kucoin_api/ccxt/static_dependencies/msgpack/_cmsgpack.pyx +0 -11
  171. kucoin_api/ccxt/static_dependencies/msgpack/_packer.pyx +0 -374
  172. kucoin_api/ccxt/static_dependencies/msgpack/_unpacker.pyx +0 -547
  173. kucoin_api/ccxt/static_dependencies/msgpack/buff_converter.h +0 -8
  174. kucoin_api/ccxt/static_dependencies/msgpack/exceptions.py +0 -48
  175. kucoin_api/ccxt/static_dependencies/msgpack/ext.py +0 -168
  176. kucoin_api/ccxt/static_dependencies/msgpack/fallback.py +0 -951
  177. kucoin_api/ccxt/static_dependencies/msgpack/pack.h +0 -89
  178. kucoin_api/ccxt/static_dependencies/msgpack/pack_template.h +0 -820
  179. kucoin_api/ccxt/static_dependencies/msgpack/sysdep.h +0 -194
  180. kucoin_api/ccxt/static_dependencies/msgpack/unpack.h +0 -391
  181. kucoin_api/ccxt/static_dependencies/msgpack/unpack_define.h +0 -95
  182. kucoin_api/ccxt/static_dependencies/msgpack/unpack_template.h +0 -464
  183. kucoin_api/ccxt/static_dependencies/parsimonious/__init__.py +0 -10
  184. kucoin_api/ccxt/static_dependencies/parsimonious/exceptions.py +0 -105
  185. kucoin_api/ccxt/static_dependencies/parsimonious/expressions.py +0 -479
  186. kucoin_api/ccxt/static_dependencies/parsimonious/grammar.py +0 -487
  187. kucoin_api/ccxt/static_dependencies/parsimonious/nodes.py +0 -325
  188. kucoin_api/ccxt/static_dependencies/parsimonious/utils.py +0 -40
  189. kucoin_api/ccxt/static_dependencies/starknet/__init__.py +0 -0
  190. kucoin_api/ccxt/static_dependencies/starknet/abi/v0/__init__.py +0 -2
  191. kucoin_api/ccxt/static_dependencies/starknet/abi/v0/model.py +0 -44
  192. kucoin_api/ccxt/static_dependencies/starknet/abi/v0/parser.py +0 -216
  193. kucoin_api/ccxt/static_dependencies/starknet/abi/v0/schemas.py +0 -72
  194. kucoin_api/ccxt/static_dependencies/starknet/abi/v0/shape.py +0 -63
  195. kucoin_api/ccxt/static_dependencies/starknet/abi/v1/__init__.py +0 -2
  196. kucoin_api/ccxt/static_dependencies/starknet/abi/v1/core_structures.json +0 -14
  197. kucoin_api/ccxt/static_dependencies/starknet/abi/v1/model.py +0 -39
  198. kucoin_api/ccxt/static_dependencies/starknet/abi/v1/parser.py +0 -220
  199. kucoin_api/ccxt/static_dependencies/starknet/abi/v1/parser_transformer.py +0 -179
  200. kucoin_api/ccxt/static_dependencies/starknet/abi/v1/schemas.py +0 -66
  201. kucoin_api/ccxt/static_dependencies/starknet/abi/v1/shape.py +0 -47
  202. kucoin_api/ccxt/static_dependencies/starknet/abi/v2/__init__.py +0 -2
  203. kucoin_api/ccxt/static_dependencies/starknet/abi/v2/model.py +0 -89
  204. kucoin_api/ccxt/static_dependencies/starknet/abi/v2/parser.py +0 -293
  205. kucoin_api/ccxt/static_dependencies/starknet/abi/v2/parser_transformer.py +0 -192
  206. kucoin_api/ccxt/static_dependencies/starknet/abi/v2/schemas.py +0 -132
  207. kucoin_api/ccxt/static_dependencies/starknet/abi/v2/shape.py +0 -107
  208. kucoin_api/ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  209. kucoin_api/ccxt/static_dependencies/starknet/cairo/data_types.py +0 -123
  210. kucoin_api/ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  211. kucoin_api/ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +0 -77
  212. kucoin_api/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +0 -46
  213. kucoin_api/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +0 -138
  214. kucoin_api/ccxt/static_dependencies/starknet/cairo/felt.py +0 -64
  215. kucoin_api/ccxt/static_dependencies/starknet/cairo/type_parser.py +0 -121
  216. kucoin_api/ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  217. kucoin_api/ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +0 -59
  218. kucoin_api/ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  219. kucoin_api/ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +0 -77
  220. kucoin_api/ccxt/static_dependencies/starknet/ccxt_utils.py +0 -7
  221. kucoin_api/ccxt/static_dependencies/starknet/common.py +0 -15
  222. kucoin_api/ccxt/static_dependencies/starknet/constants.py +0 -39
  223. kucoin_api/ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  224. kucoin_api/ccxt/static_dependencies/starknet/hash/address.py +0 -79
  225. kucoin_api/ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +0 -111
  226. kucoin_api/ccxt/static_dependencies/starknet/hash/selector.py +0 -16
  227. kucoin_api/ccxt/static_dependencies/starknet/hash/storage.py +0 -12
  228. kucoin_api/ccxt/static_dependencies/starknet/hash/utils.py +0 -78
  229. kucoin_api/ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  230. kucoin_api/ccxt/static_dependencies/starknet/models/typed_data.py +0 -45
  231. kucoin_api/ccxt/static_dependencies/starknet/serialization/__init__.py +0 -24
  232. kucoin_api/ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +0 -40
  233. kucoin_api/ccxt/static_dependencies/starknet/serialization/_context.py +0 -142
  234. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +0 -10
  235. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +0 -82
  236. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +0 -43
  237. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +0 -37
  238. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +0 -66
  239. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +0 -71
  240. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +0 -71
  241. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +0 -50
  242. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +0 -58
  243. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +0 -43
  244. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +0 -40
  245. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +0 -72
  246. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +0 -36
  247. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +0 -36
  248. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +0 -76
  249. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +0 -100
  250. kucoin_api/ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +0 -32
  251. kucoin_api/ccxt/static_dependencies/starknet/serialization/errors.py +0 -10
  252. kucoin_api/ccxt/static_dependencies/starknet/serialization/factory.py +0 -229
  253. kucoin_api/ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +0 -110
  254. kucoin_api/ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +0 -59
  255. kucoin_api/ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  256. kucoin_api/ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +0 -86
  257. kucoin_api/ccxt/static_dependencies/starknet/utils/iterable.py +0 -13
  258. kucoin_api/ccxt/static_dependencies/starknet/utils/schema.py +0 -13
  259. kucoin_api/ccxt/static_dependencies/starknet/utils/typed_data.py +0 -182
  260. kucoin_api/ccxt/static_dependencies/starkware/__init__.py +0 -0
  261. kucoin_api/ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  262. kucoin_api/ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +0 -50
  263. kucoin_api/ccxt/static_dependencies/starkware/crypto/math_utils.py +0 -78
  264. kucoin_api/ccxt/static_dependencies/starkware/crypto/signature.py +0 -2344
  265. kucoin_api/ccxt/static_dependencies/starkware/crypto/utils.py +0 -63
  266. kucoin_api/ccxt/static_dependencies/sympy/__init__.py +0 -0
  267. kucoin_api/ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  268. kucoin_api/ccxt/static_dependencies/sympy/core/intfunc.py +0 -35
  269. kucoin_api/ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  270. kucoin_api/ccxt/static_dependencies/sympy/external/gmpy.py +0 -345
  271. kucoin_api/ccxt/static_dependencies/sympy/external/importtools.py +0 -187
  272. kucoin_api/ccxt/static_dependencies/sympy/external/ntheory.py +0 -637
  273. kucoin_api/ccxt/static_dependencies/sympy/external/pythonmpq.py +0 -341
  274. kucoin_api/ccxt/static_dependencies/toolz/__init__.py +0 -26
  275. kucoin_api/ccxt/static_dependencies/toolz/_signatures.py +0 -784
  276. kucoin_api/ccxt/static_dependencies/toolz/_version.py +0 -520
  277. kucoin_api/ccxt/static_dependencies/toolz/compatibility.py +0 -30
  278. kucoin_api/ccxt/static_dependencies/toolz/curried/__init__.py +0 -101
  279. kucoin_api/ccxt/static_dependencies/toolz/curried/exceptions.py +0 -22
  280. kucoin_api/ccxt/static_dependencies/toolz/curried/operator.py +0 -22
  281. kucoin_api/ccxt/static_dependencies/toolz/dicttoolz.py +0 -339
  282. kucoin_api/ccxt/static_dependencies/toolz/functoolz.py +0 -1049
  283. kucoin_api/ccxt/static_dependencies/toolz/itertoolz.py +0 -1057
  284. kucoin_api/ccxt/static_dependencies/toolz/recipes.py +0 -46
  285. kucoin_api/ccxt/static_dependencies/toolz/utils.py +0 -9
  286. kucoin_api/ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  287. kucoin_api/ccxt/static_dependencies/typing_inspect/typing_inspect.py +0 -851
  288. kucoin_api-0.0.11.dist-info/METADATA +0 -62
  289. kucoin_api-0.0.11.dist-info/RECORD +0 -288
  290. {kucoin_api-0.0.11.dist-info → kucoin_api-0.0.13.dist-info}/WHEEL +0 -0
@@ -1,1356 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
- # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
-
6
- import ccxt.async_support
7
- from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
8
- from ccxt.base.types import Any, Balances, Int, Order, OrderBook, Str, Strings, Ticker, Tickers, Trade
9
- from ccxt.async_support.base.ws.client import Client
10
- from typing import List
11
- from ccxt.base.errors import ExchangeError
12
- from ccxt.base.errors import ArgumentsRequired
13
-
14
-
15
- from ccxt.async_support import kucoin as kucoinAsync
16
-
17
-
18
- class kucoin(kucoinAsync):
19
-
20
- def describe(self) -> Any:
21
- return self.deep_extend(super(kucoin, self).describe(), {
22
- 'has': {
23
- 'ws': True,
24
- 'createOrderWs': False,
25
- 'editOrderWs': False,
26
- 'fetchOpenOrdersWs': False,
27
- 'fetchOrderWs': False,
28
- 'cancelOrderWs': False,
29
- 'cancelOrdersWs': False,
30
- 'cancelAllOrdersWs': False,
31
- 'watchBidsAsks': True,
32
- 'watchOrderBook': True,
33
- 'watchOrders': True,
34
- 'watchMyTrades': True,
35
- 'watchTickers': True,
36
- 'watchTicker': True,
37
- 'watchTrades': True,
38
- 'watchTradesForSymbols': True,
39
- 'watchOrderBookForSymbols': True,
40
- 'watchBalance': True,
41
- 'watchOHLCV': True,
42
- },
43
- 'options': {
44
- 'tradesLimit': 1000,
45
- 'watchTicker': {
46
- 'name': 'market/snapshot', # market/ticker
47
- },
48
- 'watchOrderBook': {
49
- 'snapshotDelay': 5,
50
- 'snapshotMaxRetries': 3,
51
- 'method': '/market/level2', # '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50'
52
- },
53
- 'watchMyTrades': {
54
- 'method': '/spotMarket/tradeOrders', # or '/spot/tradeFills'
55
- },
56
- },
57
- 'streaming': {
58
- # kucoin does not support built-in ws protocol-level ping-pong
59
- # instead it requires a custom json-based text ping-pong
60
- # https://docs.kucoin.com/#ping
61
- 'ping': self.ping,
62
- },
63
- })
64
-
65
- async def negotiate(self, privateChannel, params={}):
66
- connectId = 'private' if privateChannel else 'public'
67
- urls = self.safe_value(self.options, 'urls', {})
68
- spawaned = self.safe_value(urls, connectId)
69
- if spawaned is not None:
70
- return await spawaned
71
- # we store an awaitable to the url
72
- # so that multiple calls don't asynchronously
73
- # fetch different urls and overwrite each other
74
- urls[connectId] = self.spawn(self.negotiate_helper, privateChannel, params)
75
- self.options['urls'] = urls
76
- future = urls[connectId]
77
- return await future
78
-
79
- async def negotiate_helper(self, privateChannel, params={}):
80
- response = None
81
- connectId = 'private' if privateChannel else 'public'
82
- try:
83
- if privateChannel:
84
- response = await self.privatePostBulletPrivate(params)
85
- #
86
- # {
87
- # "code": "200000",
88
- # "data": {
89
- # "instanceServers": [
90
- # {
91
- # "pingInterval": 50000,
92
- # "endpoint": "wss://push-private.kucoin.com/endpoint",
93
- # "protocol": "websocket",
94
- # "encrypt": True,
95
- # "pingTimeout": 10000
96
- # }
97
- # ],
98
- # "token": "2neAiuYvAU61ZDXANAGAsiL4-iAExhsBXZxftpOeh_55i3Ysy2q2LEsEWU64mdzUOPusi34M_wGoSf7iNyEWJ1UQy47YbpY4zVdzilNP-Bj3iXzrjjGlWtiYB9J6i9GjsxUuhPw3BlrzazF6ghq4Lzf7scStOz3KkxjwpsOBCH4=.WNQmhZQeUKIkh97KYgU0Lg=="
99
- # }
100
- # }
101
- #
102
- else:
103
- response = await self.publicPostBulletPublic(params)
104
- data = self.safe_value(response, 'data', {})
105
- instanceServers = self.safe_value(data, 'instanceServers', [])
106
- firstInstanceServer = self.safe_value(instanceServers, 0)
107
- pingInterval = self.safe_integer(firstInstanceServer, 'pingInterval')
108
- endpoint = self.safe_string(firstInstanceServer, 'endpoint')
109
- token = self.safe_string(data, 'token')
110
- result = endpoint + '?' + self.urlencode({
111
- 'token': token,
112
- 'privateChannel': privateChannel,
113
- 'connectId': connectId,
114
- })
115
- client = self.client(result)
116
- client.keepAlive = pingInterval
117
- return result
118
- except Exception as e:
119
- future = self.safe_value(self.options['urls'], connectId)
120
- future.reject(e)
121
- del self.options['urls'][connectId]
122
- return None
123
-
124
- def request_id(self):
125
- requestId = self.sum(self.safe_integer(self.options, 'requestId', 0), 1)
126
- self.options['requestId'] = requestId
127
- return requestId
128
-
129
- async def subscribe(self, url, messageHash, subscriptionHash, params={}, subscription=None):
130
- requestId = str(self.request_id())
131
- request: dict = {
132
- 'id': requestId,
133
- 'type': 'subscribe',
134
- 'topic': subscriptionHash,
135
- 'response': True,
136
- }
137
- message = self.extend(request, params)
138
- client = self.client(url)
139
- if not (subscriptionHash in client.subscriptions):
140
- client.subscriptions[requestId] = subscriptionHash
141
- return await self.watch(url, messageHash, message, subscriptionHash, subscription)
142
-
143
- async def subscribe_multiple(self, url, messageHashes, topic, subscriptionHashes, params={}, subscription=None):
144
- requestId = str(self.request_id())
145
- request: dict = {
146
- 'id': requestId,
147
- 'type': 'subscribe',
148
- 'topic': topic,
149
- 'response': True,
150
- }
151
- message = self.extend(request, params)
152
- client = self.client(url)
153
- for i in range(0, len(subscriptionHashes)):
154
- subscriptionHash = subscriptionHashes[i]
155
- if not (subscriptionHash in client.subscriptions):
156
- client.subscriptions[requestId] = subscriptionHash
157
- return await self.watch_multiple(url, messageHashes, message, subscriptionHashes, subscription)
158
-
159
- async def un_subscribe_multiple(self, url, messageHashes, topic, subscriptionHashes, params={}, subscription: dict = None):
160
- requestId = str(self.request_id())
161
- request: dict = {
162
- 'id': requestId,
163
- 'type': 'unsubscribe',
164
- 'topic': topic,
165
- 'response': True,
166
- }
167
- message = self.extend(request, params)
168
- if subscription is not None:
169
- subscription[requestId] = requestId
170
- client = self.client(url)
171
- for i in range(0, len(subscriptionHashes)):
172
- subscriptionHash = subscriptionHashes[i]
173
- if not (subscriptionHash in client.subscriptions):
174
- client.subscriptions[requestId] = subscriptionHash
175
- return await self.watch_multiple(url, messageHashes, message, subscriptionHashes, subscription)
176
-
177
- async def watch_ticker(self, symbol: str, params={}) -> Ticker:
178
- """
179
- watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
180
-
181
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/market-snapshot
182
-
183
- :param str symbol: unified symbol of the market to fetch the ticker for
184
- :param dict [params]: extra parameters specific to the exchange API endpoint
185
- :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
186
- """
187
- await self.load_markets()
188
- market = self.market(symbol)
189
- symbol = market['symbol']
190
- url = await self.negotiate(False)
191
- method, query = self.handle_option_and_params(params, 'watchTicker', 'method', '/market/snapshot')
192
- topic = method + ':' + market['id']
193
- messageHash = 'ticker:' + symbol
194
- return await self.subscribe(url, messageHash, topic, query)
195
-
196
- async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
197
- """
198
-
199
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/ticker
200
-
201
- watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
202
- :param str[] symbols: unified symbol of the market to fetch the ticker for
203
- :param dict [params]: extra parameters specific to the exchange API endpoint
204
- :param str [params.method]: either '/market/snapshot' or '/market/ticker' default is '/market/ticker'
205
- :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
206
- """
207
- await self.load_markets()
208
- symbols = self.market_symbols(symbols)
209
- messageHash = 'tickers'
210
- method = None
211
- method, params = self.handle_option_and_params(params, 'watchTickers', 'method', '/market/ticker')
212
- messageHashes = []
213
- topics = []
214
- if symbols is not None:
215
- for i in range(0, len(symbols)):
216
- symbol = symbols[i]
217
- messageHashes.append('ticker:' + symbol)
218
- market = self.market(symbol)
219
- topics.append(method + ':' + market['id'])
220
- url = await self.negotiate(False)
221
- tickers = None
222
- if symbols is None:
223
- allTopic = method + ':all'
224
- tickers = await self.subscribe(url, messageHash, allTopic, params)
225
- if self.newUpdates:
226
- return tickers
227
- else:
228
- marketIds = self.market_ids(symbols)
229
- symbolsTopic = method + ':' + ','.join(marketIds)
230
- tickers = await self.subscribe_multiple(url, messageHashes, symbolsTopic, topics, params)
231
- if self.newUpdates:
232
- newDict: dict = {}
233
- newDict[tickers['symbol']] = tickers
234
- return newDict
235
- return self.filter_by_array(self.tickers, 'symbol', symbols)
236
-
237
- def handle_ticker(self, client: Client, message):
238
- #
239
- # market/snapshot
240
- #
241
- # updates come in every 2 sec unless there
242
- # were no changes since the previous update
243
- #
244
- # {
245
- # "data": {
246
- # "sequence": "1545896669291",
247
- # "data": {
248
- # "trading": True,
249
- # "symbol": "KCS-BTC",
250
- # "buy": 0.00011,
251
- # "sell": 0.00012,
252
- # "sort": 100,
253
- # "volValue": 3.13851792584, # total
254
- # "baseCurrency": "KCS",
255
- # "market": "BTC",
256
- # "quoteCurrency": "BTC",
257
- # "symbolCode": "KCS-BTC",
258
- # "datetime": 1548388122031,
259
- # "high": 0.00013,
260
- # "vol": 27514.34842,
261
- # "low": 0.0001,
262
- # "changePrice": -1.0e-5,
263
- # "changeRate": -0.0769,
264
- # "lastTradedPrice": 0.00012,
265
- # "board": 0,
266
- # "mark": 0
267
- # }
268
- # },
269
- # "subject": "trade.snapshot",
270
- # "topic": "/market/snapshot:KCS-BTC",
271
- # "type": "message"
272
- # }
273
- #
274
- # market/ticker
275
- #
276
- # {
277
- # "type": "message",
278
- # "topic": "/market/ticker:BTC-USDT",
279
- # "subject": "trade.ticker",
280
- # "data": {
281
- # "bestAsk": "62163",
282
- # "bestAskSize": "0.99011388",
283
- # "bestBid": "62162.9",
284
- # "bestBidSize": "0.04794181",
285
- # "price": "62162.9",
286
- # "sequence": "1621383371852",
287
- # "size": "0.00832274",
288
- # "time": 1634641987564
289
- # }
290
- # }
291
- #
292
- topic = self.safe_string(message, 'topic')
293
- market = None
294
- if topic is not None:
295
- parts = topic.split(':')
296
- first = self.safe_string(parts, 1)
297
- marketId = None
298
- if first == 'all':
299
- marketId = self.safe_string(message, 'subject')
300
- else:
301
- marketId = first
302
- market = self.safe_market(marketId, market, '-')
303
- data = self.safe_value(message, 'data', {})
304
- rawTicker = self.safe_value(data, 'data', data)
305
- ticker = self.parse_ticker(rawTicker, market)
306
- symbol = ticker['symbol']
307
- self.tickers[symbol] = ticker
308
- messageHash = 'ticker:' + symbol
309
- client.resolve(ticker, messageHash)
310
- # watchTickers
311
- allTickers: dict = {}
312
- allTickers[symbol] = ticker
313
- client.resolve(allTickers, 'tickers')
314
-
315
- async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
316
- """
317
-
318
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level1-bbo-market-data
319
-
320
- watches best bid & ask for symbols
321
- :param str[] symbols: unified symbol of the market to fetch the ticker for
322
- :param dict [params]: extra parameters specific to the exchange API endpoint
323
- :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
324
- """
325
- ticker = await self.watch_multi_helper('watchBidsAsks', '/spotMarket/level1:', symbols, params)
326
- if self.newUpdates:
327
- tickers: dict = {}
328
- tickers[ticker['symbol']] = ticker
329
- return tickers
330
- return self.filter_by_array(self.bidsasks, 'symbol', symbols)
331
-
332
- async def watch_multi_helper(self, methodName, channelName: str, symbols: Strings = None, params={}):
333
- await self.load_markets()
334
- symbols = self.market_symbols(symbols, None, False, True, False)
335
- length = len(symbols)
336
- if length > 100:
337
- raise ArgumentsRequired(self.id + ' ' + methodName + '() accepts a maximum of 100 symbols')
338
- messageHashes = []
339
- for i in range(0, len(symbols)):
340
- symbol = symbols[i]
341
- market = self.market(symbol)
342
- messageHashes.append('bidask@' + market['symbol'])
343
- url = await self.negotiate(False)
344
- marketIds = self.market_ids(symbols)
345
- joined = ','.join(marketIds)
346
- requestId = str(self.request_id())
347
- request: dict = {
348
- 'id': requestId,
349
- 'type': 'subscribe',
350
- 'topic': channelName + joined,
351
- 'response': True,
352
- }
353
- message = self.extend(request, params)
354
- return await self.watch_multiple(url, messageHashes, message, messageHashes)
355
-
356
- def handle_bid_ask(self, client: Client, message):
357
- #
358
- # arrives one symbol dict
359
- #
360
- # {
361
- # topic: '/spotMarket/level1:ETH-USDT',
362
- # type: 'message',
363
- # data: {
364
- # asks: ['3347.42', '2.0778387'],
365
- # bids: ['3347.41', '6.0411697'],
366
- # timestamp: 1712231142085
367
- # },
368
- # subject: 'level1'
369
- # }
370
- #
371
- parsedTicker = self.parse_ws_bid_ask(message)
372
- symbol = parsedTicker['symbol']
373
- self.bidsasks[symbol] = parsedTicker
374
- messageHash = 'bidask@' + symbol
375
- client.resolve(parsedTicker, messageHash)
376
-
377
- def parse_ws_bid_ask(self, ticker, market=None):
378
- topic = self.safe_string(ticker, 'topic')
379
- parts = topic.split(':')
380
- marketId = parts[1]
381
- market = self.safe_market(marketId, market)
382
- symbol = self.safe_string(market, 'symbol')
383
- data = self.safe_dict(ticker, 'data', {})
384
- ask = self.safe_list(data, 'asks', [])
385
- bid = self.safe_list(data, 'bids', [])
386
- timestamp = self.safe_integer(data, 'timestamp')
387
- return self.safe_ticker({
388
- 'symbol': symbol,
389
- 'timestamp': timestamp,
390
- 'datetime': self.iso8601(timestamp),
391
- 'ask': self.safe_number(ask, 0),
392
- 'askVolume': self.safe_number(ask, 1),
393
- 'bid': self.safe_number(bid, 0),
394
- 'bidVolume': self.safe_number(bid, 1),
395
- 'info': ticker,
396
- }, market)
397
-
398
- async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
399
- """
400
- watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
401
-
402
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/klines
403
-
404
- :param str symbol: unified symbol of the market to fetch OHLCV data for
405
- :param str timeframe: the length of time each candle represents
406
- :param int [since]: timestamp in ms of the earliest candle to fetch
407
- :param int [limit]: the maximum amount of candles to fetch
408
- :param dict [params]: extra parameters specific to the exchange API endpoint
409
- :returns int[][]: A list of candles ordered, open, high, low, close, volume
410
- """
411
- await self.load_markets()
412
- url = await self.negotiate(False)
413
- market = self.market(symbol)
414
- symbol = market['symbol']
415
- period = self.safe_string(self.timeframes, timeframe, timeframe)
416
- topic = '/market/candles:' + market['id'] + '_' + period
417
- messageHash = 'candles:' + symbol + ':' + timeframe
418
- ohlcv = await self.subscribe(url, messageHash, topic, params)
419
- if self.newUpdates:
420
- limit = ohlcv.getLimit(symbol, limit)
421
- return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
422
-
423
- def handle_ohlcv(self, client: Client, message):
424
- #
425
- # {
426
- # "data": {
427
- # "symbol": "BTC-USDT",
428
- # "candles": [
429
- # "1624881240",
430
- # "34138.8",
431
- # "34121.6",
432
- # "34138.8",
433
- # "34097.9",
434
- # "3.06097133",
435
- # "104430.955068564"
436
- # ],
437
- # "time": 1624881284466023700
438
- # },
439
- # "subject": "trade.candles.update",
440
- # "topic": "/market/candles:BTC-USDT_1min",
441
- # "type": "message"
442
- # }
443
- #
444
- data = self.safe_value(message, 'data', {})
445
- marketId = self.safe_string(data, 'symbol')
446
- candles = self.safe_value(data, 'candles', [])
447
- topic = self.safe_string(message, 'topic')
448
- parts = topic.split('_')
449
- interval = self.safe_string(parts, 1)
450
- # use a reverse lookup in a static map instead
451
- timeframe = self.find_timeframe(interval)
452
- market = self.safe_market(marketId)
453
- symbol = market['symbol']
454
- messageHash = 'candles:' + symbol + ':' + timeframe
455
- self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
456
- stored = self.safe_value(self.ohlcvs[symbol], timeframe)
457
- if stored is None:
458
- limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
459
- stored = ArrayCacheByTimestamp(limit)
460
- self.ohlcvs[symbol][timeframe] = stored
461
- ohlcv = self.parse_ohlcv(candles, market)
462
- stored.append(ohlcv)
463
- client.resolve(stored, messageHash)
464
-
465
- async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
466
- """
467
- get the list of most recent trades for a particular symbol
468
-
469
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/match-execution-data
470
-
471
- :param str symbol: unified symbol of the market to fetch trades for
472
- :param int [since]: timestamp in ms of the earliest trade to fetch
473
- :param int [limit]: the maximum amount of trades to fetch
474
- :param dict [params]: extra parameters specific to the exchange API endpoint
475
- :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
476
- """
477
- return await self.watch_trades_for_symbols([symbol], since, limit, params)
478
-
479
- async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
480
- """
481
- get the list of most recent trades for a particular symbol
482
-
483
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/match-execution-data
484
-
485
- :param str[] symbols:
486
- :param int [since]: timestamp in ms of the earliest trade to fetch
487
- :param int [limit]: the maximum amount of trades to fetch
488
- :param dict [params]: extra parameters specific to the exchange API endpoint
489
- :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
490
- """
491
- symbolsLength = len(symbols)
492
- if symbolsLength == 0:
493
- raise ArgumentsRequired(self.id + ' watchTradesForSymbols() requires a non-empty array of symbols')
494
- await self.load_markets()
495
- symbols = self.market_symbols(symbols)
496
- marketIds = self.market_ids(symbols)
497
- url = await self.negotiate(False)
498
- messageHashes = []
499
- subscriptionHashes = []
500
- topic = '/market/match:' + ','.join(marketIds)
501
- for i in range(0, len(symbols)):
502
- symbol = symbols[i]
503
- messageHashes.append('trades:' + symbol)
504
- marketId = marketIds[i]
505
- subscriptionHashes.append('/market/match:' + marketId)
506
- trades = await self.subscribe_multiple(url, messageHashes, topic, subscriptionHashes, params)
507
- if self.newUpdates:
508
- first = self.safe_value(trades, 0)
509
- tradeSymbol = self.safe_string(first, 'symbol')
510
- limit = trades.getLimit(tradeSymbol, limit)
511
- return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
512
-
513
- async def un_watch_trades_for_symbols(self, symbols: List[str], params={}) -> Any:
514
- """
515
- unWatches trades stream
516
-
517
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/match-execution-data
518
-
519
- :param str symbols:
520
- :param dict [params]: extra parameters specific to the exchange API endpoint
521
- :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
522
- """
523
- await self.load_markets()
524
- symbols = self.market_symbols(symbols, None, False)
525
- marketIds = self.market_ids(symbols)
526
- url = await self.negotiate(False)
527
- messageHashes = []
528
- subscriptionHashes = []
529
- topic = '/market/match:' + ','.join(marketIds)
530
- for i in range(0, len(symbols)):
531
- symbol = symbols[i]
532
- messageHashes.append('unsubscribe:trades:' + symbol)
533
- subscriptionHashes.append('trades:' + symbol)
534
- subscription = {
535
- 'messageHashes': messageHashes,
536
- 'subMessageHashes': subscriptionHashes,
537
- 'topic': 'trades',
538
- 'unsubscribe': True,
539
- 'symbols': symbols,
540
- }
541
- return await self.un_subscribe_multiple(url, messageHashes, topic, messageHashes, params, subscription)
542
-
543
- async def un_watch_trades(self, symbol: str, params={}) -> Any:
544
- """
545
- unWatches trades stream
546
-
547
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/match-execution-data
548
-
549
- :param str symbol: unified symbol of the market to fetch trades for
550
- :param dict [params]: extra parameters specific to the exchange API endpoint
551
- :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
552
- """
553
- return await self.un_watch_trades_for_symbols([symbol], params)
554
-
555
- def handle_trade(self, client: Client, message):
556
- #
557
- # {
558
- # "data": {
559
- # "sequence": "1568787654360",
560
- # "symbol": "BTC-USDT",
561
- # "side": "buy",
562
- # "size": "0.00536577",
563
- # "price": "9345",
564
- # "takerOrderId": "5e356c4a9f1a790008f8d921",
565
- # "time": "1580559434436443257",
566
- # "type": "match",
567
- # "makerOrderId": "5e356bffedf0010008fa5d7f",
568
- # "tradeId": "5e356c4aeefabd62c62a1ece"
569
- # },
570
- # "subject": "trade.l3match",
571
- # "topic": "/market/match:BTC-USDT",
572
- # "type": "message"
573
- # }
574
- #
575
- data = self.safe_value(message, 'data', {})
576
- trade = self.parse_trade(data)
577
- symbol = trade['symbol']
578
- messageHash = 'trades:' + symbol
579
- trades = self.safe_value(self.trades, symbol)
580
- if trades is None:
581
- limit = self.safe_integer(self.options, 'tradesLimit', 1000)
582
- trades = ArrayCache(limit)
583
- self.trades[symbol] = trades
584
- trades.append(trade)
585
- client.resolve(trades, messageHash)
586
-
587
- async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
588
- """
589
-
590
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level1-bbo-market-data
591
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-market-data
592
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-5-best-ask-bid-orders
593
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-50-best-ask-bid-orders
594
-
595
- watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
596
- :param str symbol: unified symbol of the market to fetch the order book for
597
- :param int [limit]: the maximum amount of order book entries to return
598
- :param dict [params]: extra parameters specific to the exchange API endpoint
599
- :param str [params.method]: either '/market/level2' or '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50' default is '/market/level2'
600
- :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
601
- """
602
- #
603
- # https://docs.kucoin.com/#level-2-market-data
604
- #
605
- # 1. After receiving the websocket Level 2 data flow, cache the data.
606
- # 2. Initiate a REST request to get the snapshot data of Level 2 order book.
607
- # 3. Playback the cached Level 2 data flow.
608
- # 4. Apply the new Level 2 data flow to the local snapshot to ensure that
609
- # the sequence of the new Level 2 update lines up with the sequence of
610
- # the previous Level 2 data. Discard all the message prior to that
611
- # sequence, and then playback the change to snapshot.
612
- # 5. Update the level2 full data based on sequence according to the
613
- # size. If the price is 0, ignore the messages and update the sequence.
614
- # If the size=0, update the sequence and remove the price of which the
615
- # size is 0 out of level 2. Fr other cases, please update the price.
616
- #
617
- return await self.watch_order_book_for_symbols([symbol], limit, params)
618
-
619
- async def un_watch_order_book(self, symbol: str, params={}) -> Any:
620
- """
621
-
622
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level1-bbo-market-data
623
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-market-data
624
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-5-best-ask-bid-orders
625
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-50-best-ask-bid-orders
626
-
627
- unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
628
- :param str symbol: unified symbol of the market to fetch the order book for
629
- :param dict [params]: extra parameters specific to the exchange API endpoint
630
- :param str [params.method]: either '/market/level2' or '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50' default is '/market/level2'
631
- :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
632
- """
633
- return await self.un_watch_order_book_for_symbols([symbol], params)
634
-
635
- async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
636
- """
637
-
638
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level1-bbo-market-data
639
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-market-data
640
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-5-best-ask-bid-orders
641
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-50-best-ask-bid-orders
642
-
643
- watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
644
- :param str[] symbols: unified array of symbols
645
- :param int [limit]: the maximum amount of order book entries to return
646
- :param dict [params]: extra parameters specific to the exchange API endpoint
647
- :param str [params.method]: either '/market/level2' or '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50' default is '/market/level2'
648
- :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
649
- """
650
- symbolsLength = len(symbols)
651
- if symbolsLength == 0:
652
- raise ArgumentsRequired(self.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols')
653
- if limit is not None:
654
- if (limit != 20) and (limit != 100) and (limit != 50) and (limit != 5):
655
- raise ExchangeError(self.id + " watchOrderBook 'limit' argument must be None, 5, 20, 50 or 100")
656
- await self.load_markets()
657
- symbols = self.market_symbols(symbols)
658
- marketIds = self.market_ids(symbols)
659
- url = await self.negotiate(False)
660
- method: Str = None
661
- method, params = self.handle_option_and_params(params, 'watchOrderBook', 'method', '/market/level2')
662
- if (limit == 5) or (limit == 50):
663
- method = '/spotMarket/level2Depth' + str(limit)
664
- topic = method + ':' + ','.join(marketIds)
665
- messageHashes = []
666
- subscriptionHashes = []
667
- for i in range(0, len(symbols)):
668
- symbol = symbols[i]
669
- messageHashes.append('orderbook:' + symbol)
670
- marketId = marketIds[i]
671
- subscriptionHashes.append(method + ':' + marketId)
672
- subscription = {}
673
- if method == '/market/level2': # other streams return the entire orderbook, so we don't need to fetch the snapshot through REST
674
- subscription = {
675
- 'method': self.handle_order_book_subscription,
676
- 'symbols': symbols,
677
- 'limit': limit,
678
- }
679
- orderbook = await self.subscribe_multiple(url, messageHashes, topic, subscriptionHashes, params, subscription)
680
- return orderbook.limit()
681
-
682
- async def un_watch_order_book_for_symbols(self, symbols: List[str], params={}) -> Any:
683
- """
684
-
685
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level1-bbo-market-data
686
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-market-data
687
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-5-best-ask-bid-orders
688
- https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-50-best-ask-bid-orders
689
-
690
- unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
691
- :param str[] symbols: unified array of symbols
692
- :param dict [params]: extra parameters specific to the exchange API endpoint
693
- :param str [params.method]: either '/market/level2' or '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50' default is '/market/level2'
694
- :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
695
- """
696
- limit = self.safe_integer(params, 'limit')
697
- params = self.omit(params, 'limit')
698
- await self.load_markets()
699
- symbols = self.market_symbols(symbols, None, False)
700
- marketIds = self.market_ids(symbols)
701
- url = await self.negotiate(False)
702
- method: Str = None
703
- method, params = self.handle_option_and_params(params, 'watchOrderBook', 'method', '/market/level2')
704
- if (limit == 5) or (limit == 50):
705
- method = '/spotMarket/level2Depth' + str(limit)
706
- topic = method + ':' + ','.join(marketIds)
707
- messageHashes = []
708
- subscriptionHashes = []
709
- for i in range(0, len(symbols)):
710
- symbol = symbols[i]
711
- messageHashes.append('unsubscribe:orderbook:' + symbol)
712
- subscriptionHashes.append('orderbook:' + symbol)
713
- subscription = {
714
- 'messageHashes': messageHashes,
715
- 'symbols': symbols,
716
- 'unsubscribe': True,
717
- 'topic': 'orderbook',
718
- 'subMessageHashes': subscriptionHashes,
719
- }
720
- return await self.un_subscribe_multiple(url, messageHashes, topic, messageHashes, params, subscription)
721
-
722
- def handle_order_book(self, client: Client, message):
723
- #
724
- # initial snapshot is fetched with ccxt's fetchOrderBook
725
- # the feed does not include a snapshot, just the deltas
726
- #
727
- # {
728
- # "type":"message",
729
- # "topic":"/market/level2:BTC-USDT",
730
- # "subject":"trade.l2update",
731
- # "data":{
732
- # "sequenceStart":1545896669105,
733
- # "sequenceEnd":1545896669106,
734
- # "symbol":"BTC-USDT",
735
- # "changes": {
736
- # "asks": [["6","1","1545896669105"]], # price, size, sequence
737
- # "bids": [["4","1","1545896669106"]]
738
- # }
739
- # }
740
- # }
741
- #
742
- # {
743
- # "topic": "/spotMarket/level2Depth5:BTC-USDT",
744
- # "type": "message",
745
- # "data": {
746
- # "asks": [
747
- # [
748
- # "42815.6",
749
- # "1.24016245"
750
- # ]
751
- # ],
752
- # "bids": [
753
- # [
754
- # "42815.5",
755
- # "0.08652716"
756
- # ]
757
- # ],
758
- # "timestamp": 1707204474018
759
- # },
760
- # "subject": "level2"
761
- # }
762
- #
763
- data = self.safe_value(message, 'data')
764
- subject = self.safe_string(message, 'subject')
765
- topic = self.safe_string(message, 'topic')
766
- topicParts = topic.split(':')
767
- topicSymbol = self.safe_string(topicParts, 1)
768
- topicChannel = self.safe_string(topicParts, 0)
769
- marketId = self.safe_string(data, 'symbol', topicSymbol)
770
- symbol = self.safe_symbol(marketId, None, '-')
771
- messageHash = 'orderbook:' + symbol
772
- # orderbook = self.safe_dict(self.orderbooks, symbol)
773
- if subject == 'level2':
774
- if not (symbol in self.orderbooks):
775
- self.orderbooks[symbol] = self.order_book()
776
- else:
777
- orderbook = self.orderbooks[symbol]
778
- orderbook.reset()
779
- self.orderbooks[symbol]['symbol'] = symbol
780
- else:
781
- if not (symbol in self.orderbooks):
782
- self.orderbooks[symbol] = self.order_book()
783
- orderbook = self.orderbooks[symbol]
784
- nonce = self.safe_integer(orderbook, 'nonce')
785
- deltaEnd = self.safe_integer_2(data, 'sequenceEnd', 'timestamp')
786
- if nonce is None:
787
- cacheLength = len(orderbook.cache)
788
- subscriptions = list(client.subscriptions.keys())
789
- subscription = None
790
- for i in range(0, len(subscriptions)):
791
- key = subscriptions[i]
792
- if (key.find(topicSymbol) >= 0) and (key.find(topicChannel) >= 0):
793
- subscription = client.subscriptions[key]
794
- break
795
- limit = self.safe_integer(subscription, 'limit')
796
- snapshotDelay = self.handle_option('watchOrderBook', 'snapshotDelay', 5)
797
- if cacheLength == snapshotDelay:
798
- self.spawn(self.load_order_book, client, messageHash, symbol, limit, {})
799
- orderbook.cache.append(data)
800
- return
801
- elif nonce >= deltaEnd:
802
- return
803
- self.handle_delta(self.orderbooks[symbol], data)
804
- client.resolve(self.orderbooks[symbol], messageHash)
805
-
806
- def get_cache_index(self, orderbook, cache):
807
- firstDelta = self.safe_value(cache, 0)
808
- nonce = self.safe_integer(orderbook, 'nonce')
809
- firstDeltaStart = self.safe_integer(firstDelta, 'sequenceStart')
810
- if nonce < firstDeltaStart - 1:
811
- return -1
812
- for i in range(0, len(cache)):
813
- delta = cache[i]
814
- deltaStart = self.safe_integer(delta, 'sequenceStart')
815
- deltaEnd = self.safe_integer(delta, 'sequenceEnd')
816
- if (nonce >= deltaStart - 1) and (nonce < deltaEnd):
817
- return i
818
- return len(cache)
819
-
820
- def handle_delta(self, orderbook, delta):
821
- timestamp = self.safe_integer_2(delta, 'time', 'timestamp')
822
- orderbook['nonce'] = self.safe_integer(delta, 'sequenceEnd', timestamp)
823
- orderbook['timestamp'] = timestamp
824
- orderbook['datetime'] = self.iso8601(timestamp)
825
- changes = self.safe_value(delta, 'changes', delta)
826
- bids = self.safe_value(changes, 'bids', [])
827
- asks = self.safe_value(changes, 'asks', [])
828
- storedBids = orderbook['bids']
829
- storedAsks = orderbook['asks']
830
- self.handle_bid_asks(storedBids, bids)
831
- self.handle_bid_asks(storedAsks, asks)
832
-
833
- def handle_bid_asks(self, bookSide, bidAsks):
834
- for i in range(0, len(bidAsks)):
835
- bidAsk = self.parse_bid_ask(bidAsks[i])
836
- bookSide.storeArray(bidAsk)
837
-
838
- def handle_order_book_subscription(self, client: Client, message, subscription):
839
- limit = self.safe_integer(subscription, 'limit')
840
- symbols = self.safe_value(subscription, 'symbols')
841
- if symbols is None:
842
- symbol = self.safe_string(subscription, 'symbol')
843
- self.orderbooks[symbol] = self.order_book({}, limit)
844
- else:
845
- for i in range(0, len(symbols)):
846
- symbol = symbols[i]
847
- self.orderbooks[symbol] = self.order_book({}, limit)
848
- # moved snapshot initialization to handleOrderBook to fix
849
- # https://github.com/ccxt/ccxt/issues/6820
850
- # the general idea is to fetch the snapshot after the first delta
851
- # but not before, because otherwise we cannot synchronize the feed
852
-
853
- def handle_subscription_status(self, client: Client, message):
854
- #
855
- # {
856
- # "id": "1578090438322",
857
- # "type": "ack"
858
- # }
859
- #
860
- id = self.safe_string(message, 'id')
861
- if not (id in client.subscriptions):
862
- return
863
- subscriptionHash = self.safe_string(client.subscriptions, id)
864
- subscription = self.safe_value(client.subscriptions, subscriptionHash)
865
- del client.subscriptions[id]
866
- method = self.safe_value(subscription, 'method')
867
- if method is not None:
868
- method(client, message, subscription)
869
- isUnSub = self.safe_bool(subscription, 'unsubscribe', False)
870
- if isUnSub:
871
- messageHashes = self.safe_list(subscription, 'messageHashes', [])
872
- subMessageHashes = self.safe_list(subscription, 'subMessageHashes', [])
873
- for i in range(0, len(messageHashes)):
874
- messageHash = messageHashes[i]
875
- subHash = subMessageHashes[i]
876
- self.clean_unsubscription(client, subHash, messageHash)
877
- self.clean_cache(subscription)
878
-
879
- def handle_system_status(self, client: Client, message):
880
- #
881
- # todo: answer the question whether handleSystemStatus should be renamed
882
- # and unified for any usage pattern that
883
- # involves system status and maintenance updates
884
- #
885
- # {
886
- # "id": "1578090234088", # connectId
887
- # "type": "welcome",
888
- # }
889
- #
890
- return message
891
-
892
- async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
893
- """
894
- watches information on multiple orders made by the user
895
-
896
- https://www.kucoin.com/docs/websocket/spot-trading/private-channels/private-order-change
897
- https://www.kucoin.com/docs/websocket/spot-trading/private-channels/stop-order-event
898
-
899
- :param str symbol: unified market symbol of the market orders were made in
900
- :param int [since]: the earliest time in ms to fetch orders for
901
- :param int [limit]: the maximum number of order structures to retrieve
902
- :param dict [params]: extra parameters specific to the exchange API endpoint
903
- :param boolean [params.trigger]: trigger orders are watched if True
904
- :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
905
- """
906
- await self.load_markets()
907
- trigger = self.safe_value_2(params, 'stop', 'trigger')
908
- params = self.omit(params, ['stop', 'trigger'])
909
- url = await self.negotiate(True)
910
- topic = '/spotMarket/advancedOrders' if trigger else '/spotMarket/tradeOrders'
911
- request: dict = {
912
- 'privateChannel': True,
913
- }
914
- messageHash = 'orders'
915
- if symbol is not None:
916
- market = self.market(symbol)
917
- symbol = market['symbol']
918
- messageHash = messageHash + ':' + symbol
919
- orders = await self.subscribe(url, messageHash, topic, self.extend(request, params))
920
- if self.newUpdates:
921
- limit = orders.getLimit(symbol, limit)
922
- return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
923
-
924
- def parse_ws_order_status(self, status):
925
- statuses: dict = {
926
- 'open': 'open',
927
- 'filled': 'closed',
928
- 'match': 'open',
929
- 'update': 'open',
930
- 'canceled': 'canceled',
931
- 'cancel': 'canceled',
932
- 'TRIGGERED': 'triggered',
933
- }
934
- return self.safe_string(statuses, status, status)
935
-
936
- def parse_ws_order(self, order, market=None):
937
- #
938
- # /spotMarket/tradeOrders
939
- #
940
- # {
941
- # "symbol": "XCAD-USDT",
942
- # "orderType": "limit",
943
- # "side": "buy",
944
- # "orderId": "6249167327218b000135e749",
945
- # "type": "canceled",
946
- # "orderTime": 1648957043065280224,
947
- # "size": "100.452",
948
- # "filledSize": "0",
949
- # "price": "2.9635",
950
- # "clientOid": "buy-XCAD-USDT-1648957043010159",
951
- # "remainSize": "0",
952
- # "status": "done",
953
- # "ts": 1648957054031001037
954
- # }
955
- #
956
- # /spotMarket/advancedOrders
957
- #
958
- # {
959
- # "createdAt": 1589789942337,
960
- # "orderId": "5ec244f6a8a75e0009958237",
961
- # "orderPrice": "0.00062",
962
- # "orderType": "stop",
963
- # "side": "sell",
964
- # "size": "1",
965
- # "stop": "entry",
966
- # "stopPrice": "0.00062",
967
- # "symbol": "KCS-BTC",
968
- # "tradeType": "TRADE",
969
- # "triggerSuccess": True,
970
- # "ts": 1589790121382281286,
971
- # "type": "triggered"
972
- # }
973
- #
974
- rawType = self.safe_string(order, 'type')
975
- status = self.parse_ws_order_status(rawType)
976
- timestamp = self.safe_integer_2(order, 'orderTime', 'createdAt')
977
- marketId = self.safe_string(order, 'symbol')
978
- market = self.safe_market(marketId, market)
979
- triggerPrice = self.safe_string(order, 'stopPrice')
980
- triggerSuccess = self.safe_value(order, 'triggerSuccess')
981
- triggerFail = (triggerSuccess is not True) and (triggerSuccess is not None) # TODO: updated to triggerSuccess == False once transpiler transpiles it correctly
982
- if (status == 'triggered') and triggerFail:
983
- status = 'canceled'
984
- return self.safe_order({
985
- 'info': order,
986
- 'symbol': market['symbol'],
987
- 'id': self.safe_string(order, 'orderId'),
988
- 'clientOrderId': self.safe_string(order, 'clientOid'),
989
- 'timestamp': timestamp,
990
- 'datetime': self.iso8601(timestamp),
991
- 'lastTradeTimestamp': None,
992
- 'type': self.safe_string_lower(order, 'orderType'),
993
- 'timeInForce': None,
994
- 'postOnly': None,
995
- 'side': self.safe_string_lower(order, 'side'),
996
- 'price': self.safe_string_2(order, 'price', 'orderPrice'),
997
- 'stopPrice': triggerPrice,
998
- 'triggerPrice': triggerPrice,
999
- 'amount': self.safe_string(order, 'size'),
1000
- 'cost': None,
1001
- 'average': None,
1002
- 'filled': self.safe_string(order, 'filledSize'),
1003
- 'remaining': None,
1004
- 'status': status,
1005
- 'fee': None,
1006
- 'trades': None,
1007
- }, market)
1008
-
1009
- def handle_order(self, client: Client, message):
1010
- #
1011
- # Trigger Orders
1012
- #
1013
- # {
1014
- # "createdAt": 1692745706437,
1015
- # "error": "Balance insufficient!", # not always there
1016
- # "orderId": "vs86kp757vlda6ni003qs70v",
1017
- # "orderPrice": "0.26",
1018
- # "orderType": "stop",
1019
- # "side": "sell",
1020
- # "size": "5",
1021
- # "stop": "loss",
1022
- # "stopPrice": "0.26",
1023
- # "symbol": "ADA-USDT",
1024
- # "tradeType": "TRADE",
1025
- # "triggerSuccess": False, # not always there
1026
- # "ts": "1692745706442929298",
1027
- # "type": "open"
1028
- # }
1029
- #
1030
- messageHash = 'orders'
1031
- data = self.safe_value(message, 'data')
1032
- tradeId = self.safe_string(data, 'tradeId')
1033
- if tradeId is not None:
1034
- self.handle_my_trade(client, message)
1035
- parsed = self.parse_ws_order(data)
1036
- symbol = self.safe_string(parsed, 'symbol')
1037
- orderId = self.safe_string(parsed, 'id')
1038
- triggerPrice = self.safe_value(parsed, 'triggerPrice')
1039
- isTriggerOrder = (triggerPrice is not None)
1040
- if self.orders is None:
1041
- limit = self.safe_integer(self.options, 'ordersLimit', 1000)
1042
- self.orders = ArrayCacheBySymbolById(limit)
1043
- self.triggerOrders = ArrayCacheBySymbolById(limit)
1044
- cachedOrders = self.triggerOrders if isTriggerOrder else self.orders
1045
- orders = self.safe_value(cachedOrders.hashmap, symbol, {})
1046
- order = self.safe_value(orders, orderId)
1047
- if order is not None:
1048
- # todo add others to calculate average etc
1049
- if order['status'] == 'closed':
1050
- parsed['status'] = 'closed'
1051
- cachedOrders.append(parsed)
1052
- client.resolve(cachedOrders, messageHash)
1053
- symbolSpecificMessageHash = messageHash + ':' + symbol
1054
- client.resolve(cachedOrders, symbolSpecificMessageHash)
1055
-
1056
- async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
1057
- """
1058
- watches information on multiple trades made by the user
1059
-
1060
- https://www.kucoin.com/docs/websocket/spot-trading/private-channels/private-order-change
1061
-
1062
- :param str symbol: unified market symbol of the market trades were made in
1063
- :param int [since]: the earliest time in ms to fetch trades for
1064
- :param int [limit]: the maximum number of trade structures to retrieve
1065
- :param dict [params]: extra parameters specific to the exchange API endpoint
1066
- :param str [params.method]: '/spotMarket/tradeOrders' or '/spot/tradeFills' default is '/spotMarket/tradeOrders'
1067
- :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1068
- """
1069
- await self.load_markets()
1070
- url = await self.negotiate(True)
1071
- topic: Str = None
1072
- topic, params = self.handle_option_and_params(params, 'watchMyTrades', 'method', '/spotMarket/tradeOrders')
1073
- request: dict = {
1074
- 'privateChannel': True,
1075
- }
1076
- messageHash = 'myTrades'
1077
- if symbol is not None:
1078
- market = self.market(symbol)
1079
- symbol = market['symbol']
1080
- messageHash = messageHash + ':' + market['symbol']
1081
- trades = await self.subscribe(url, messageHash, topic, self.extend(request, params))
1082
- if self.newUpdates:
1083
- limit = trades.getLimit(symbol, limit)
1084
- return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
1085
-
1086
- def handle_my_trade(self, client: Client, message):
1087
- #
1088
- # {
1089
- # "type": "message",
1090
- # "topic": "/spotMarket/tradeOrders",
1091
- # "subject": "orderChange",
1092
- # "channelType": "private",
1093
- # "data": {
1094
- # "symbol": "KCS-USDT",
1095
- # "orderType": "limit",
1096
- # "side": "sell",
1097
- # "orderId": "5efab07953bdea00089965fa",
1098
- # "liquidity": "taker",
1099
- # "type": "match",
1100
- # "feeType": "takerFee",
1101
- # "orderTime": 1670329987026,
1102
- # "size": "0.1",
1103
- # "filledSize": "0.1",
1104
- # "price": "0.938",
1105
- # "matchPrice": "0.96738",
1106
- # "matchSize": "0.1",
1107
- # "tradeId": "5efab07a4ee4c7000a82d6d9",
1108
- # "clientOid": "1593487481000313",
1109
- # "remainSize": "0",
1110
- # "status": "match",
1111
- # "ts": 1670329987311000000
1112
- # }
1113
- # }
1114
- #
1115
- if self.myTrades is None:
1116
- limit = self.safe_integer(self.options, 'tradesLimit', 1000)
1117
- self.myTrades = ArrayCacheBySymbolById(limit)
1118
- data = self.safe_dict(message, 'data')
1119
- parsed = self.parse_ws_trade(data)
1120
- myTrades = self.myTrades
1121
- myTrades.append(parsed)
1122
- messageHash = 'myTrades'
1123
- client.resolve(self.myTrades, messageHash)
1124
- symbolSpecificMessageHash = messageHash + ':' + parsed['symbol']
1125
- client.resolve(self.myTrades, symbolSpecificMessageHash)
1126
-
1127
- def parse_ws_trade(self, trade, market=None):
1128
- #
1129
- # /spotMarket/tradeOrders
1130
- #
1131
- # {
1132
- # "symbol": "KCS-USDT",
1133
- # "orderType": "limit",
1134
- # "side": "sell",
1135
- # "orderId": "5efab07953bdea00089965fa",
1136
- # "liquidity": "taker",
1137
- # "type": "match",
1138
- # "feeType": "takerFee",
1139
- # "orderTime": 1670329987026,
1140
- # "size": "0.1",
1141
- # "filledSize": "0.1",
1142
- # "price": "0.938",
1143
- # "matchPrice": "0.96738",
1144
- # "matchSize": "0.1",
1145
- # "tradeId": "5efab07a4ee4c7000a82d6d9",
1146
- # "clientOid": "1593487481000313",
1147
- # "remainSize": "0",
1148
- # "status": "match",
1149
- # "ts": 1670329987311000000
1150
- # }
1151
- #
1152
- # /spot/tradeFills
1153
- #
1154
- # {
1155
- # "fee": 0.00262148,
1156
- # "feeCurrency": "USDT",
1157
- # "feeRate": 0.001,
1158
- # "orderId": "62417436b29df8000183df2f",
1159
- # "orderType": "market",
1160
- # "price": 131.074,
1161
- # "side": "sell",
1162
- # "size": 0.02,
1163
- # "symbol": "LTC-USDT",
1164
- # "time": "1648456758734571745",
1165
- # "tradeId": "624174362e113d2f467b3043"
1166
- # }
1167
- #
1168
- marketId = self.safe_string(trade, 'symbol')
1169
- market = self.safe_market(marketId, market, '-')
1170
- symbol = market['symbol']
1171
- type = self.safe_string(trade, 'orderType')
1172
- side = self.safe_string(trade, 'side')
1173
- tradeId = self.safe_string(trade, 'tradeId')
1174
- price = self.safe_string(trade, 'matchPrice')
1175
- amount = self.safe_string(trade, 'matchSize')
1176
- if price is None:
1177
- # /spot/tradeFills
1178
- price = self.safe_string(trade, 'price')
1179
- amount = self.safe_string(trade, 'size')
1180
- order = self.safe_string(trade, 'orderId')
1181
- timestamp = self.safe_integer_product_2(trade, 'ts', 'time', 0.000001)
1182
- feeCurrency = market['quote']
1183
- feeRate = self.safe_string(trade, 'feeRate')
1184
- feeCost = self.safe_string(trade, 'fee')
1185
- return self.safe_trade({
1186
- 'info': trade,
1187
- 'timestamp': timestamp,
1188
- 'datetime': self.iso8601(timestamp),
1189
- 'symbol': symbol,
1190
- 'id': tradeId,
1191
- 'order': order,
1192
- 'type': type,
1193
- 'takerOrMaker': self.safe_string(trade, 'liquidity'),
1194
- 'side': side,
1195
- 'price': price,
1196
- 'amount': amount,
1197
- 'cost': None,
1198
- 'fee': {
1199
- 'cost': feeCost,
1200
- 'rate': feeRate,
1201
- 'currency': feeCurrency,
1202
- },
1203
- }, market)
1204
-
1205
- async def watch_balance(self, params={}) -> Balances:
1206
- """
1207
- watch balance and get the amount of funds available for trading or funds locked in orders
1208
-
1209
- https://www.kucoin.com/docs/websocket/spot-trading/private-channels/account-balance-change
1210
-
1211
- :param dict [params]: extra parameters specific to the exchange API endpoint
1212
- :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1213
- """
1214
- await self.load_markets()
1215
- url = await self.negotiate(True)
1216
- topic = '/account/balance'
1217
- request: dict = {
1218
- 'privateChannel': True,
1219
- }
1220
- messageHash = 'balance'
1221
- return await self.subscribe(url, messageHash, topic, self.extend(request, params))
1222
-
1223
- def handle_balance(self, client: Client, message):
1224
- #
1225
- # {
1226
- # "id":"6217a451294b030001e3a26a",
1227
- # "type":"message",
1228
- # "topic":"/account/balance",
1229
- # "userId":"6217707c52f97f00012a67db",
1230
- # "channelType":"private",
1231
- # "subject":"account.balance",
1232
- # "data":{
1233
- # "accountId":"62177fe67810720001db2f18",
1234
- # "available":"89",
1235
- # "availableChange":"-30",
1236
- # "currency":"USDT",
1237
- # "hold":"0",
1238
- # "holdChange":"0",
1239
- # "relationContext":{
1240
- # },
1241
- # "relationEvent":"main.transfer",
1242
- # "relationEventId":"6217a451294b030001e3a26a",
1243
- # "time":"1645716561816",
1244
- # "total":"89"
1245
- # }
1246
- #
1247
- data = self.safe_value(message, 'data', {})
1248
- messageHash = 'balance'
1249
- currencyId = self.safe_string(data, 'currency')
1250
- relationEvent = self.safe_string(data, 'relationEvent')
1251
- requestAccountType = None
1252
- if relationEvent is not None:
1253
- relationEventParts = relationEvent.split('.')
1254
- requestAccountType = self.safe_string(relationEventParts, 0)
1255
- selectedType = self.safe_string_2(self.options, 'watchBalance', 'defaultType', 'trade') # trade, main, margin or other
1256
- accountsByType = self.safe_value(self.options, 'accountsByType')
1257
- uniformType = self.safe_string(accountsByType, requestAccountType, 'trade')
1258
- if not (uniformType in self.balance):
1259
- self.balance[uniformType] = {}
1260
- self.balance[uniformType]['info'] = data
1261
- timestamp = self.safe_integer(data, 'time')
1262
- self.balance[uniformType]['timestamp'] = timestamp
1263
- self.balance[uniformType]['datetime'] = self.iso8601(timestamp)
1264
- code = self.safe_currency_code(currencyId)
1265
- account = self.account()
1266
- account['free'] = self.safe_string(data, 'available')
1267
- account['used'] = self.safe_string(data, 'hold')
1268
- account['total'] = self.safe_string(data, 'total')
1269
- self.balance[uniformType][code] = account
1270
- self.balance[uniformType] = self.safe_balance(self.balance[uniformType])
1271
- if uniformType == selectedType:
1272
- client.resolve(self.balance[uniformType], messageHash)
1273
-
1274
- def handle_subject(self, client: Client, message):
1275
- #
1276
- # {
1277
- # "type":"message",
1278
- # "topic":"/market/level2:BTC-USDT",
1279
- # "subject":"trade.l2update",
1280
- # "data":{
1281
- # "sequenceStart":1545896669105,
1282
- # "sequenceEnd":1545896669106,
1283
- # "symbol":"BTC-USDT",
1284
- # "changes": {
1285
- # "asks": [["6","1","1545896669105"]], # price, size, sequence
1286
- # "bids": [["4","1","1545896669106"]]
1287
- # }
1288
- # }
1289
- # }
1290
- #
1291
- topic = self.safe_string(message, 'topic')
1292
- if topic == '/market/ticker:all':
1293
- self.handle_ticker(client, message)
1294
- return
1295
- subject = self.safe_string(message, 'subject')
1296
- methods: dict = {
1297
- 'level1': self.handle_bid_ask,
1298
- 'level2': self.handle_order_book,
1299
- 'trade.l2update': self.handle_order_book,
1300
- 'trade.ticker': self.handle_ticker,
1301
- 'trade.snapshot': self.handle_ticker,
1302
- 'trade.l3match': self.handle_trade,
1303
- 'trade.candles.update': self.handle_ohlcv,
1304
- 'account.balance': self.handle_balance,
1305
- 'orderChange': self.handle_order,
1306
- 'stopOrder': self.handle_order,
1307
- '/spot/tradeFills': self.handle_my_trade,
1308
- }
1309
- method = self.safe_value(methods, subject)
1310
- if method is not None:
1311
- method(client, message)
1312
-
1313
- def ping(self, client: Client):
1314
- # kucoin does not support built-in ws protocol-level ping-pong
1315
- # instead it requires a custom json-based text ping-pong
1316
- # https://docs.kucoin.com/#ping
1317
- id = str(self.request_id())
1318
- return {
1319
- 'id': id,
1320
- 'type': 'ping',
1321
- }
1322
-
1323
- def handle_pong(self, client: Client, message):
1324
- client.lastPong = self.milliseconds()
1325
- # https://docs.kucoin.com/#ping
1326
-
1327
- def handle_error_message(self, client: Client, message):
1328
- #
1329
- # {
1330
- # "id": "1",
1331
- # "type": "error",
1332
- # "code": 415,
1333
- # "data": "type is not supported"
1334
- # }
1335
- #
1336
- data = self.safe_string(message, 'data', '')
1337
- if data == 'token is expired':
1338
- type = 'public'
1339
- if client.url.find('connectId=private') >= 0:
1340
- type = 'private'
1341
- self.options['urls'][type] = None
1342
- self.handle_errors(None, None, client.url, None, None, data, message, None, None)
1343
-
1344
- def handle_message(self, client: Client, message):
1345
- type = self.safe_string(message, 'type')
1346
- methods: dict = {
1347
- # 'heartbeat': self.handleHeartbeat,
1348
- 'welcome': self.handle_system_status,
1349
- 'ack': self.handle_subscription_status,
1350
- 'message': self.handle_subject,
1351
- 'pong': self.handle_pong,
1352
- 'error': self.handle_error_message,
1353
- }
1354
- method = self.safe_value(methods, type)
1355
- if method is not None:
1356
- method(client, message)