cryptofeed 2.3.2__tar.gz → 2.4.1__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.
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/AUTHORS.md +5 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/CHANGES.md +22 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/INSTALL.md +5 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/LICENSE +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/PKG-INFO +73 -13
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/README.md +3 -3
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/__init__.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/_util.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/aggregate.py +4 -4
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/arctic.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/backend.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/gcppubsub.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/http.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/influxdb.py +2 -2
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/kafka.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/mongo.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/postgres.py +1 -1
- cryptofeed-2.4.1/cryptofeed/backends/quasardb.py +175 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/quest.py +8 -5
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/rabbitmq.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/redis.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/socket.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/zmq.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/callback.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/config.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/connection.py +14 -8
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/connection_handler.py +1 -21
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/defines.py +2 -2
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exceptions.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchange.py +4 -4
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/__init__.py +4 -4
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/ascendex.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bequant.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/binance.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/binance_delivery.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/binance_futures.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/binance_tr.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/binance_us.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bitdotcom.py +4 -5
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bitfinex.py +2 -2
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bitflyer.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bitget.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bithumb.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bitmex.py +18 -10
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bitstamp.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/blockchain.py +1 -1
- cryptofeed-2.4.1/cryptofeed/exchanges/bybit.py +618 -0
- cryptofeed-2.4.1/cryptofeed/exchanges/coinbase.py +192 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/cryptodotcom.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/delta.py +2 -2
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/deribit.py +6 -2
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/dydx.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/fmfw.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/gateio.py +1 -1
- cryptofeed-2.4.1/cryptofeed/exchanges/gateio_futures.py +361 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/gemini.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/hitbtc.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/huobi.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/huobi_dm.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/huobi_swap.py +4 -4
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/independent_reserve.py +6 -6
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/kraken.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/kraken_futures.py +4 -2
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/kucoin.py +2 -2
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/binance_rest.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/bitfinex_rest.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/bitmex_rest.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/bitstamp_rest.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/coinbase_rest.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/deribit_rest.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/dydx_rest.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/gemini_rest.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/kraken_rest.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/okx_rest.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/upbit_rest.py +1 -1
- cryptofeed-2.4.1/cryptofeed/exchanges/okcoin.py +45 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/okx.py +4 -4
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/phemex.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/poloniex.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/probit.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/upbit.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/feed.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/feedhandler.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/log.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/nbbo.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/raw_data_collection.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/symbols.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/types.c +21224 -9672
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/types.pyx +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/util/book.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/util/perf.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/util/time.py +1 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed.egg-info/PKG-INFO +73 -13
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed.egg-info/SOURCES.txt +2 -1
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed.egg-info/requires.txt +6 -2
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/setup.py +9 -7
- cryptofeed-2.3.2/cryptofeed/exchanges/bittrex.py +0 -413
- cryptofeed-2.3.2/cryptofeed/exchanges/bybit.py +0 -520
- cryptofeed-2.3.2/cryptofeed/exchanges/coinbase.py +0 -391
- cryptofeed-2.3.2/cryptofeed/exchanges/okcoin.py +0 -163
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/MANIFEST.in +0 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/__init__.py +0 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/ascendex_futures.py +0 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/exx.py +0 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/__init__.py +0 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/util/__init__.py +0 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/util/split.py +0 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed.egg-info/dependency_links.txt +0 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed.egg-info/top_level.txt +0 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/pyproject.toml +0 -0
- {cryptofeed-2.3.2 → cryptofeed-2.4.1}/setup.cfg +0 -0
|
@@ -14,3 +14,8 @@ Cryptofeed was originally created by Bryant Moscon, but many others have contrib
|
|
|
14
14
|
* [O. Janche](https://github.com/toyan) - <toyan@yandex.ru>
|
|
15
15
|
* [Bastien Enjalbert](https://github.com/bastienjalbert) - <bastienjalbert@gmail.com>
|
|
16
16
|
* [Jonggyun Kim](https://github.com/gyunt) - <truth0233@gmail.com>
|
|
17
|
+
* [QuasarDB](https://quasar.ai/)
|
|
18
|
+
* [Thomas Bouamoud](https://github.com/thomasbs17) - <thomasbs17@yahoo.fr>
|
|
19
|
+
* [Carlo Eugster](https://github.com/carloe) - <carlo@relaun.ch>
|
|
20
|
+
* [Marten Schlüter](https://github.com/maschlr)
|
|
21
|
+
* [Handel Scholze](https://github.com/HandelSM) - <handel.scholze@gmail.com>
|
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
## Changelog
|
|
2
2
|
|
|
3
|
+
### 2.4.1 (2025-02-08)
|
|
4
|
+
* Update: Added `is_data_json` to `write()` in `HTTPSync` from `connection.py` to support JSON payloads (#1071)
|
|
5
|
+
* Bugfix: Handle empty nextFundingRate in OKX
|
|
6
|
+
* Bugfix: Handle null next_funding_time and estimated_rate in HuobiSwap funding
|
|
7
|
+
* Update: transitioned from Coinbase Pro (retired) to Coinbase Advanced Trade
|
|
8
|
+
* Feature: Bybit spot support
|
|
9
|
+
* Update: Bybit migrate to API V5 for public streams
|
|
10
|
+
* Bugfix: Handle None ids for Kraken trades in QuestDB
|
|
11
|
+
* Bugfix: Handle OrderChanged event in IndependentReserve
|
|
12
|
+
* Bugfix: Remove deprecated `USD` currency from bit.com
|
|
13
|
+
* Bugfix: Make `entry` key optional when retrieving symbols for BitMex
|
|
14
|
+
* Update: Changes to work with latest version of websockets
|
|
15
|
+
|
|
16
|
+
### 2.4.0 (2024-01-07)
|
|
17
|
+
* Update: Fix tests
|
|
18
|
+
* Update: Okcoin moved to v5 API used by OKX
|
|
19
|
+
* Bugfix: InfluxDB none type conversions
|
|
20
|
+
* New Exchange: GateIO Futures
|
|
21
|
+
* Bugfix: Fix instrument types in symbol parsing on Bitmex
|
|
22
|
+
* Bugfix: fix crash issue when init symbol data on Kraken Futures
|
|
23
|
+
* Updates: Remove closed exchanges, clean up feeds (update APIs, adjust symbol parsing, etc)
|
|
24
|
+
|
|
3
25
|
### 2.3.2 (2023-05-27)
|
|
4
26
|
* Bugfix: Fix Socket backend
|
|
5
27
|
* Bugfix: Fix AUCTION symbol parsing on Coinbase
|
|
@@ -47,6 +47,11 @@ for the exhaustive list of these *extra* dependencies.
|
|
|
47
47
|
|
|
48
48
|
pip install --user --upgrade cryptofeed[postgres]
|
|
49
49
|
|
|
50
|
+
* QuasarDB backend
|
|
51
|
+
To install Cryptofeed along with [QuasarDB](https://quasar.ai/) in one bundle:
|
|
52
|
+
|
|
53
|
+
pip install --user --upgrade cryptofeed[quasardb]
|
|
54
|
+
|
|
50
55
|
* RabbitMQ backend
|
|
51
56
|
|
|
52
57
|
pip install --user --upgrade cryptofeed[rabbit]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright (C) 2017-
|
|
1
|
+
Copyright (C) 2017-2025 Bryant Moscon - bmoscon@gmail.com
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
4
|
of this software and associated documentation files (the "Software"), to
|
|
@@ -1,38 +1,72 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cryptofeed
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.1
|
|
4
4
|
Summary: Cryptocurrency Exchange Websocket Data Feed Handler
|
|
5
5
|
Home-page: https://github.com/bmoscon/cryptofeed
|
|
6
6
|
Author: Bryant Moscon
|
|
7
7
|
Author-email: bmoscon@gmail.com
|
|
8
8
|
License: XFree86
|
|
9
|
-
Keywords: cryptocurrency,bitcoin,btc,feed handler,market feed,market data,crypto assets,Trades,Tickers,BBO,Funding,Open Interest,Liquidation,Order book,Bid,Ask,fmfw.io,Bitfinex,bitFlyer,AscendEX,Bitstamp,
|
|
10
|
-
Platform: UNKNOWN
|
|
9
|
+
Keywords: cryptocurrency,bitcoin,btc,feed handler,market feed,market data,crypto assets,Trades,Tickers,BBO,Funding,Open Interest,Liquidation,Order book,Bid,Ask,fmfw.io,Bitfinex,bitFlyer,AscendEX,Bitstamp,Blockchain.com,Bybit,Binance,Binance Delivery,Binance Futures,Binance US,BitMEX,Coinbase,Deribit,EXX,Gate.io,Gemini,HitBTC,Huobi,Huobi DM,Huobi Swap,Kraken,Kraken Futures,OKCoin,OKX,Poloniex,ProBit,Upbit
|
|
11
10
|
Classifier: Intended Audience :: Developers
|
|
12
11
|
Classifier: Development Status :: 4 - Beta
|
|
13
12
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
15
13
|
Classifier: Programming Language :: Python :: 3.9
|
|
16
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
17
|
Classifier: Framework :: AsyncIO
|
|
18
|
-
Requires-Python: >=3.
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
License-File: AUTHORS.md
|
|
22
|
+
Requires-Dist: requests>=2.18.4
|
|
23
|
+
Requires-Dist: websockets>=14.1
|
|
24
|
+
Requires-Dist: pyyaml
|
|
25
|
+
Requires-Dist: aiohttp>=3.11.6
|
|
26
|
+
Requires-Dist: aiofile>=2.0.0
|
|
27
|
+
Requires-Dist: yapic.json>=1.6.3
|
|
28
|
+
Requires-Dist: uvloop; platform_system != "Windows"
|
|
29
|
+
Requires-Dist: order_book>=0.6.0
|
|
30
|
+
Requires-Dist: aiodns>=1.1
|
|
20
31
|
Provides-Extra: arctic
|
|
21
|
-
|
|
32
|
+
Requires-Dist: arctic; extra == "arctic"
|
|
33
|
+
Requires-Dist: pandas; extra == "arctic"
|
|
34
|
+
Provides-Extra: gcp-pubsub
|
|
35
|
+
Requires-Dist: google_cloud_pubsub>=2.4.1; extra == "gcp-pubsub"
|
|
36
|
+
Requires-Dist: gcloud_aio_pubsub; extra == "gcp-pubsub"
|
|
22
37
|
Provides-Extra: kafka
|
|
38
|
+
Requires-Dist: aiokafka>=0.7.0; extra == "kafka"
|
|
23
39
|
Provides-Extra: mongo
|
|
40
|
+
Requires-Dist: motor; extra == "mongo"
|
|
24
41
|
Provides-Extra: postgres
|
|
42
|
+
Requires-Dist: asyncpg; extra == "postgres"
|
|
43
|
+
Provides-Extra: quasardb
|
|
44
|
+
Requires-Dist: quasardb; extra == "quasardb"
|
|
45
|
+
Requires-Dist: numpy; extra == "quasardb"
|
|
25
46
|
Provides-Extra: rabbit
|
|
47
|
+
Requires-Dist: aio_pika; extra == "rabbit"
|
|
48
|
+
Requires-Dist: pika; extra == "rabbit"
|
|
26
49
|
Provides-Extra: redis
|
|
50
|
+
Requires-Dist: hiredis; extra == "redis"
|
|
51
|
+
Requires-Dist: redis>=4.5.1; extra == "redis"
|
|
27
52
|
Provides-Extra: zmq
|
|
53
|
+
Requires-Dist: pyzmq; extra == "zmq"
|
|
28
54
|
Provides-Extra: all
|
|
29
|
-
|
|
30
|
-
|
|
55
|
+
Requires-Dist: arctic; extra == "all"
|
|
56
|
+
Requires-Dist: google_cloud_pubsub>=2.4.1; extra == "all"
|
|
57
|
+
Requires-Dist: gcloud_aio_pubsub; extra == "all"
|
|
58
|
+
Requires-Dist: aiokafka>=0.7.0; extra == "all"
|
|
59
|
+
Requires-Dist: motor; extra == "all"
|
|
60
|
+
Requires-Dist: asyncpg; extra == "all"
|
|
61
|
+
Requires-Dist: aio_pika; extra == "all"
|
|
62
|
+
Requires-Dist: pika; extra == "all"
|
|
63
|
+
Requires-Dist: hiredis; extra == "all"
|
|
64
|
+
Requires-Dist: redis>=4.5.1; extra == "all"
|
|
65
|
+
Requires-Dist: pyzmq; extra == "all"
|
|
31
66
|
|
|
32
67
|
# Cryptocurrency Exchange Feed Handler
|
|
33
68
|
[](LICENSE)
|
|
34
69
|

|
|
35
|
-
[](https://travis-ci.com/bmoscon/cryptofeed)
|
|
36
70
|
[](https://pypi.python.org/pypi/cryptofeed)
|
|
37
71
|
[](https://www.codacy.com/app/bmoscon/cryptofeed?utm_source=github.com&utm_medium=referral&utm_content=bmoscon/cryptofeed&utm_campaign=Badge_Grade)
|
|
38
72
|
|
|
@@ -46,7 +80,6 @@ Handles multiple cryptocurrency exchange data feeds and returns normalized and s
|
|
|
46
80
|
* [bitFlyer](https://bitflyer.com/)
|
|
47
81
|
* [Bithumb](https://en.bithumb.com/)
|
|
48
82
|
* [Bitstamp](https://www.bitstamp.net/)
|
|
49
|
-
* [Bittrex](https://global.bittrex.com/)
|
|
50
83
|
* [Blockchain.com](https://www.blockchain.com/)
|
|
51
84
|
* [Bybit](https://www.bybit.com/)
|
|
52
85
|
* [Binance](https://www.binance.com/en)
|
|
@@ -64,6 +97,7 @@ Handles multiple cryptocurrency exchange data feeds and returns normalized and s
|
|
|
64
97
|
* [FMFW.io](https://www.fmfw.io/)
|
|
65
98
|
* [EXX](https://www.exx.com/)
|
|
66
99
|
* [Gate.io](https://www.gate.io/)
|
|
100
|
+
* [Gate.io Futures](https://www.gate.io/futures_center)
|
|
67
101
|
* [Gemini](https://gemini.com/)
|
|
68
102
|
* [HitBTC](https://hitbtc.com/)
|
|
69
103
|
* [Huobi](https://www.hbg.com/)
|
|
@@ -172,6 +206,7 @@ Supported Backends:
|
|
|
172
206
|
* Kafka
|
|
173
207
|
* RabbitMQ
|
|
174
208
|
* PostgreSQL
|
|
209
|
+
* [QuasarDB](https://quasar.ai/)
|
|
175
210
|
* GCP Pub/Sub
|
|
176
211
|
* [QuestDB](https://questdb.io/)
|
|
177
212
|
|
|
@@ -207,7 +242,7 @@ Cryptofeed supports some REST interfaces for retrieving real-time and historical
|
|
|
207
242
|
|
|
208
243
|
## Future Work
|
|
209
244
|
|
|
210
|
-
There are a lot of planned features, new exchanges, etc planned! If you'd like to discuss ongoing development, please join the [
|
|
245
|
+
There are a lot of planned features, new exchanges, etc planned! If you'd like to discuss ongoing development, please join the [discord](https://discord.gg/zaBYaGAYfR) or open a thread in the [discussions](https://github.com/bmoscon/cryptofeed/discussions) in GitHub.
|
|
211
246
|
|
|
212
247
|
## Contributing
|
|
213
248
|
|
|
@@ -274,6 +309,11 @@ for the exhaustive list of these *extra* dependencies.
|
|
|
274
309
|
|
|
275
310
|
pip install --user --upgrade cryptofeed[postgres]
|
|
276
311
|
|
|
312
|
+
* QuasarDB backend
|
|
313
|
+
To install Cryptofeed along with [QuasarDB](https://quasar.ai/) in one bundle:
|
|
314
|
+
|
|
315
|
+
pip install --user --upgrade cryptofeed[quasardb]
|
|
316
|
+
|
|
277
317
|
* RabbitMQ backend
|
|
278
318
|
|
|
279
319
|
pip install --user --upgrade cryptofeed[rabbit]
|
|
@@ -298,6 +338,28 @@ Your Pull Requests are also welcome, even for minor changes.
|
|
|
298
338
|
|
|
299
339
|
## Changelog
|
|
300
340
|
|
|
341
|
+
### 2.4.1 (2025-02-08)
|
|
342
|
+
* Update: Added `is_data_json` to `write()` in `HTTPSync` from `connection.py` to support JSON payloads (#1071)
|
|
343
|
+
* Bugfix: Handle empty nextFundingRate in OKX
|
|
344
|
+
* Bugfix: Handle null next_funding_time and estimated_rate in HuobiSwap funding
|
|
345
|
+
* Update: transitioned from Coinbase Pro (retired) to Coinbase Advanced Trade
|
|
346
|
+
* Feature: Bybit spot support
|
|
347
|
+
* Update: Bybit migrate to API V5 for public streams
|
|
348
|
+
* Bugfix: Handle None ids for Kraken trades in QuestDB
|
|
349
|
+
* Bugfix: Handle OrderChanged event in IndependentReserve
|
|
350
|
+
* Bugfix: Remove deprecated `USD` currency from bit.com
|
|
351
|
+
* Bugfix: Make `entry` key optional when retrieving symbols for BitMex
|
|
352
|
+
* Update: Changes to work with latest version of websockets
|
|
353
|
+
|
|
354
|
+
### 2.4.0 (2024-01-07)
|
|
355
|
+
* Update: Fix tests
|
|
356
|
+
* Update: Okcoin moved to v5 API used by OKX
|
|
357
|
+
* Bugfix: InfluxDB none type conversions
|
|
358
|
+
* New Exchange: GateIO Futures
|
|
359
|
+
* Bugfix: Fix instrument types in symbol parsing on Bitmex
|
|
360
|
+
* Bugfix: fix crash issue when init symbol data on Kraken Futures
|
|
361
|
+
* Updates: Remove closed exchanges, clean up feeds (update APIs, adjust symbol parsing, etc)
|
|
362
|
+
|
|
301
363
|
### 2.3.2 (2023-05-27)
|
|
302
364
|
* Bugfix: Fix Socket backend
|
|
303
365
|
* Bugfix: Fix AUCTION symbol parsing on Coinbase
|
|
@@ -1078,5 +1140,3 @@ Your Pull Requests are also welcome, even for minor changes.
|
|
|
1078
1140
|
### 0.5.0 (2018-01-02)
|
|
1079
1141
|
* Initial release: GDAX, Poloniex, Bitfinex Support
|
|
1080
1142
|
* Feature: NBBO support
|
|
1081
|
-
|
|
1082
|
-
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Cryptocurrency Exchange Feed Handler
|
|
2
2
|
[](LICENSE)
|
|
3
3
|

|
|
4
|
-
[](https://travis-ci.com/bmoscon/cryptofeed)
|
|
5
4
|
[](https://pypi.python.org/pypi/cryptofeed)
|
|
6
5
|
[](https://www.codacy.com/app/bmoscon/cryptofeed?utm_source=github.com&utm_medium=referral&utm_content=bmoscon/cryptofeed&utm_campaign=Badge_Grade)
|
|
7
6
|
|
|
@@ -15,7 +14,6 @@ Handles multiple cryptocurrency exchange data feeds and returns normalized and s
|
|
|
15
14
|
* [bitFlyer](https://bitflyer.com/)
|
|
16
15
|
* [Bithumb](https://en.bithumb.com/)
|
|
17
16
|
* [Bitstamp](https://www.bitstamp.net/)
|
|
18
|
-
* [Bittrex](https://global.bittrex.com/)
|
|
19
17
|
* [Blockchain.com](https://www.blockchain.com/)
|
|
20
18
|
* [Bybit](https://www.bybit.com/)
|
|
21
19
|
* [Binance](https://www.binance.com/en)
|
|
@@ -33,6 +31,7 @@ Handles multiple cryptocurrency exchange data feeds and returns normalized and s
|
|
|
33
31
|
* [FMFW.io](https://www.fmfw.io/)
|
|
34
32
|
* [EXX](https://www.exx.com/)
|
|
35
33
|
* [Gate.io](https://www.gate.io/)
|
|
34
|
+
* [Gate.io Futures](https://www.gate.io/futures_center)
|
|
36
35
|
* [Gemini](https://gemini.com/)
|
|
37
36
|
* [HitBTC](https://hitbtc.com/)
|
|
38
37
|
* [Huobi](https://www.hbg.com/)
|
|
@@ -141,6 +140,7 @@ Supported Backends:
|
|
|
141
140
|
* Kafka
|
|
142
141
|
* RabbitMQ
|
|
143
142
|
* PostgreSQL
|
|
143
|
+
* [QuasarDB](https://quasar.ai/)
|
|
144
144
|
* GCP Pub/Sub
|
|
145
145
|
* [QuestDB](https://questdb.io/)
|
|
146
146
|
|
|
@@ -176,7 +176,7 @@ Cryptofeed supports some REST interfaces for retrieving real-time and historical
|
|
|
176
176
|
|
|
177
177
|
## Future Work
|
|
178
178
|
|
|
179
|
-
There are a lot of planned features, new exchanges, etc planned! If you'd like to discuss ongoing development, please join the [
|
|
179
|
+
There are a lot of planned features, new exchanges, etc planned! If you'd like to discuss ongoing development, please join the [discord](https://discord.gg/zaBYaGAYfR) or open a thread in the [discussions](https://github.com/bmoscon/cryptofeed/discussions) in GitHub.
|
|
180
180
|
|
|
181
181
|
## Contributing
|
|
182
182
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'''
|
|
2
|
-
Copyright (C) 2017-
|
|
2
|
+
Copyright (C) 2017-2025 Bryant Moscon - bmoscon@gmail.com
|
|
3
3
|
|
|
4
4
|
Please see the LICENSE file for the terms and conditions
|
|
5
5
|
associated with this software.
|
|
@@ -13,9 +13,9 @@ import numpy as np
|
|
|
13
13
|
class AggregateCallback:
|
|
14
14
|
def __init__(self, handler):
|
|
15
15
|
self.handler = handler
|
|
16
|
-
if hasattr(self.handler,
|
|
17
|
-
setattr(self,
|
|
18
|
-
setattr(self,
|
|
16
|
+
if hasattr(self.handler, "__class__") and hasattr(self.handler, "start") and hasattr(self.handler, "stop"):
|
|
17
|
+
setattr(self, "start", self.handler.start)
|
|
18
|
+
setattr(self, "stop", self.handler.stop)
|
|
19
19
|
self.__name__ = self.handler.__class__
|
|
20
20
|
|
|
21
21
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'''
|
|
2
|
-
Copyright (C) 2017-
|
|
2
|
+
Copyright (C) 2017-2025 Bryant Moscon - bmoscon@gmail.com
|
|
3
3
|
|
|
4
4
|
Please see the LICENSE file for the terms and conditions
|
|
5
5
|
associated with this software.
|
|
@@ -68,7 +68,7 @@ class InfluxCallback(HTTPCallback):
|
|
|
68
68
|
for key, value in data.items():
|
|
69
69
|
if key in {'timestamp', 'exchange', 'symbol', 'receipt_timestamp'}:
|
|
70
70
|
continue
|
|
71
|
-
if isinstance(value, str):
|
|
71
|
+
if isinstance(value, str) or value is None:
|
|
72
72
|
ret.append(f'{key}="{value}"')
|
|
73
73
|
else:
|
|
74
74
|
ret.append(f'{key}={value}')
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
from datetime import datetime, timedelta
|
|
2
|
+
import quasardb.pool as pool
|
|
3
|
+
import quasardb.numpy as qdbnp
|
|
4
|
+
import numpy as np
|
|
5
|
+
from cryptofeed.backends.backend import BackendCallback
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class QuasarCallback(BackendCallback):
|
|
9
|
+
def __init__(self, uri="qdb://127.0.0.1:2836", username: str = "", private_key: str = "", public_key: str = "", none_to=None, shard_size: timedelta = timedelta(minutes=15)):
|
|
10
|
+
self.numeric_type = float
|
|
11
|
+
self.table = ""
|
|
12
|
+
self.running = True
|
|
13
|
+
self.none_to = none_to
|
|
14
|
+
self.shard_size = self._get_str_timedelta(shard_size)
|
|
15
|
+
|
|
16
|
+
pool.initialize(uri=uri, user_name=username, user_private_key=private_key, cluster_public_key=public_key)
|
|
17
|
+
|
|
18
|
+
def _get_str_timedelta(self, delta: timedelta):
|
|
19
|
+
# calculate the number of hours, minutes, and remaining seconds from timedelta, return it in correct format for query
|
|
20
|
+
hours, remainder = divmod(delta.total_seconds(), 3600)
|
|
21
|
+
minutes, seconds = divmod(remainder, 60)
|
|
22
|
+
return f"{int(hours)}hour {int(minutes)}min {int(seconds)}s"
|
|
23
|
+
|
|
24
|
+
def format(self, data: dict):
|
|
25
|
+
data['timestamp'] = np.datetime64(datetime.utcfromtimestamp(data['timestamp']), 'ns')
|
|
26
|
+
data['receipt_timestamp'] = np.datetime64(datetime.utcfromtimestamp(data['receipt_timestamp']), 'ns')
|
|
27
|
+
data['timestamp'], data['receipt_timestamp'] = data['receipt_timestamp'], data['timestamp']
|
|
28
|
+
index = data['timestamp']
|
|
29
|
+
data.pop('timestamp')
|
|
30
|
+
return index, data
|
|
31
|
+
|
|
32
|
+
def _set_table_name(self, data: dict):
|
|
33
|
+
# setting table name
|
|
34
|
+
# {channel}/{exchange}/{symbol_1-symbol_2}
|
|
35
|
+
# eg. ticker/coinbase/btc-usd
|
|
36
|
+
self.table = f"{self.table_prefix.lower()}/{data['exchange'].lower()}/{data['symbol'].lower()}"
|
|
37
|
+
|
|
38
|
+
def _create_table(self, conn):
|
|
39
|
+
if not conn.table(self.table).exists():
|
|
40
|
+
conn.query(self.query)
|
|
41
|
+
|
|
42
|
+
def _insert_format(self, date: np.datetime64, data: dict):
|
|
43
|
+
# converts values to np.array
|
|
44
|
+
for key, value in data.items():
|
|
45
|
+
data[key] = np.array([value])
|
|
46
|
+
return np.array([date]), data
|
|
47
|
+
|
|
48
|
+
async def write(self, data: dict):
|
|
49
|
+
self._set_table_name(data)
|
|
50
|
+
self._create_query()
|
|
51
|
+
index, data = self.format(data)
|
|
52
|
+
idx, np_array = self._insert_format(index, data)
|
|
53
|
+
# write to table, if table doesnt exist it will be created with specified shard_size value
|
|
54
|
+
with pool.instance().connect() as conn:
|
|
55
|
+
self._create_table(conn)
|
|
56
|
+
qdbnp.write_arrays(np_array, conn, conn.table(self.table), index=idx, fast=True, _async=True)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class TickerQuasar(QuasarCallback):
|
|
60
|
+
table_prefix = "ticker"
|
|
61
|
+
|
|
62
|
+
def _create_query(self):
|
|
63
|
+
self.query = f'CREATE TABLE "{self.table}" (exchange SYMBOL(exchange), symbol SYMBOL(symbol), bid DOUBLE, ask DOUBLE, receipt_timestamp TIMESTAMP) SHARD_SIZE = {self.shard_size}'
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class TradeQuasar(QuasarCallback):
|
|
67
|
+
table_prefix = "trades"
|
|
68
|
+
|
|
69
|
+
def _create_query(self):
|
|
70
|
+
self.query = f'CREATE TABLE "{self.table}" (exchange SYMBOL(exchange), symbol SYMBOL(symbol), side SYMBOL(side), amount DOUBLE, price DOUBLE, id STRING, type SYMBOL(type), receipt_timestamp TIMESTAMP) SHARD_SIZE = {self.shard_size}'
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class CandlesQuasar(QuasarCallback):
|
|
74
|
+
table_prefix = "candles"
|
|
75
|
+
|
|
76
|
+
def format(self, data: dict):
|
|
77
|
+
index, data = super().format(data)
|
|
78
|
+
data['start'] = datetime.utcfromtimestamp(data['start'])
|
|
79
|
+
data['stop'] = datetime.utcfromtimestamp(data['stop'])
|
|
80
|
+
data['closed'] = int(data['closed'])
|
|
81
|
+
return index, data
|
|
82
|
+
|
|
83
|
+
def _create_query(self):
|
|
84
|
+
self.query = f'CREATE TABLE "{self.table}" (exchange SYMBOL(exchange), symbol SYMBOL(symbol), start TIMESTAMP, stop TIMESTAMP, interval STRING, trades STRING, open DOUBLE, close DOUBLE, high DOUBLE, low DOUBLE, volume DOUBLE, closed INT64, receipt_timestamp TIMESTAMP) SHARD_SIZE = {self.shard_size}'
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class FundingQuasar(QuasarCallback):
|
|
88
|
+
table_prefix = "funding"
|
|
89
|
+
|
|
90
|
+
def format(self, data: dict):
|
|
91
|
+
index, data = super().format(data)
|
|
92
|
+
data['next_funding_time'] = datetime.utcfromtimestamp(data['next_funding_time'])
|
|
93
|
+
return index, data
|
|
94
|
+
|
|
95
|
+
def _create_query(self):
|
|
96
|
+
self.query = f'CREATE TABLE "{self.table}" (exchange SYMBOL(exchange), symbol SYMBOL(symbol), mark_price DOUBLE, rate DOUBLE, next_funding_time TIMESTAMP, predicted_rate DOUBLE, receipt_timestamp TIMESTAMP) SHARD_SIZE = {self.shard_size}'
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class BookQuasar(QuasarCallback):
|
|
100
|
+
table_prefix = "book"
|
|
101
|
+
|
|
102
|
+
def format(self, data: dict):
|
|
103
|
+
index, data = super().format(data)
|
|
104
|
+
# store only best bid and best ask
|
|
105
|
+
if not data['book']:
|
|
106
|
+
best_bid = max(data["delta"]["bid"], key=lambda x: x[0])
|
|
107
|
+
best_ask = min(data["delta"]["ask"], key=lambda x: x[0])
|
|
108
|
+
|
|
109
|
+
data['best_bid_price'] = best_bid[0]
|
|
110
|
+
data['best_bid_amount'] = best_bid[1]
|
|
111
|
+
data['best_ask_price'] = best_ask[0]
|
|
112
|
+
data['best_ask_amount'] = best_ask[1]
|
|
113
|
+
data.pop('delta')
|
|
114
|
+
else:
|
|
115
|
+
best_bid = max(data["book"]["bid"].keys())
|
|
116
|
+
best_ask = min(data["book"]["ask"].keys())
|
|
117
|
+
|
|
118
|
+
data['best_bid_price'] = best_bid
|
|
119
|
+
data['best_bid_amount'] = data["book"]["bid"][best_bid]
|
|
120
|
+
data['best_ask_price'] = best_ask
|
|
121
|
+
data['best_ask_amount'] = data["book"]["ask"][best_ask]
|
|
122
|
+
data.pop('book')
|
|
123
|
+
return index, data
|
|
124
|
+
|
|
125
|
+
def _create_query(self):
|
|
126
|
+
self.query = f'CREATE TABLE "{self.table}" (exchange SYMBOL(exchange), symbol SYMBOL(symbol), best_bid_price DOUBLE, best_bid_amount DOUBLE, best_ask_price DOUBLE, best_ask_amount DOUBLE, receipt_timestamp TIMESTAMP) SHARD_SIZE = {self.shard_size}'
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class LiquidationsQuasar(QuasarCallback):
|
|
130
|
+
table_prefix = "liquidations"
|
|
131
|
+
|
|
132
|
+
def _create_query(self):
|
|
133
|
+
self.query = f'CREATE TABLE "{self.table}" (exchange SYMBOL(exchange), symbol SYMBOL(symbol), side SYMBOL(side), quantity DOUBLE, price DOUBLE, id STRING, status SYMBOL(type), receipt_timestamp TIMESTAMP) SHARD_SIZE = {self.shard_size}'
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class OpenInterestQuasar(QuasarCallback):
|
|
137
|
+
table_prefix = "open_interest"
|
|
138
|
+
|
|
139
|
+
def _create_query(self):
|
|
140
|
+
self.query = f'CREATE TABLE "{self.table}" (exchange SYMBOL(exchange), symbol SYMBOL(symbol), open_interest FLOAT, receipt_timestamp TIMESTAMP) SHARD_SIZE = {self.shard_size}'
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class OrderInfoQuasar(QuasarCallback):
|
|
144
|
+
table_prefix = "order_info"
|
|
145
|
+
|
|
146
|
+
def _create_query(self):
|
|
147
|
+
self.query = f'CREATE TABLE "{self.table}" (exchange SYMBOL(exchange), symbol SYMBOL(symbol), id STRING, client_order_id STRING, side SYMBOL(side), status SYMBOL(type), type SYMBOL(type), price DOUBLE, amount DOUBLE, remaining DOUBLE, account STRING, receipt_timestamp TIMESTAMP) SHARD_SIZE = {self.shard_size}'
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class TransactionsQuasar(QuasarCallback):
|
|
151
|
+
table_prefix = "transactions"
|
|
152
|
+
|
|
153
|
+
def _create_query(self):
|
|
154
|
+
self.query = f'CREATE TABLE "{self.table}" (exchange SYMBOL(exchange), currency SYMBOL(currency), type SYMBOL(type), status SYMBOL(type), amount DOUBLE, receipt_timestamp TIMESTAMP) SHARD_SIZE = {self.shard_size}'
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class BalancesQuasar(QuasarCallback):
|
|
158
|
+
table_prefix = "balances"
|
|
159
|
+
|
|
160
|
+
def _create_query(self):
|
|
161
|
+
self.query = f'CREATE TABLE "{self.table}" (exchange SYMBOL(exchange), currency SYMBOL(currency), balance DOUBLE, reserved DOUBLE, receipt_timestamp TIMESTAMP) SHARD_SIZE = {self.shard_size}'
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class FillsQuasar(QuasarCallback):
|
|
165
|
+
table_prefix = "fills"
|
|
166
|
+
|
|
167
|
+
def _create_query(self):
|
|
168
|
+
self.query = f'CREATE TABLE "{self.table}" (exchange SYMBOL(exchange), symbol SYMBOL(symbol), price DOUBLE, amount DOUBLE, side SYMBOL(side), fee DOUBLE, id STRING, order_id STRING, liquidity DOUBLE, type SYMBOL(type), account STRING, receipt_timestamp TIMESTAMP) SHARD_SIZE = {self.shard_size}'
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class IndexQuasar(QuasarCallback):
|
|
172
|
+
table_prefix = "index"
|
|
173
|
+
|
|
174
|
+
def _create_query(self):
|
|
175
|
+
self.query = f'CREATE TABLE "{self.table}" (exchange SYMBOL(exchange), symbol SYMBOL(symbol), price DOUBLE, receipt_timestamp TIMESTAMP) SHARD_SIZE = {self.shard_size}'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'''
|
|
2
|
-
Copyright (C) 2017-
|
|
2
|
+
Copyright (C) 2017-2025 Bryant Moscon - bmoscon@gmail.com
|
|
3
3
|
|
|
4
4
|
Please see the LICENSE file for the terms and conditions
|
|
5
5
|
associated with this software.
|
|
@@ -22,7 +22,7 @@ class QuestCallback(SocketCallback):
|
|
|
22
22
|
self.running = True
|
|
23
23
|
|
|
24
24
|
async def writer(self):
|
|
25
|
-
while
|
|
25
|
+
while self.running:
|
|
26
26
|
await self.connect()
|
|
27
27
|
async with self.read_queue() as updates:
|
|
28
28
|
update = "\n".join(updates) + "\n"
|
|
@@ -54,9 +54,12 @@ class TradeQuest(QuestCallback, BackendCallback):
|
|
|
54
54
|
async def write(self, data):
|
|
55
55
|
timestamp = data["timestamp"]
|
|
56
56
|
received_timestamp_int = int(data["receipt_timestamp"] * 1_000_000)
|
|
57
|
+
id_field = f'id={data["id"]}i,' if data["id"] is not None else ''
|
|
57
58
|
timestamp_int = int(timestamp * 1_000_000_000) if timestamp is not None else received_timestamp_int * 1000
|
|
58
|
-
update =
|
|
59
|
-
|
|
59
|
+
update = (
|
|
60
|
+
f'{self.key}-{data["exchange"]},symbol={data["symbol"]},side={data["side"]},type={data["type"]} '
|
|
61
|
+
f'price={data["price"]},amount={data["amount"]},{id_field}receipt_timestamp={received_timestamp_int}t {timestamp_int}'
|
|
62
|
+
)
|
|
60
63
|
await self.queue.put(update)
|
|
61
64
|
|
|
62
65
|
|
|
@@ -72,7 +75,7 @@ class BookQuest(QuestCallback):
|
|
|
72
75
|
self.depth = depth
|
|
73
76
|
|
|
74
77
|
async def __call__(self, book, receipt_timestamp: float):
|
|
75
|
-
vals = ','.join([f"bid_{i}_price={book.book.bids.index(i)[0]},bid_{i}_size={book.book.bids.index(i)[1]}" for i in range(self.depth)] + [f"
|
|
78
|
+
vals = ','.join([f"bid_{i}_price={book.book.bids.index(i)[0]},bid_{i}_size={book.book.bids.index(i)[1]}" for i in range(self.depth)] + [f"ask_{i}_price={book.book.asks.index(i)[0]},ask_{i}_size={book.book.asks.index(i)[1]}" for i in range(self.depth)])
|
|
76
79
|
timestamp = book.timestamp
|
|
77
80
|
receipt_timestamp_int = int(receipt_timestamp * 1_000_000)
|
|
78
81
|
timestamp_int = int(timestamp * 1_000_000_000) if timestamp is not None else receipt_timestamp_int * 1000
|