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.
- {dccd-2.0.2 → dccd-2.1.0}/CHANGELOG.md +39 -0
- {dccd-2.0.2 → dccd-2.1.0}/PKG-INFO +26 -19
- {dccd-2.0.2 → dccd-2.1.0}/README.rst +24 -18
- {dccd-2.0.2 → dccd-2.1.0}/dccd/continuous_dl/__init__.py +13 -3
- dccd-2.1.0/dccd/continuous_dl/binance.py +263 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/continuous_dl/bitfinex.py +66 -133
- {dccd-2.0.2 → dccd-2.1.0}/dccd/continuous_dl/bitmex.py +120 -146
- {dccd-2.0.2 → dccd-2.1.0}/dccd/continuous_dl/bybit.py +31 -2
- {dccd-2.0.2 → dccd-2.1.0}/dccd/continuous_dl/exchange.py +20 -51
- dccd-2.1.0/dccd/continuous_dl/kraken.py +336 -0
- dccd-2.1.0/dccd/continuous_dl/okx.py +330 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/binance.py +5 -2
- {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/bybit.py +5 -3
- {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/coinbase.py +5 -4
- {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/exchange.py +112 -30
- {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/kraken.py +28 -8
- {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/okx.py +5 -3
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/conftest.py +9 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_binance.py +19 -0
- dccd-2.1.0/dccd/tests/test_binance_ws.py +120 -0
- dccd-2.1.0/dccd/tests/test_bitfinex.py +83 -0
- dccd-2.1.0/dccd/tests/test_bitmex.py +108 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_bybit.py +15 -0
- dccd-2.1.0/dccd/tests/test_bybit_ws.py +113 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_coinbase.py +15 -0
- dccd-2.1.0/dccd/tests/test_date_time.py +127 -0
- dccd-2.1.0/dccd/tests/test_histo_dl.py +60 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_kraken.py +15 -0
- dccd-2.1.0/dccd/tests/test_kraken_ws.py +162 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_okx.py +15 -0
- dccd-2.1.0/dccd/tests/test_okx_ws.py +151 -0
- dccd-2.1.0/dccd/tests/test_websocket.py +69 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tools/__init__.py +0 -2
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tools/date_time.py +59 -30
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tools/io.py +14 -11
- {dccd-2.0.2 → dccd-2.1.0}/dccd.egg-info/PKG-INFO +26 -19
- {dccd-2.0.2 → dccd-2.1.0}/dccd.egg-info/SOURCES.txt +11 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd.egg-info/requires.txt +1 -0
- {dccd-2.0.2 → dccd-2.1.0}/pyproject.toml +6 -8
- dccd-2.0.2/dccd/tests/test_date_time.py +0 -46
- {dccd-2.0.2 → dccd-2.1.0}/CONTRIBUTING.md +0 -0
- {dccd-2.0.2 → dccd-2.1.0}/LICENSE.txt +0 -0
- {dccd-2.0.2 → dccd-2.1.0}/MANIFEST.in +0 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/__init__.py +0 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/histo_dl/__init__.py +0 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/models.py +0 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/process_data.py +0 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/__init__.py +0 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_io.py +0 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_models.py +0 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tests/test_process_data.py +0 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd/tools/websocket.py +0 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd.egg-info/dependency_links.txt +0 -0
- {dccd-2.0.2 → dccd-2.1.0}/dccd.egg-info/top_level.txt +0 -0
- {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
|
|
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://
|
|
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 |
|
|
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://
|
|
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 |
|
|
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.
|
|
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)
|