lumibot 4.0.21__py3-none-any.whl → 4.0.23__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of lumibot might be problematic. Click here for more details.
- lumibot/backtesting/__init__.py +3 -3
- lumibot/data_sources/__init__.py +2 -1
- lumibot/data_sources/databento_data.py +5 -5
- lumibot/data_sources/databento_data_polars_backtesting.py +490 -0
- lumibot/data_sources/databento_data_polars_live.py +793 -0
- {lumibot-4.0.21.dist-info → lumibot-4.0.23.dist-info}/METADATA +1 -1
- {lumibot-4.0.21.dist-info → lumibot-4.0.23.dist-info}/RECORD +12 -10
- tests/backtest/test_databento.py +56 -2
- tests/test_databento_live.py +10 -10
- {lumibot-4.0.21.dist-info → lumibot-4.0.23.dist-info}/LICENSE +0 -0
- {lumibot-4.0.21.dist-info → lumibot-4.0.23.dist-info}/WHEEL +0 -0
- {lumibot-4.0.21.dist-info → lumibot-4.0.23.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
lumibot/__init__.py,sha256=fHJI9tgI2gk8n7Z8v8bopekW7oXIa8Rm3nYKwhQkYxo,4378
|
|
2
2
|
lumibot/constants.py,sha256=aQT0_QR7sCQuNPizeo2lQNhF0xd5g_H2_gr_-kG2AXM,629
|
|
3
3
|
lumibot/credentials.py,sha256=tplT093Fd0lDP0fUAxpqQb9Iqh67pWBDL8P39VaUyCY,31238
|
|
4
|
-
lumibot/backtesting/__init__.py,sha256=
|
|
4
|
+
lumibot/backtesting/__init__.py,sha256=vrzgpE4TsVJFzFs1xf0aqvSQ5Vj74iv5tG_aWW5I2i0,782
|
|
5
5
|
lumibot/backtesting/alpaca_backtesting.py,sha256=56vnBwKjwZ-8QW92I_dlJd1AO752_WV5Mhwt8jd7x5o,31258
|
|
6
6
|
lumibot/backtesting/alpha_vantage_backtesting.py,sha256=LR3UNhJrdAKdvadiThVKdKrMZYQ_xcHzAISKPe0yqS0,417
|
|
7
7
|
lumibot/backtesting/backtesting_broker.py,sha256=mf-UnOT9DX-JhF8wjqKQZrv-wY48rH0_B9CwTtR-o4M,62267
|
|
@@ -33,7 +33,7 @@ lumibot/components/options_helper.py,sha256=Y41hcNFNJO7PdZZAf0P5_cem5byYd-zIq7BR
|
|
|
33
33
|
lumibot/components/perplexity_helper.py,sha256=0dhAIXunvUnTKIFFdYbFt8adnSIavKRqXkQ91fjsDPI,31432
|
|
34
34
|
lumibot/components/quiver_helper.py,sha256=s0Y-tL1y2S1mYlbtlRTcL5R4WV0HYOgiSJ9hT41Hzrw,14380
|
|
35
35
|
lumibot/components/vix_helper.py,sha256=tsWHFQzOJCjdmSGgmnYIty0K5ua-iAgBiRlyRIpGli0,61940
|
|
36
|
-
lumibot/data_sources/__init__.py,sha256=
|
|
36
|
+
lumibot/data_sources/__init__.py,sha256=pIU_0Kbucd594EmUQoQC6QpPJA9EUlNwJjTGj9fOzKE,1064
|
|
37
37
|
lumibot/data_sources/alpaca_data.py,sha256=9pguY470mfgqSFYsB09ujQu9yBnX1Wb5H_ef0d1WzzM,50012
|
|
38
38
|
lumibot/data_sources/alpha_vantage_data.py,sha256=ypcbMlJEF3r4_rGL_QLRqicG0FRHH9g_D_UR_obRa-8,5040
|
|
39
39
|
lumibot/data_sources/bitunix_data.py,sha256=H2u4fJVEJqmNrqJnYs1hucZyg4N3dEtCB9JZsEm2am8,8946
|
|
@@ -41,8 +41,10 @@ lumibot/data_sources/ccxt_backtesting_data.py,sha256=FgVVMgA0WLF1RYlSNENN7jkppUj
|
|
|
41
41
|
lumibot/data_sources/ccxt_data.py,sha256=kvLtfcXfS_V6yILzUATdQMa07lZdspMtDez0boFE4DE,7766
|
|
42
42
|
lumibot/data_sources/data_source.py,sha256=oOZ9hdg2OUAFT5yCQ8uExDEoNYqqeswDoHdVxHhJACs,28225
|
|
43
43
|
lumibot/data_sources/data_source_backtesting.py,sha256=nQKx9uxFUaZfNBQk4jqBuwEy3Y7J3TPl21woPJXr61k,8711
|
|
44
|
-
lumibot/data_sources/databento_data.py,sha256=
|
|
44
|
+
lumibot/data_sources/databento_data.py,sha256=GdD9UwLhRkbWwVpqssO6hT_pALh_V3t1aIO_j90FJFk,14210
|
|
45
45
|
lumibot/data_sources/databento_data_polars.py,sha256=7Nl6TDfP4piUSiZs3KqFuZkdseEu3-7F37mWUC6P76U,36479
|
|
46
|
+
lumibot/data_sources/databento_data_polars_backtesting.py,sha256=naARl0QVzOkeUCU2z2z37i4Z_DelJoBSbOgqsYeqnJA,17851
|
|
47
|
+
lumibot/data_sources/databento_data_polars_live.py,sha256=NJc1nHU6P94uUZQWtQ0z5-bi1SRKCkW4-yCFmwZ5FDI,36479
|
|
46
48
|
lumibot/data_sources/example_broker_data.py,sha256=WkCc3rLyOOI4GzLptUwhqeFRkEWQsM4y3tdzUbHPfik,2066
|
|
47
49
|
lumibot/data_sources/exceptions.py,sha256=fYS44FgrzyDAuPqZRo3RiZKijjcurcG81HkL2dWURX0,557
|
|
48
50
|
lumibot/data_sources/interactive_brokers_data.py,sha256=2e0cqOHaveL9XdlZ_N98vehUuoKaHqhV4BelMIScUqQ,13894
|
|
@@ -170,7 +172,7 @@ tests/test_databento_backtesting.py,sha256=5uGiKxQIY8eYVvgQEO6kA4GWUP4k2MCHi_S5h
|
|
|
170
172
|
tests/test_databento_backtesting_polars.py,sha256=V9Z7-WG2TNKpHQVF5vGJSIdgUsuhJwlopZV66FREWA0,8097
|
|
171
173
|
tests/test_databento_data.py,sha256=HakjDileGpicQc_OXeX7l8ncIDn3FtxP8ymKA6TQp8o,18860
|
|
172
174
|
tests/test_databento_helper.py,sha256=3z9OLiJdtxDsZmM9tVhzqn4U6wNWKFfTygU_YcRiuhk,44253
|
|
173
|
-
tests/test_databento_live.py,sha256=
|
|
175
|
+
tests/test_databento_live.py,sha256=tbg2C9cyW45OYY7dKYlPMNZpgsN_sjs4yk1GR23OL6o,15648
|
|
174
176
|
tests/test_databento_timezone_fixes.py,sha256=kJClHKqQ9ZiNd4Bt0ceGx9fMxjVnyR3F9T7jJ66hRQg,10832
|
|
175
177
|
tests/test_drift_rebalancer.py,sha256=AUuEd3WIunfx3gwVdLVtq8jOHlz65UeqpO4adY1xfcs,105289
|
|
176
178
|
tests/test_futures_integration.py,sha256=3Ut0M8d5xPwHd4WcTSmP4HLC7VG_xSUXeJPX0-c0Fe8,9179
|
|
@@ -224,7 +226,7 @@ tests/backtest/performance_tracker.py,sha256=oyaDvte66HveBAiU6fOsk5Z5FJaKulKN67I
|
|
|
224
226
|
tests/backtest/test_backtesting_broker_processing.py,sha256=JbTKZvcMq3l4AgIGhsvVWvhw3_NXQwql2ImztNKbziw,22145
|
|
225
227
|
tests/backtest/test_buy_hold_quiet_logs_full_run.py,sha256=LDiR8wsEwIASPnO_bUMide6re0Jb-rzFG3hccD9OGJM,4998
|
|
226
228
|
tests/backtest/test_crypto_cash_regressions.py,sha256=-f0wjb-9nXpggS30N4zomYl098Qu-tfvfWwhlkoxPMM,6077
|
|
227
|
-
tests/backtest/test_databento.py,sha256=
|
|
229
|
+
tests/backtest/test_databento.py,sha256=MNrpV4nUczUJUyaMS0mbfQ8BAd77-avgNeFP3qsLcI8,7395
|
|
228
230
|
tests/backtest/test_dividends.py,sha256=fYSpzAf13AMpfxmxyFTfvUGPAGkbUTWL_gUYQUrqkbU,9815
|
|
229
231
|
tests/backtest/test_example_strategies.py,sha256=EDgz-1PJUHEv_11DLWXvlzHqGOY_bJSCnUA16VbMByY,14575
|
|
230
232
|
tests/backtest/test_failing_backtest.py,sha256=jBkm_3Yq-TrzezAQM7XEAn3424lzG6Mu5agnTJQCo6E,5460
|
|
@@ -235,8 +237,8 @@ tests/backtest/test_polygon.py,sha256=bKrI5C3Gel1nsZfSR4tqdONMpEDNBDy1Q2If7wLclD
|
|
|
235
237
|
tests/backtest/test_strategy_executor.py,sha256=r-QNPCNJnisxQyIAxPGO-BQ-l3qtZMChOUWCVX-b4ls,1289
|
|
236
238
|
tests/backtest/test_thetadata.py,sha256=-76X2QpPCt-EXkOYeTlFIOr_UBBGPel0B-r_F84hl5g,16838
|
|
237
239
|
tests/backtest/test_yahoo.py,sha256=FolIqwsPlAOyAr2fjw4TKp_dAzBLT-KMLNcJa1ej4RE,2011
|
|
238
|
-
lumibot-4.0.
|
|
239
|
-
lumibot-4.0.
|
|
240
|
-
lumibot-4.0.
|
|
241
|
-
lumibot-4.0.
|
|
242
|
-
lumibot-4.0.
|
|
240
|
+
lumibot-4.0.23.dist-info/LICENSE,sha256=fYhGIyxjyNXACgpNQS3xxpxDOaVOWRVxZMCRbsDv8k0,35130
|
|
241
|
+
lumibot-4.0.23.dist-info/METADATA,sha256=5ZXFriQ3hRp76mlw6FMmw6u68Zm1iC6pKk_allFOQQc,11519
|
|
242
|
+
lumibot-4.0.23.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
243
|
+
lumibot-4.0.23.dist-info/top_level.txt,sha256=otUnUjDFVASauEDiTiAzNgMyqQ1B6jjS3QqqP-WSx38,14
|
|
244
|
+
lumibot-4.0.23.dist-info/RECORD,,
|
tests/backtest/test_databento.py
CHANGED
|
@@ -3,6 +3,7 @@ import pytest
|
|
|
3
3
|
import pytz
|
|
4
4
|
|
|
5
5
|
from lumibot.backtesting import BacktestingBroker, DataBentoDataBacktesting
|
|
6
|
+
from lumibot.data_sources import DataBentoDataBacktesting as DataBentoDataBacktestingPolars
|
|
6
7
|
from lumibot.entities import Asset
|
|
7
8
|
from lumibot.strategies import Strategy
|
|
8
9
|
from lumibot.traders import Trader
|
|
@@ -97,6 +98,58 @@ class TestDatabentoBacktestFull:
|
|
|
97
98
|
for price in strat_obj.prices:
|
|
98
99
|
assert price is not None and price > 0, f"Expected valid price, got {price}"
|
|
99
100
|
|
|
101
|
+
@pytest.mark.apitest
|
|
102
|
+
@pytest.mark.skipif(
|
|
103
|
+
not DATABENTO_API_KEY,
|
|
104
|
+
reason="This test requires a Databento API key"
|
|
105
|
+
)
|
|
106
|
+
@pytest.mark.skipif(
|
|
107
|
+
DATABENTO_API_KEY == '<your key here>',
|
|
108
|
+
reason="This test requires a Databento API key"
|
|
109
|
+
)
|
|
110
|
+
def test_databento_continuous_futures_minute_data_polars(self):
|
|
111
|
+
"""
|
|
112
|
+
Test Databento with Polars implementation - minute-level data.
|
|
113
|
+
Should be significantly faster than pandas version.
|
|
114
|
+
"""
|
|
115
|
+
# Use timezone-aware datetimes for futures trading
|
|
116
|
+
tzinfo = pytz.timezone("America/New_York")
|
|
117
|
+
backtesting_start = tzinfo.localize(datetime.datetime(2025, 1, 2, 9, 30))
|
|
118
|
+
backtesting_end = tzinfo.localize(datetime.datetime(2025, 1, 3, 16, 0))
|
|
119
|
+
|
|
120
|
+
data_source = DataBentoDataBacktestingPolars(
|
|
121
|
+
datetime_start=backtesting_start,
|
|
122
|
+
datetime_end=backtesting_end,
|
|
123
|
+
api_key=DATABENTO_API_KEY,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
broker = BacktestingBroker(data_source=data_source)
|
|
127
|
+
|
|
128
|
+
strat_obj = SimpleContinuousFutures(
|
|
129
|
+
broker=broker,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
trader = Trader(logfile="", backtest=True)
|
|
133
|
+
trader.add_strategy(strat_obj)
|
|
134
|
+
results = trader.run_all(
|
|
135
|
+
show_plot=False,
|
|
136
|
+
show_tearsheet=False,
|
|
137
|
+
show_indicators=False,
|
|
138
|
+
save_tearsheet=False
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
# Verify results
|
|
142
|
+
assert results is not None
|
|
143
|
+
assert len(strat_obj.prices) > 0, "Expected to collect some prices"
|
|
144
|
+
assert len(strat_obj.times) > 0, "Expected to collect some timestamps"
|
|
145
|
+
|
|
146
|
+
# Verify minute-level cadence
|
|
147
|
+
assert len(strat_obj.prices) > 100, f"Expected many minute-level data points, got {len(strat_obj.prices)}"
|
|
148
|
+
|
|
149
|
+
# Verify all prices are valid numbers
|
|
150
|
+
for price in strat_obj.prices:
|
|
151
|
+
assert price is not None and price > 0, f"Expected valid price, got {price}"
|
|
152
|
+
|
|
100
153
|
@pytest.mark.apitest
|
|
101
154
|
@pytest.mark.skipif(
|
|
102
155
|
not DATABENTO_API_KEY,
|
|
@@ -111,8 +164,9 @@ class TestDatabentoBacktestFull:
|
|
|
111
164
|
Test Databento with continuous futures using daily data over a longer period.
|
|
112
165
|
This is similar to the profiling test but as a permanent test.
|
|
113
166
|
"""
|
|
114
|
-
|
|
115
|
-
|
|
167
|
+
tzinfo = pytz.timezone("America/New_York")
|
|
168
|
+
backtesting_start = tzinfo.localize(datetime.datetime(2025, 1, 2))
|
|
169
|
+
backtesting_end = tzinfo.localize(datetime.datetime(2025, 3, 31))
|
|
116
170
|
|
|
117
171
|
# Simple daily strategy
|
|
118
172
|
class DailyContinuousFutures(Strategy):
|
tests/test_databento_live.py
CHANGED
|
@@ -27,13 +27,13 @@ load_dotenv()
|
|
|
27
27
|
def test_symbol_resolution():
|
|
28
28
|
"""Test that symbols are properly resolved to contract codes"""
|
|
29
29
|
from lumibot.entities import Asset
|
|
30
|
-
from lumibot.data_sources.
|
|
30
|
+
from lumibot.data_sources.databento_data_polars_live import DataBentoDataPolarsLive
|
|
31
31
|
|
|
32
32
|
print("\n" + "="*60)
|
|
33
33
|
print("TEST 1: Symbol Resolution")
|
|
34
34
|
print("="*60)
|
|
35
35
|
|
|
36
|
-
data_source =
|
|
36
|
+
data_source = DataBentoDataPolarsLive(
|
|
37
37
|
api_key=os.getenv('DATABENTO_API_KEY'),
|
|
38
38
|
has_paid_subscription=True,
|
|
39
39
|
enable_live_stream=False # Don't need streaming for this test
|
|
@@ -97,14 +97,14 @@ def test_live_api_connection():
|
|
|
97
97
|
def test_minute_bar_aggregation():
|
|
98
98
|
"""Test minute bar aggregation with <1 minute lag"""
|
|
99
99
|
from lumibot.entities import Asset
|
|
100
|
-
from lumibot.data_sources.
|
|
100
|
+
from lumibot.data_sources.databento_data_polars_live import DataBentoDataPolarsLive
|
|
101
101
|
|
|
102
102
|
print("\n" + "="*60)
|
|
103
103
|
print("TEST 3: Minute Bar Aggregation & Latency")
|
|
104
104
|
print("="*60)
|
|
105
105
|
|
|
106
106
|
# Initialize with Live API
|
|
107
|
-
data_source =
|
|
107
|
+
data_source = DataBentoDataPolarsLive(
|
|
108
108
|
api_key=os.getenv('DATABENTO_API_KEY'),
|
|
109
109
|
has_paid_subscription=True,
|
|
110
110
|
enable_live_stream=True
|
|
@@ -175,13 +175,13 @@ def test_minute_bar_aggregation():
|
|
|
175
175
|
)
|
|
176
176
|
def test_api_routing():
|
|
177
177
|
"""Test that correct API is used based on time range"""
|
|
178
|
-
from lumibot.data_sources.
|
|
178
|
+
from lumibot.data_sources.databento_data_polars_live import DataBentoDataPolarsLive
|
|
179
179
|
|
|
180
180
|
print("\n" + "="*60)
|
|
181
181
|
print("TEST 4: API Routing (Live vs Historical)")
|
|
182
182
|
print("="*60)
|
|
183
183
|
|
|
184
|
-
data_source =
|
|
184
|
+
data_source = DataBentoDataPolarsLive(
|
|
185
185
|
api_key=os.getenv('DATABENTO_API_KEY'),
|
|
186
186
|
has_paid_subscription=True,
|
|
187
187
|
enable_live_stream=True
|
|
@@ -219,13 +219,13 @@ def test_api_routing():
|
|
|
219
219
|
def test_long_time_periods():
|
|
220
220
|
"""Test different time periods including long periods (500+ bars)"""
|
|
221
221
|
from lumibot.entities import Asset
|
|
222
|
-
from lumibot.data_sources.
|
|
222
|
+
from lumibot.data_sources.databento_data_polars_live import DataBentoDataPolarsLive
|
|
223
223
|
|
|
224
224
|
print("\n" + "="*60)
|
|
225
225
|
print("TEST 5: Long Time Period Handling (500+ bars)")
|
|
226
226
|
print("="*60)
|
|
227
227
|
|
|
228
|
-
data_source =
|
|
228
|
+
data_source = DataBentoDataPolarsLive(
|
|
229
229
|
api_key=os.getenv('DATABENTO_API_KEY'),
|
|
230
230
|
has_paid_subscription=True,
|
|
231
231
|
enable_live_stream=True
|
|
@@ -324,14 +324,14 @@ def test_long_time_periods():
|
|
|
324
324
|
def test_continuous_latency_monitoring():
|
|
325
325
|
"""Run continuous tests to verify consistent <1 minute lag"""
|
|
326
326
|
from lumibot.entities import Asset
|
|
327
|
-
from lumibot.data_sources.
|
|
327
|
+
from lumibot.data_sources.databento_data_polars_live import DataBentoDataPolarsLive
|
|
328
328
|
|
|
329
329
|
print("\n" + "="*60)
|
|
330
330
|
print("TEST 6: Continuous Latency Monitoring")
|
|
331
331
|
print("="*60)
|
|
332
332
|
print("Running 5 consecutive tests to verify consistent low latency...")
|
|
333
333
|
|
|
334
|
-
data_source =
|
|
334
|
+
data_source = DataBentoDataPolarsLive(
|
|
335
335
|
api_key=os.getenv('DATABENTO_API_KEY'),
|
|
336
336
|
has_paid_subscription=True,
|
|
337
337
|
enable_live_stream=True
|
|
File without changes
|
|
File without changes
|
|
File without changes
|