dccd 2.0.2__tar.gz → 2.1.0__tar.gz

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 (55) hide show
  1. {dccd-2.0.2 → dccd-2.1.0}/CHANGELOG.md +39 -0
  2. {dccd-2.0.2 → dccd-2.1.0}/PKG-INFO +26 -19
  3. {dccd-2.0.2 → dccd-2.1.0}/README.rst +24 -18
  4. {dccd-2.0.2 → dccd-2.1.0}/dccd/continuous_dl/__init__.py +13 -3
  5. dccd-2.1.0/dccd/continuous_dl/binance.py +263 -0
  6. {dccd-2.0.2 → dccd-2.1.0}/dccd/continuous_dl/bitfinex.py +66 -133
  7. {dccd-2.0.2 → dccd-2.1.0}/dccd/continuous_dl/bitmex.py +120 -146
  8. {dccd-2.0.2 → dccd-2.1.0}/dccd/continuous_dl/bybit.py +31 -2
  9. {dccd-2.0.2 → dccd-2.1.0}/dccd/continuous_dl/exchange.py +20 -51
  10. dccd-2.1.0/dccd/continuous_dl/kraken.py +336 -0
  11. dccd-2.1.0/dccd/continuous_dl/okx.py +330 -0
  12. {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/binance.py +5 -2
  13. {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/bybit.py +5 -3
  14. {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/coinbase.py +5 -4
  15. {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/exchange.py +112 -30
  16. {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/kraken.py +28 -8
  17. {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/okx.py +5 -3
  18. {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/conftest.py +9 -0
  19. {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_binance.py +19 -0
  20. dccd-2.1.0/dccd/tests/test_binance_ws.py +120 -0
  21. dccd-2.1.0/dccd/tests/test_bitfinex.py +83 -0
  22. dccd-2.1.0/dccd/tests/test_bitmex.py +108 -0
  23. {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_bybit.py +15 -0
  24. dccd-2.1.0/dccd/tests/test_bybit_ws.py +113 -0
  25. {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_coinbase.py +15 -0
  26. dccd-2.1.0/dccd/tests/test_date_time.py +127 -0
  27. dccd-2.1.0/dccd/tests/test_histo_dl.py +60 -0
  28. {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_kraken.py +15 -0
  29. dccd-2.1.0/dccd/tests/test_kraken_ws.py +162 -0
  30. {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_okx.py +15 -0
  31. dccd-2.1.0/dccd/tests/test_okx_ws.py +151 -0
  32. dccd-2.1.0/dccd/tests/test_websocket.py +69 -0
  33. {dccd-2.0.2 → dccd-2.1.0}/dccd/tools/__init__.py +0 -2
  34. {dccd-2.0.2 → dccd-2.1.0}/dccd/tools/date_time.py +59 -30
  35. {dccd-2.0.2 → dccd-2.1.0}/dccd/tools/io.py +14 -11
  36. {dccd-2.0.2 → dccd-2.1.0}/dccd.egg-info/PKG-INFO +26 -19
  37. {dccd-2.0.2 → dccd-2.1.0}/dccd.egg-info/SOURCES.txt +11 -0
  38. {dccd-2.0.2 → dccd-2.1.0}/dccd.egg-info/requires.txt +1 -0
  39. {dccd-2.0.2 → dccd-2.1.0}/pyproject.toml +6 -8
  40. dccd-2.0.2/dccd/tests/test_date_time.py +0 -46
  41. {dccd-2.0.2 → dccd-2.1.0}/CONTRIBUTING.md +0 -0
  42. {dccd-2.0.2 → dccd-2.1.0}/LICENSE.txt +0 -0
  43. {dccd-2.0.2 → dccd-2.1.0}/MANIFEST.in +0 -0
  44. {dccd-2.0.2 → dccd-2.1.0}/dccd/__init__.py +0 -0
  45. {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/__init__.py +0 -0
  46. {dccd-2.0.2 → dccd-2.1.0}/dccd/models.py +0 -0
  47. {dccd-2.0.2 → dccd-2.1.0}/dccd/process_data.py +0 -0
  48. {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/__init__.py +0 -0
  49. {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_io.py +0 -0
  50. {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_models.py +0 -0
  51. {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_process_data.py +0 -0
  52. {dccd-2.0.2 → dccd-2.1.0}/dccd/tools/websocket.py +0 -0
  53. {dccd-2.0.2 → dccd-2.1.0}/dccd.egg-info/dependency_links.txt +0 -0
  54. {dccd-2.0.2 → dccd-2.1.0}/dccd.egg-info/top_level.txt +0 -0
  55. {dccd-2.0.2 → dccd-2.1.0}/setup.cfg +0 -0
@@ -6,6 +6,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.1.0] - 2026-05-15
10
+
11
+ ### Added
12
+
13
+ - `dccd/tests/test_binance.py`, `test_kraken.py`, `test_bybit.py`, `test_okx.py`, `test_coinbase.py` — REST error-scenario tests: HTTP 500 and malformed response for every exchange (#22)
14
+ - `dccd/continuous_dl/binance.py` — `DownloadBinanceData` streaming trades and order book via Binance combined WebSocket streams (#20)
15
+ - `dccd/continuous_dl/kraken.py` — `DownloadKrakenData` streaming trades, order book, and OHLCV via Kraken WebSocket v2 (#20)
16
+ - `dccd/continuous_dl/okx.py` — `DownloadOKXData` streaming trades, order book, and candles via OKX WebSocket v5 (#20)
17
+ - `get_trades_*`, `get_orderbook_*`, `get_data_*` high-level helpers for Binance, Kraken, and OKX (#20)
18
+ - `dccd/tests/test_binance_ws.py`, `test_kraken_ws.py`, `test_okx_ws.py` — 34 new tests for the new WS modules (#20)
19
+ - `README.rst` and `doc/source/index.rst` — exchange support matrix table (REST/WS × data type) (#20)
20
+ - `dccd/tests/test_websocket.py`, `test_bitfinex.py`, `test_bitmex.py`, `test_bybit_ws.py` — tests for `continuous_dl` and `BasisWebSocket`; coverage lifted from excluded to 82% overall (#12)
21
+ - `dccd/tests/test_histo_dl.py` — tests for `_get_last_date` (xlsx, csv, parquet, empty directory) (#12)
22
+ - `pyproject.toml` — `pytest-asyncio>=0.23` added to dev dependencies (#12)
23
+
24
+ ### Fixed
25
+
26
+ - `dccd/tools/date_time.py` — `span_to_str` and `str_to_span` now cover all spans supported by the exchanges: 180 s (3 m), 900 s (15 m), 14400 s (4 h), 21600 s (6 h), 28800 s (8 h), 43200 s (12 h), 259200 s (3 d), 1296000 s (15 d), 2592000 s (1 M); previously any span outside the original 7 values returned `None` and silently broke the save path (#21)
27
+ - `dccd/histo_dl/kraken.py` — `import_data` now raises `UserWarning` when `end` is passed, as the Kraken OHLC API does not support a custom end date and silently ignored the parameter (#21)
28
+
29
+ ### Changed
30
+
31
+ - `dccd/continuous_dl/exchange.py` — `get_parser()` now raises `KeyError` on unknown key instead of falling back to the removed debug parser; `_loop()` awaits `is_connect` instead of `_data` (#22)
32
+ - `dccd/continuous_dl/bitmex.py`, `dccd/continuous_dl/bybit.py` — added numpydoc docstrings on `_parser_trades()` and `_parser_book()` (#22)
33
+ - `dccd/histo_dl/exchange.py` — `ImportDataCryptoCurrencies` docstring updated: `See Also` lists all five exchanges; `platform` parameter documents all supported values; fixed typos (#22)
34
+ - `dccd/histo_dl/exchange.py` — `ImportDataCryptoCurrencies` now inherits from `ABC` and `_import_data` is decorated with `@abstractmethod`, preventing accidental instantiation of the base class (#21)
35
+ - `dccd/histo_dl/binance.py`, `coinbase.py`, `bybit.py`, `okx.py`, `kraken.py` — added `from __future__ import annotations`, `from typing import Any`, and full type hints on `_import_data` and `import_data` signatures (#21)
36
+ - `dccd/histo_dl/exchange.py` — `_get_last_date` now reads `.csv` and `.parquet` files in addition to `.xlsx` instead of falling back to 2012-01-01 (#12)
37
+ - `dccd/histo_dl/exchange.py` — completed numpydoc docstrings for `_get_last_date`, `_set_by_period`, `_name_file`, `_excel_format`, `_sort_data`, `set_hierarchy` (#12)
38
+ - `dccd/tools/io.py` — documented `driver`, `username`, `password`, `host`, `port` parameters of `save_as_sql` (#12)
39
+ - `dccd/continuous_dl/exchange.py` — documented `time_step=None` tick-by-tick behaviour in `ContinuousDownloader` (#12)
40
+ - `dccd/continuous_dl/bitfinex.py` — resolved all inline TODOs, added full type annotations, removed dead `__main__` block (#12)
41
+ - `dccd/continuous_dl/bitmex.py` — resolved all inline TODOs, added full type annotations, fixed undefined `pair` variable in `get_data_bitmex`, removed dead `__main__` block (#12)
42
+ - `pyproject.toml` — removed `bitfinex` and `bitmex` from mypy `ignore_errors` override; lifted `continuous_dl/*` and `tools/websocket.py` from coverage omit (#12)
43
+
44
+ ### Removed
45
+
46
+ - `ContinuousDownloader._parser_debug()` — dead method, never called; `dccd/tools/__init__.py` commented-out imports removed (#22)
47
+
9
48
  ## [2.0.2] - 2026-05-15
10
49
 
11
50
  ### Changed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dccd
3
- Version: 2.0.2
3
+ Version: 2.1.0
4
4
  Summary: Download Crypto Currency Data from different exchanges.
5
5
  Author-email: Arthur Bernard <arthur.bernard.92@gmail.com>
6
6
  License: MIT
@@ -35,6 +35,7 @@ Requires-Dist: pyarrow>=13; extra == "io"
35
35
  Requires-Dist: polars>=0.20; extra == "io"
36
36
  Provides-Extra: dev
37
37
  Requires-Dist: pytest>=7.4; extra == "dev"
38
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
38
39
  Requires-Dist: pytest-cov>=4.1; extra == "dev"
39
40
  Requires-Dist: ruff>=0.4; extra == "dev"
40
41
  Requires-Dist: interrogate>=1.5; extra == "dev"
@@ -75,7 +76,11 @@ Download Crypto-Currency Data
75
76
  :target: https://download-crypto-currencies-data.readthedocs.io/en/latest/
76
77
  :alt: Documentation Status
77
78
 
78
- .. image:: https://raw.githubusercontent.com/ArthurBernard/Download_Crypto_Currencies_Data/master/interrogate_badge_output.svg
79
+ .. image:: https://codecov.io/gh/ArthurBernard/Download_Crypto_Currencies_Data/branch/master/graph/badge.svg
80
+ :target: https://codecov.io/gh/ArthurBernard/Download_Crypto_Currencies_Data
81
+ :alt: Coverage
82
+
83
+ .. image:: https://raw.githubusercontent.com/ArthurBernard/Download_Crypto_Currencies_Data/badges/interrogate_badge.svg
79
84
  :target: https://github.com/ArthurBernard/Download_Crypto_Currencies_Data
80
85
  :alt: Docstring Coverage
81
86
 
@@ -107,23 +112,25 @@ From source::
107
112
  Supported exchanges
108
113
  ===================
109
114
 
110
- +------------------+------------+-----------------+
111
- | Exchange | Historical | Real-time |
112
- +==================+============+=================+
113
- | Binance | ✓ | |
114
- +------------------+------------+-----------------+
115
- | Coinbase | ✓ | |
116
- +------------------+------------+-----------------+
117
- | Kraken | ✓ | |
118
- +------------------+------------+-----------------+
119
- | Bybit | ✓ | ✓ |
120
- +------------------+------------+-----------------+
121
- | OKX | ✓ | |
122
- +------------------+------------+-----------------+
123
- | Bitfinex | | ✓ |
124
- +------------------+------------+-----------------+
125
- | Bitmex | | ✓ |
126
- +------------------+------------+-----------------+
115
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
116
+ | Exchange | REST OHLCV | REST Trades | REST Order Book | WS OHLCV | WS Trades | WS Order Book |
117
+ +==================+============+=============+=================+==========+===========+================+
118
+ | Binance | ✓ | | | | ✓ | ✓ |
119
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
120
+ | Coinbase | ✓ | | | | | |
121
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
122
+ | Kraken | ✓ | | | ✓ | ✓ | ✓ |
123
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
124
+ | Bybit | ✓ | | | | | ✓ |
125
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
126
+ | OKX | ✓ | | | ✓ | ✓ | ✓ |
127
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
128
+ | Bitfinex | | | | ✓\* | | ✓ |
129
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
130
+ | Bitmex | | | | | | ✓ |
131
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
132
+
133
+ \* Bitfinex WS OHLCV is aggregated from the trades stream via ``get_ohlc_bitfinex``.
127
134
 
128
135
  Presentation
129
136
  ============
@@ -25,7 +25,11 @@ Download Crypto-Currency Data
25
25
  :target: https://download-crypto-currencies-data.readthedocs.io/en/latest/
26
26
  :alt: Documentation Status
27
27
 
28
- .. image:: https://raw.githubusercontent.com/ArthurBernard/Download_Crypto_Currencies_Data/master/interrogate_badge_output.svg
28
+ .. image:: https://codecov.io/gh/ArthurBernard/Download_Crypto_Currencies_Data/branch/master/graph/badge.svg
29
+ :target: https://codecov.io/gh/ArthurBernard/Download_Crypto_Currencies_Data
30
+ :alt: Coverage
31
+
32
+ .. image:: https://raw.githubusercontent.com/ArthurBernard/Download_Crypto_Currencies_Data/badges/interrogate_badge.svg
29
33
  :target: https://github.com/ArthurBernard/Download_Crypto_Currencies_Data
30
34
  :alt: Docstring Coverage
31
35
 
@@ -57,23 +61,25 @@ From source::
57
61
  Supported exchanges
58
62
  ===================
59
63
 
60
- +------------------+------------+-----------------+
61
- | Exchange | Historical | Real-time |
62
- +==================+============+=================+
63
- | Binance | ✓ | |
64
- +------------------+------------+-----------------+
65
- | Coinbase | ✓ | |
66
- +------------------+------------+-----------------+
67
- | Kraken | ✓ | |
68
- +------------------+------------+-----------------+
69
- | Bybit | ✓ | ✓ |
70
- +------------------+------------+-----------------+
71
- | OKX | ✓ | |
72
- +------------------+------------+-----------------+
73
- | Bitfinex | | ✓ |
74
- +------------------+------------+-----------------+
75
- | Bitmex | | ✓ |
76
- +------------------+------------+-----------------+
64
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
65
+ | Exchange | REST OHLCV | REST Trades | REST Order Book | WS OHLCV | WS Trades | WS Order Book |
66
+ +==================+============+=============+=================+==========+===========+================+
67
+ | Binance | ✓ | | | | ✓ | ✓ |
68
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
69
+ | Coinbase | ✓ | | | | | |
70
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
71
+ | Kraken | ✓ | | | ✓ | ✓ | ✓ |
72
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
73
+ | Bybit | ✓ | | | | | ✓ |
74
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
75
+ | OKX | ✓ | | | ✓ | ✓ | ✓ |
76
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
77
+ | Bitfinex | | | | ✓\* | | ✓ |
78
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
79
+ | Bitmex | | | | | | ✓ |
80
+ +------------------+------------+-------------+-----------------+----------+-----------+----------------+
81
+
82
+ \* Bitfinex WS OHLCV is aggregated from the trades stream via ``get_ohlc_bitfinex``.
77
83
 
78
84
  Presentation
79
85
  ============
@@ -9,8 +9,8 @@
9
9
  """ Module to download continuously data.
10
10
 
11
11
  Module to download continuously data (orderbook, trades, etc.) and update
12
- automatically the database. *Currently only supports Bitfinex and Bitmex
13
- exchanges.*
12
+ automatically the database. Supports Binance, Bitfinex, Bitmex, Bybit,
13
+ Kraken, and OKX exchanges via WebSocket.
14
14
 
15
15
  .. currentmodule:: dccd.continuous_dl
16
16
 
@@ -18,8 +18,12 @@ exchanges.*
18
18
  :maxdepth: 1
19
19
  :caption: Contents:
20
20
 
21
+ continuous_dl.binance
21
22
  continuous_dl.bitfinex
22
23
  continuous_dl.bitmex
24
+ continuous_dl.bybit
25
+ continuous_dl.kraken
26
+ continuous_dl.okx
23
27
 
24
28
  """
25
29
 
@@ -28,12 +32,18 @@ exchanges.*
28
32
  # Third party packages
29
33
 
30
34
  # Local packages
31
- from . import bitfinex, bitmex, bybit, exchange
35
+ from . import binance, bitfinex, bitmex, bybit, exchange, kraken, okx
36
+ from .binance import *
32
37
  from .bitfinex import *
33
38
  from .bitmex import *
34
39
  from .bybit import *
40
+ from .kraken import *
41
+ from .okx import *
35
42
 
36
43
  __all__ = ['exchange']
44
+ __all__ += binance.__all__
37
45
  __all__ += bitfinex.__all__
38
46
  __all__ += bitmex.__all__
39
47
  __all__ += bybit.__all__
48
+ __all__ += kraken.__all__
49
+ __all__ += okx.__all__
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/env python3
2
+ # coding: utf-8
3
+
4
+ """ Objects and functions to download data from Binance exchange (WebSocket).
5
+
6
+ .. currentmodule:: dccd.continuous_dl.binance
7
+
8
+ High level API
9
+ --------------
10
+
11
+ .. autofunction:: get_data_binance
12
+ .. autofunction:: get_orderbook_binance
13
+ .. autofunction:: get_trades_binance
14
+
15
+ Low level API
16
+ -------------
17
+
18
+ .. autoclass:: dccd.continuous_dl.binance.DownloadBinanceData
19
+ :members: set_process_data, set_saver
20
+ :special-members: __call__
21
+ :show-inheritance:
22
+
23
+ """
24
+
25
+ # Built-in packages
26
+ import logging
27
+ import time
28
+
29
+ # Third party packages
30
+ # Local packages
31
+ from dccd.continuous_dl.exchange import ContinuousDownloader
32
+ from dccd.process_data import set_marketdepth, set_orders, set_trades
33
+ from dccd.tools.io import IODataBase
34
+
35
+ __all__ = [
36
+ 'DownloadBinanceData', 'get_data_binance', 'get_orderbook_binance',
37
+ 'get_trades_binance',
38
+ ]
39
+
40
+ _BINANCE_WS_URL = 'wss://stream.binance.com:9443/stream?streams={sym}@trade/{sym}@depth50@100ms'
41
+
42
+
43
+ def _parser_trades(data: dict) -> list[dict]:
44
+ """ Parse a trade message from Binance combined stream.
45
+
46
+ Parameters
47
+ ----------
48
+ data : dict
49
+ The ``data`` field of a combined-stream trade message.
50
+
51
+ Returns
52
+ -------
53
+ list of dict
54
+ Each dict has keys: ``tid``, ``timestamp``, ``price``, ``amount``,
55
+ ``type`` ('buy' or 'sell').
56
+
57
+ """
58
+ return [{
59
+ 'tid': data['t'],
60
+ 'timestamp': int(data['T']) / 1000,
61
+ 'price': float(data['p']),
62
+ 'amount': float(data['q']),
63
+ 'type': 'sell' if data['m'] else 'buy',
64
+ }]
65
+
66
+
67
+ def _parser_book(data: dict) -> dict:
68
+ """ Parse a depth message from Binance combined stream.
69
+
70
+ Parameters
71
+ ----------
72
+ data : dict
73
+ The ``data`` field of a combined-stream depth message.
74
+
75
+ Returns
76
+ -------
77
+ dict
78
+ Price levels as strings; bids positive, asks prefixed with ``'-'``
79
+ and negative. Zero quantity means the level was removed.
80
+
81
+ """
82
+ book: dict[str, float] = {}
83
+ for bid in data.get('b', []):
84
+ book[bid[0]] = float(bid[1])
85
+ for ask in data.get('a', []):
86
+ book['-' + ask[0]] = -float(ask[1])
87
+ return book
88
+
89
+
90
+ class DownloadBinanceData(ContinuousDownloader):
91
+ """ Download data continuously from Binance via combined WebSocket streams.
92
+
93
+ Parameters
94
+ ----------
95
+ pair : str
96
+ Trading pair symbol in Binance format (e.g. 'BTCUSDT').
97
+ time_step : int, optional
98
+ Seconds between data snapshots, default is 60.
99
+ until : int, optional
100
+ Seconds to run or stop timestamp, default is 3600.
101
+
102
+ Attributes
103
+ ----------
104
+ host : str
105
+ WebSocket URL (combined stream endpoint).
106
+ is_connect : bool
107
+ True if connected.
108
+ ts : int
109
+ Snapshot interval in seconds.
110
+ until : int
111
+ Stop timestamp.
112
+
113
+ Methods
114
+ -------
115
+ set_process_data
116
+ set_saver
117
+ __call__
118
+
119
+ """
120
+
121
+ def __init__(self, pair: str = 'BTCUSDT', time_step: int = 60,
122
+ until: int | None = 3600) -> None:
123
+ """ Initialize object. """
124
+ if until is None:
125
+ until = 0
126
+ elif until > time.time():
127
+ until -= int(time.time())
128
+
129
+ self.pair = pair
130
+ url = _BINANCE_WS_URL.format(sym=pair.lower())
131
+ ContinuousDownloader.__init__(self, url, time_step=time_step, STOP=until)
132
+ self._parser_data = {
133
+ 'trades': self.parser_trades,
134
+ 'book': self.parser_book,
135
+ }
136
+ self.logger = logging.getLogger(__name__)
137
+ self.d: dict[str, float] = {}
138
+
139
+ async def _subscribe(self, **kwargs: object) -> None:
140
+ """ Wait for connection; Binance streams are declared in the URL. """
141
+ await self.wait_that('ws')
142
+ self.is_connect = True
143
+
144
+ async def on_message(self, msg: dict) -> None:
145
+ """ Dispatch incoming combined-stream WebSocket messages.
146
+
147
+ Parameters
148
+ ----------
149
+ msg : dict
150
+ Combined-stream envelope with ``stream`` and ``data`` keys.
151
+
152
+ """
153
+ stream = msg.get('stream', '')
154
+ if '@trade' in stream:
155
+ self.parser_trades(msg['data'])
156
+ elif '@depth' in stream:
157
+ self.parser_book(msg['data'])
158
+
159
+ def parser_trades(self, data: dict) -> None:
160
+ """ Parse and store a trade message.
161
+
162
+ Parameters
163
+ ----------
164
+ data : dict
165
+ The ``data`` field from the combined-stream trade envelope.
166
+
167
+ """
168
+ for trade in _parser_trades(data):
169
+ self._raw_parser(trade)
170
+
171
+ def parser_book(self, data: dict) -> None:
172
+ """ Parse and update the order book from a depth message.
173
+
174
+ Parameters
175
+ ----------
176
+ data : dict
177
+ The ``data`` field from the combined-stream depth envelope.
178
+
179
+ """
180
+ updates = _parser_book(data)
181
+ for price, qty in updates.items():
182
+ if qty == 0:
183
+ self.d.pop(price, None)
184
+ else:
185
+ self.d[price] = qty
186
+ self._data[self.t] = dict(self.d)
187
+
188
+ def _raw_parser(self, data: object) -> None:
189
+ if self.t not in self._data:
190
+ self._data[self.t] = []
191
+ self._data[self.t].append(data) # type: ignore[union-attr]
192
+
193
+
194
+ def get_trades_binance(path: str, pair: str = 'BTCUSDT', time_step: int = 60,
195
+ until: int = 3600, form: str = 'csv') -> None:
196
+ """ Download trades data from Binance via WebSocket.
197
+
198
+ Parameters
199
+ ----------
200
+ path : str
201
+ Path to save data.
202
+ pair : str, optional
203
+ Trading pair in Binance format (e.g. 'BTCUSDT'), default is 'BTCUSDT'.
204
+ time_step : int, optional
205
+ Seconds between snapshots, default is 60.
206
+ until : int, optional
207
+ Duration in seconds or stop timestamp, default is 3600.
208
+ form : str, optional
209
+ Save format ('csv', 'parquet', etc.), default is 'csv'.
210
+
211
+ """
212
+ downloader = DownloadBinanceData(pair=pair, time_step=time_step, until=until)
213
+ downloader.set_process_data(set_trades)
214
+ downloader.set_saver(IODataBase(path, method=form))
215
+ downloader(pair=pair)
216
+
217
+
218
+ def get_orderbook_binance(path: str, pair: str = 'BTCUSDT', time_step: int = 60,
219
+ until: int = 3600, form: str = 'csv') -> None:
220
+ """ Download order book data from Binance via WebSocket.
221
+
222
+ Parameters
223
+ ----------
224
+ path : str
225
+ Path to save data.
226
+ pair : str, optional
227
+ Trading pair in Binance format (e.g. 'BTCUSDT'), default is 'BTCUSDT'.
228
+ time_step : int, optional
229
+ Seconds between snapshots, default is 60.
230
+ until : int, optional
231
+ Duration in seconds or stop timestamp, default is 3600.
232
+ form : str, optional
233
+ Save format ('csv', 'parquet', etc.), default is 'csv'.
234
+
235
+ """
236
+ downloader = DownloadBinanceData(pair=pair, time_step=time_step, until=until)
237
+ downloader.set_process_data(set_marketdepth)
238
+ downloader.set_saver(IODataBase(path, method=form))
239
+ downloader(pair=pair)
240
+
241
+
242
+ def get_data_binance(path: str, pair: str = 'BTCUSDT', time_step: int = 60,
243
+ until: int = 3600, form: str = 'csv') -> None:
244
+ """ Download order book and trades data from Binance via WebSocket.
245
+
246
+ Parameters
247
+ ----------
248
+ path : str
249
+ Path to save data.
250
+ pair : str, optional
251
+ Trading pair in Binance format (e.g. 'BTCUSDT'), default is 'BTCUSDT'.
252
+ time_step : int, optional
253
+ Seconds between snapshots, default is 60.
254
+ until : int, optional
255
+ Duration in seconds or stop timestamp, default is 3600.
256
+ form : str, optional
257
+ Save format ('csv', 'parquet', etc.), default is 'csv'.
258
+
259
+ """
260
+ downloader = DownloadBinanceData(pair=pair, time_step=time_step, until=until)
261
+ downloader.set_process_data(set_orders)
262
+ downloader.set_saver(IODataBase(path, method=form))
263
+ downloader(pair=pair)