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.
Files changed (111) hide show
  1. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/AUTHORS.md +5 -0
  2. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/CHANGES.md +22 -0
  3. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/INSTALL.md +5 -0
  4. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/LICENSE +1 -1
  5. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/PKG-INFO +73 -13
  6. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/README.md +3 -3
  7. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/__init__.py +1 -1
  8. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/_util.py +1 -1
  9. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/aggregate.py +4 -4
  10. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/arctic.py +1 -1
  11. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/backend.py +1 -1
  12. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/gcppubsub.py +1 -1
  13. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/http.py +1 -1
  14. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/influxdb.py +2 -2
  15. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/kafka.py +1 -1
  16. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/mongo.py +1 -1
  17. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/postgres.py +1 -1
  18. cryptofeed-2.4.1/cryptofeed/backends/quasardb.py +175 -0
  19. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/quest.py +8 -5
  20. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/rabbitmq.py +1 -1
  21. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/redis.py +1 -1
  22. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/socket.py +1 -1
  23. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/zmq.py +1 -1
  24. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/callback.py +1 -1
  25. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/config.py +1 -1
  26. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/connection.py +14 -8
  27. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/connection_handler.py +1 -21
  28. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/defines.py +2 -2
  29. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exceptions.py +1 -1
  30. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchange.py +4 -4
  31. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/__init__.py +4 -4
  32. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/ascendex.py +1 -1
  33. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bequant.py +1 -1
  34. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/binance.py +1 -1
  35. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/binance_delivery.py +1 -1
  36. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/binance_futures.py +1 -1
  37. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/binance_tr.py +1 -1
  38. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/binance_us.py +1 -1
  39. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bitdotcom.py +4 -5
  40. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bitfinex.py +2 -2
  41. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bitflyer.py +1 -1
  42. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bitget.py +1 -1
  43. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bithumb.py +1 -1
  44. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bitmex.py +18 -10
  45. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/bitstamp.py +1 -1
  46. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/blockchain.py +1 -1
  47. cryptofeed-2.4.1/cryptofeed/exchanges/bybit.py +618 -0
  48. cryptofeed-2.4.1/cryptofeed/exchanges/coinbase.py +192 -0
  49. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/cryptodotcom.py +1 -1
  50. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/delta.py +2 -2
  51. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/deribit.py +6 -2
  52. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/dydx.py +1 -1
  53. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/fmfw.py +1 -1
  54. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/gateio.py +1 -1
  55. cryptofeed-2.4.1/cryptofeed/exchanges/gateio_futures.py +361 -0
  56. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/gemini.py +1 -1
  57. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/hitbtc.py +1 -1
  58. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/huobi.py +1 -1
  59. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/huobi_dm.py +1 -1
  60. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/huobi_swap.py +4 -4
  61. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/independent_reserve.py +6 -6
  62. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/kraken.py +1 -1
  63. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/kraken_futures.py +4 -2
  64. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/kucoin.py +2 -2
  65. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/binance_rest.py +1 -1
  66. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/bitfinex_rest.py +1 -1
  67. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/bitmex_rest.py +1 -1
  68. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/bitstamp_rest.py +1 -1
  69. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/coinbase_rest.py +1 -1
  70. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/deribit_rest.py +1 -1
  71. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/dydx_rest.py +1 -1
  72. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/gemini_rest.py +1 -1
  73. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/kraken_rest.py +1 -1
  74. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/okx_rest.py +1 -1
  75. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/upbit_rest.py +1 -1
  76. cryptofeed-2.4.1/cryptofeed/exchanges/okcoin.py +45 -0
  77. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/okx.py +4 -4
  78. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/phemex.py +1 -1
  79. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/poloniex.py +1 -1
  80. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/probit.py +1 -1
  81. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/upbit.py +1 -1
  82. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/feed.py +1 -1
  83. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/feedhandler.py +1 -1
  84. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/log.py +1 -1
  85. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/nbbo.py +1 -1
  86. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/raw_data_collection.py +1 -1
  87. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/symbols.py +1 -1
  88. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/types.c +21224 -9672
  89. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/types.pyx +1 -1
  90. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/util/book.py +1 -1
  91. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/util/perf.py +1 -1
  92. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/util/time.py +1 -1
  93. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed.egg-info/PKG-INFO +73 -13
  94. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed.egg-info/SOURCES.txt +2 -1
  95. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed.egg-info/requires.txt +6 -2
  96. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/setup.py +9 -7
  97. cryptofeed-2.3.2/cryptofeed/exchanges/bittrex.py +0 -413
  98. cryptofeed-2.3.2/cryptofeed/exchanges/bybit.py +0 -520
  99. cryptofeed-2.3.2/cryptofeed/exchanges/coinbase.py +0 -391
  100. cryptofeed-2.3.2/cryptofeed/exchanges/okcoin.py +0 -163
  101. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/MANIFEST.in +0 -0
  102. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/backends/__init__.py +0 -0
  103. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/ascendex_futures.py +0 -0
  104. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/exx.py +0 -0
  105. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/exchanges/mixins/__init__.py +0 -0
  106. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/util/__init__.py +0 -0
  107. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed/util/split.py +0 -0
  108. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed.egg-info/dependency_links.txt +0 -0
  109. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/cryptofeed.egg-info/top_level.txt +0 -0
  110. {cryptofeed-2.3.2 → cryptofeed-2.4.1}/pyproject.toml +0 -0
  111. {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-2023 Bryant Moscon - bmoscon@gmail.com
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.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,Bittrex,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
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.8
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
- Provides-Extra: gcp_pubsub
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
- License-File: LICENSE
30
- License-File: AUTHORS.md
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](https://img.shields.io/badge/license-XFree86-blue.svg)](LICENSE)
34
69
  ![Python](https://img.shields.io/badge/Python-3.8+-green.svg)
35
- [![Build Status](https://travis-ci.com/bmoscon/cryptofeed.svg?branch=master)](https://travis-ci.com/bmoscon/cryptofeed)
36
70
  [![PyPi](https://img.shields.io/badge/PyPi-cryptofeed-brightgreen.svg)](https://pypi.python.org/pypi/cryptofeed)
37
71
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/efa4e0d6e10b41d0b51454d08f7b33b1)](https://www.codacy.com/app/bmoscon/cryptofeed?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=bmoscon/cryptofeed&amp;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 [slack](https://join.slack.com/t/cryptofeed-dev/shared_invite/enQtNjY4ODIwODA1MzQ3LTIzMzY3Y2YxMGVhNmQ4YzFhYTc3ODU1MjQ5MDdmY2QyZjdhMGU5ZDFhZDlmMmYzOTUzOTdkYTZiOGUwNGIzYTk) or open a thread in the [discussions](https://github.com/bmoscon/cryptofeed/discussions) in GitHub.
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](https://img.shields.io/badge/license-XFree86-blue.svg)](LICENSE)
3
3
  ![Python](https://img.shields.io/badge/Python-3.8+-green.svg)
4
- [![Build Status](https://travis-ci.com/bmoscon/cryptofeed.svg?branch=master)](https://travis-ci.com/bmoscon/cryptofeed)
5
4
  [![PyPi](https://img.shields.io/badge/PyPi-cryptofeed-brightgreen.svg)](https://pypi.python.org/pypi/cryptofeed)
6
5
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/efa4e0d6e10b41d0b51454d08f7b33b1)](https://www.codacy.com/app/bmoscon/cryptofeed?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=bmoscon/cryptofeed&amp;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 [slack](https://join.slack.com/t/cryptofeed-dev/shared_invite/enQtNjY4ODIwODA1MzQ3LTIzMzY3Y2YxMGVhNmQ4YzFhYTc3ODU1MjQ5MDdmY2QyZjdhMGU5ZDFhZDlmMmYzOTUzOTdkYTZiOGUwNGIzYTk) or open a thread in the [discussions](https://github.com/bmoscon/cryptofeed/discussions) in GitHub.
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-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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, '__class__'):
17
- setattr(self, 'start', self.handler.start)
18
- setattr(self, 'stop', self.handler.stop)
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-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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}')
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -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-2023 Bryant Moscon - bmoscon@gmail.com
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 True:
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 = f'{self.key}-{data["exchange"]},symbol={data["symbol"]},side={data["side"]},type={data["type"]} ' \
59
- f'price={data["price"]},amount={data["amount"]},id={data["id"]}i,receipt_timestamp={received_timestamp_int}t {timestamp_int}'
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"ask{i}_price={book.book.asks.index(i)[0]},ask_{i}_size={book.book.asks.index(i)[1]}" for i in range(self.depth)])
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
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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.
@@ -1,5 +1,5 @@
1
1
  '''
2
- Copyright (C) 2017-2023 Bryant Moscon - bmoscon@gmail.com
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.