Skip to content

Commit 6ba7176

Browse files
authored
v4.5.22 - Theta option backtest strike selection
Merge v4.5.22 release branch after green CI.
2 parents ad65607 + 67474de commit 6ba7176

9 files changed

Lines changed: 95 additions & 22 deletions

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## 4.5.22 - Unreleased
4+
5+
### Fixed
6+
- **ThetaData option backtests no longer exhaustively download minute quote/OHLC data during delta strike selection.** `OptionsHelper.find_strike_for_delta()` now uses the existing model-based strike selector for ThetaData-routed option backtests, including intraday-cadence strategies, and leaves real historical price validation to `find_next_valid_option()` / `evaluate_option_market()`. This prevents sparse option chains from spending minutes probing empty strikes before any trade is placed.
7+
38
## 4.5.21 - Unreleased
49

510
## 4.5.20 - 2026-05-15

README.md

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,23 @@
88

99
**Build deterministic trading strategies, multi-agent LLM trading systems, and hybrid strategies that backtest, paper trade, and execute through real brokers.** Lumibot is an open-source algorithmic trading framework for stocks, options, crypto, futures, forex, indexes, SEC fundamentals, macro data, technical indicators, and AI agents that can actually place orders.
1010

11-
**Full docs:** [lumibot.lumiwealth.com](https://lumibot.lumiwealth.com/) · **No-code cloud:** [BotSpot.trade](https://botspot.trade/?utm_source=github&utm_medium=readme&utm_campaign=lumibot)
11+
**Full docs:** [lumibot.lumiwealth.com](https://lumibot.lumiwealth.com/) · **No-code cloud:** [BotSpot.trade](https://botspot.trade/?utm_source=github&utm_medium=readme&utm_campaign=lumibot&utm_content=top_text_link)
1212

1313
<p align="center">
14-
<a href="https://botspot.trade/?utm_source=github&utm_medium=readme&utm_campaign=lumibot">
15-
<strong>Build, backtest, and deploy an AI trading bot on BotSpot</strong>
14+
<a href="https://botspot.trade/?utm_source=github&utm_medium=readme&utm_campaign=lumibot&utm_content=hero_botspot_button">
15+
<img src="docs/assets/readme/button_build_ai_botspot.png" alt="Build AI trading bots on BotSpot Cloud" width="430">
1616
</a>
1717
<br>
18-
Describe a strategy in plain English. BotSpot generates Lumibot code, runs the backtest, and deploys it in the cloud.
18+
<a href="https://lumibot.lumiwealth.com/?utm_source=github&utm_medium=readme&utm_campaign=lumibot&utm_content=hero_docs_button">
19+
<img src="docs/assets/readme/button_read_lumibot_docs.png" alt="Read the Lumibot documentation" width="320">
20+
</a>
21+
<a href="https://www.botspot.trade/ai-bot-builder-bootcamp?utm_source=github&utm_medium=readme&utm_campaign=lumibot&utm_content=hero_course_button">
22+
<img src="docs/assets/readme/button_ai_trading_bootcamp.png" alt="Join the AI Trading Bootcamp" width="330">
23+
</a>
24+
</p>
25+
26+
<p align="center">
27+
<strong>Want the managed path?</strong> Describe a strategy in plain English. BotSpot generates Lumibot code, runs the backtest, and runs it in the cloud.
1928
</p>
2029

2130
<p align="center">
@@ -51,17 +60,27 @@ Built-in AI agent tools include market/account state, order inspection, DuckDB q
5160

5261
## Build Without Code on BotSpot
5362

54-
**[BotSpot](https://botspot.trade/?utm_source=github&utm_medium=readme&utm_campaign=lumibot)** is the managed cloud product built on Lumibot. Use it when you want to describe a strategy in plain English, have AI generate Lumibot code, backtest it, and deploy it without managing servers.
63+
**[BotSpot](https://botspot.trade/?utm_source=github&utm_medium=readme&utm_campaign=lumibot&utm_content=botspot_section_text_link)** is the managed cloud product built on Lumibot. Use it when you want to describe a strategy in plain English, have AI generate Lumibot code, backtest it, and run it without managing servers.
5564

5665
- **Build** strategies using natural language -- the AI writes production-ready Lumibot code for you
5766
- **Backtest** against years of historical data with a single click
5867
- **Deploy** to live trading with real brokers including Alpaca, Interactive Brokers, Tradier, Schwab, Tradovate, TopstepX via ProjectX, Bitunix, Coinbase, Kraken, WEEX, KuCoin, Binance, BitMEX, Bybit, and OKX
5968
- **Browse** a marketplace of proven, community-built strategies you can run immediately
6069

61-
**Start on BotSpot:** [Build, backtest, and deploy AI trading bots](https://botspot.trade/?utm_source=github&utm_medium=readme&utm_campaign=lumibot)
70+
<p align="center">
71+
<a href="https://botspot.trade/?utm_source=github&utm_medium=readme&utm_campaign=lumibot&utm_content=botspot_section_button">
72+
<img src="docs/assets/readme/button_build_ai_botspot.png" alt="Create my AI trading bot on BotSpot" width="460">
73+
</a>
74+
<br>
75+
<a href="https://www.botspot.trade/ai-bot-builder-bootcamp?utm_source=github&utm_medium=readme&utm_campaign=lumibot&utm_content=botspot_section_course_button">
76+
<img src="docs/assets/readme/button_ai_trading_bootcamp.png" alt="Learn AI trading in the BotSpot bootcamp" width="350">
77+
</a>
78+
</p>
6279

6380
<p align="center">
64-
<img src="docs/assets/readme/lumibot_botspot_launch_path.png" alt="Build on Lumibot and launch on BotSpot" width="100%">
81+
<a href="https://botspot.trade/?utm_source=github&utm_medium=readme&utm_campaign=lumibot&utm_content=botspot_launch_image">
82+
<img src="docs/assets/readme/lumibot_botspot_launch_path.png" alt="Build on Lumibot and launch on BotSpot" width="100%">
83+
</a>
6584
</p>
6685

6786
## Quick Start
@@ -117,14 +136,18 @@ For full setup guides, broker tutorials, AI-agent docs, examples, and deployment
117136

118137
### Option A: BotSpot (managed cloud)
119138

120-
[BotSpot](https://botspot.trade/?utm_source=github&utm_medium=readme&utm_campaign=lumibot) runs your Lumibot strategies on hosted infrastructure with scheduling, monitoring, and live execution. Build strategies with AI, no coding required.
139+
[BotSpot](https://botspot.trade/?utm_source=github&utm_medium=readme&utm_campaign=lumibot&utm_content=deploy_section_text_link) runs your Lumibot strategies on hosted infrastructure with scheduling, monitoring, and live execution. Build strategies with AI, no coding required.
121140

122141
- Create trading bots using natural language
123142
- Backtest with historical data
124143
- Deploy to trade automatically 24/7
125144
- Join a community of algorithmic traders
126145

127-
**[Open BotSpot.trade](https://botspot.trade/?utm_source=github&utm_medium=readme&utm_campaign=lumibot)**
146+
<p align="center">
147+
<a href="https://botspot.trade/?utm_source=github&utm_medium=readme&utm_campaign=lumibot&utm_content=deploy_section_button">
148+
<img src="docs/assets/readme/button_open_botspot_cloud.png" alt="Open BotSpot Cloud" width="460">
149+
</a>
150+
</p>
128151

129152
<p align="center">
130153
<img src="docs/assets/readme/lumibot_backtest_live_parity.png" alt="One Lumibot strategy can run in backtests and live broker accounts" width="100%">
@@ -207,11 +230,11 @@ Lumibot includes a built-in AI trading agent runtime. Build agents that run iden
207230
Start here:
208231
- [Agent Documentation](https://lumibot.lumiwealth.com/agents.html)
209232
- [Agent Flow Design](https://lumibot.lumiwealth.com/agents_flows.html)
210-
- [AI Investment Committee Example](https://github.com/Lumiwealth/lumibot/blob/version/4.5.11/lumibot/example_strategies/ai_investment_committee.py)
233+
- [AI Investment Committee Example](lumibot/example_strategies/ai_investment_committee.py)
211234
- [Standalone AI Committee Demo](https://github.com/Lumiwealth/lumibot-ai-investment-committee)
212-
- [Stock Agent Example](https://github.com/Lumiwealth/lumibot/blob/version/4.5.11/lumibot/example_strategies/agent_stock_backtest.py)
213-
- [Options Agent Example](https://github.com/Lumiwealth/lumibot/blob/version/4.5.11/lumibot/example_strategies/agent_option_backtest.py)
214-
- [Full Guide](https://github.com/Lumiwealth/lumibot/blob/version/4.5.11/docs/AI_TRADING_AGENTS.md)
235+
- [Discretionary Agent Example](lumibot/example_strategies/agent_discretionary.py)
236+
- [News Sentiment Agent Example](lumibot/example_strategies/agent_news_sentiment.py)
237+
- [Full Guide](docs/AI_TRADING_AGENTS.md)
215238

216239
## Memory and Traceability
217240

@@ -237,11 +260,9 @@ python -m lumibot.example_strategies.stock_buy_and_hold
237260
ls lumibot/example_strategies/
238261
```
239262

240-
Browse all examples: [example_strategies/](https://github.com/Lumiwealth/lumibot/tree/version/4.5.11/lumibot/example_strategies)
241-
242-
**External example repo:** [stock_example_algo](https://github.com/Lumiwealth-Strategies/stock_example_algo) (deployable to Render or Repl.it)
263+
Browse all examples: [example_strategies/](lumibot/example_strategies/)
243264

244-
[![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/Lumiwealth-Strategies/stock_example_algo)
265+
**External example repo:** [stock_example_algo](https://github.com/Lumiwealth-Strategies/stock_example_algo) shows a minimal strategy repository you can run yourself or adapt inside BotSpot.
245266

246267
## Backtesting Data Sources
247268

52.2 KB
Loading
52.6 KB
Loading
56.6 KB
Loading
52.6 KB
Loading

lumibot/components/options_helper.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,8 +1095,8 @@ def _coerce_price(value: Any) -> Optional[float]:
10951095
)
10961096
return delta
10971097

1098-
def _is_theta_option_daily_backtest(self) -> bool:
1099-
"""Return True when option pricing is routed through ThetaData in a daily backtest cadence."""
1098+
def _is_theta_option_backtest(self) -> bool:
1099+
"""Return True when option pricing is routed through ThetaData in a backtest."""
11001100
broker = getattr(self.strategy, "broker", None)
11011101
if broker is None or getattr(broker, "IS_BACKTESTING_BROKER", False) is not True:
11021102
return False
@@ -1119,6 +1119,16 @@ def _is_theta_option_daily_backtest(self) -> bool:
11191119

11201120
if not is_theta_option_provider:
11211121
return False
1122+
return True
1123+
1124+
def _is_theta_option_daily_backtest(self) -> bool:
1125+
"""Return True when option pricing is routed through ThetaData in a daily backtest cadence."""
1126+
if not self._is_theta_option_backtest():
1127+
return False
1128+
1129+
broker = getattr(self.strategy, "broker", None)
1130+
option_source = getattr(broker, "option_source", None)
1131+
data_source = option_source if option_source is not None else getattr(broker, "data_source", None)
11221132

11231133
is_daily_cadence = False
11241134
try:
@@ -1373,9 +1383,13 @@ def find_strike_for_delta(
13731383
return float(cached_strike)
13741384

13751385
is_call = option_type == "CALL"
1376-
is_theta_daily_backtest = self._is_theta_option_daily_backtest()
1386+
is_theta_option_backtest = self._is_theta_option_backtest()
13771387

1378-
if is_theta_daily_backtest and candidate_strikes:
1388+
if is_theta_option_backtest and candidate_strikes:
1389+
# ThetaData option backtests can turn live-style delta probing into many minute
1390+
# quote/OHLC downloads for nearby strikes before the strategy has selected a
1391+
# contract. Use the model-based selector for the strike target, then let
1392+
# find_next_valid_option/evaluate_option_market validate real historical prices.
13791393
modeled = self._select_strike_by_model_delta(
13801394
underlying_asset=underlying_asset,
13811395
underlying_price=float(underlying_price),

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def _maybe_copy_theta_terminal(self):
4343

4444
setuptools.setup(
4545
name="lumibot",
46-
version="4.5.21",
46+
version="4.5.22",
4747
author="Robert Grzesik",
4848
author_email="rob@botspot.trade",
4949
description="Python framework for algorithmic trading: backtesting and live deployment for stocks, options, crypto, futures, and forex. Same code for backtest and live trading.",

tests/test_options_helper_delta_target_normalization.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,36 @@ def should_not_call_delta(*_args, **_kwargs):
124124
)
125125

126126
assert strike in {90.0, 95.0, 100.0}
127+
128+
129+
def test_find_strike_for_delta_uses_model_path_for_theta_intraday_backtests():
130+
class ThetaDataBacktestingPandas:
131+
_timestep = "minute"
132+
133+
class _Broker:
134+
IS_BACKTESTING_BROKER = True
135+
136+
def __init__(self):
137+
source = ThetaDataBacktestingPandas()
138+
self.option_source = source
139+
self.data_source = source
140+
141+
strategy = _Strategy()
142+
strategy.sleeptime = "1H"
143+
strategy.broker = _Broker()
144+
helper = OptionsHelper(strategy)
145+
146+
def should_not_call_delta(*_args, **_kwargs):
147+
raise AssertionError("theta backtest model path should not call get_delta_for_strike")
148+
149+
helper.get_delta_for_strike = should_not_call_delta # type: ignore[assignment]
150+
151+
strike = helper.find_strike_for_delta(
152+
underlying_asset=Asset("TEST", asset_type=Asset.AssetType.STOCK),
153+
underlying_price=100.0,
154+
target_delta=0.30,
155+
expiry=date(2026, 2, 20),
156+
right="put",
157+
)
158+
159+
assert strike in {90.0, 95.0, 100.0}

0 commit comments

Comments
 (0)