Skip to content

View original

DeribitBtcWeeklyPutWriteTrendGatedOnly

Hypotheses

Deribit BTC Weekly Cash-Secured OTM Put-Write — Trend-Gated Only, Fixed ~25-Delta, NO Long-Lookback IV Gate (Single-Leg VRP Harvest on the One Options Cell That Already Works, ~Weekly Cadence, 2-Parameter)

Hypotheses

A SINGLE-LEG, fully cash-collateralized weekly PUT-WRITING program on Deribit BTC options — deliberately the SAME instrument, venue, and execution path as the factory's single highest-Sharpe promoted strategy (Deribit BTC Weekly Cash-Secured Put-Write, Sharpe 12.2), which PROVES this exact cell has real edge, catalogued greeks/IV data, and a working options execution path (the only one that has ever cleared Layer 3). It is distinct from that promoted winner in one deliberate, evidence-driven way: it DROPS the long-lookback IV-rank / IV>RV double-gate that repeatedly abandoned the ETH-weekly and BTC/ETH-monthly siblings (those needed a ~560-day rolling IV lookback → only 4 trades → metrics_reliable=false, a structural dead end). Instead it keeps ONLY the trend filter (the gate the winner's own title flags as load-bearing) and writes a fixed ~25-delta OTM put on a ~weekly cadence. Because it does not depend on a multi-year IV-percentile window, it trades every eligible week (~40-52/yr) over the available Deribit BTC weekly option history — producing a statistically reliable trade count and sidestepping the exact 'too few trades' wall that killed every other options proposal this session. It fills the most under-represented venue (options: Deribit 5.4% + Binance-options 0.1% vs a ≥15% target) with the lowest-risk options bet available: a variant on the one options cell already known to execute and profit. Deliberately 2 parameters (put delta, trend-filter length) to resist overfit (the 202x killer).

Hypotheses

Iteration 3 fixes the recurring Layer-3 wall-clock timeout at its true source. Because this strategy has NO smoke path (per current guidance, so real option legs trade and it passes options_no_option_trades), the Layer-3 sandbox runs the FULL options backtest by expanding the real chain — unlike the smoke-path era siblings that ran a fast perp-only trade in the sandbox and deferred options to the 2h-cap backtesting stage. At 1-HOUR that full backtest processes ~17.5k bars across ~52 option instruments (option marking/PnL per bar), which exceeded 300s even after iter-2 cut lookback_days to 365. The decisive, minimal fix is to coarsen the timeframe: I switched both the primary perp bar_type and the rolling_options leg timeframe to 1-DAY, which cuts the sandbox bar count ~24x (365 daily primary bars + ~360 daily weekly-leg bars vs ~17.5k hourly) so the run completes comfortably under the cap. This is data-safe: the chain expander probes contract existence at hourly resolution but loads each leg at the spec timeframe, and the collector already fetches Deribit at '1D' (the perp price series in expand_rolling_options uses '1D'), so daily option candles resolve on demand. A weekly option still has ~7 daily bars — enough for the entry-window market check, mark-to-market, and the ~24h-before-expiry close. The strategy CODE is essentially unchanged (per-bar work stays O(1) incremental SMA); only the SMA default moved from 1200 hourly bars to a natural 50-DAY window to match the daily primary, and the trend gate / roll / sizing logic that passed Layers 1-2 is untouched. It preserves the hypothesis: subclass RollingOptionsStrategy directly, single trend gate, no IV window, ~45-52 weekly writes (reliable count, far above the 4-trade dead end), single-leg cash-secured (risk_frac 0.8, leverage 1.0), Deribit venue, 2 parameters.

Hypotheses

backtest_failed: RuntimeError: rolling_options expansion failed (ReadError: ); refusing to run with an empty option schedule Traceback (most recent call last): File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 101, in map_httpcore_exceptions yield File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 394, in handle_async_request resp = await self._pool.handle_async_request(req) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/connection_pool.py", line 256, in handle_async_request raise exc from None File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/connection_pool.py", line 236, in handle_async_request response = await connection.handle_async_request( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/connection.py", line 103, in handle_async_request return await self._connection.handle_async_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 136, in handle_async_request raise exc File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 106, in handle_async_request ) = await self._receive_response_headers(**kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 177, in _receive_response_headers event = await self._receive_event(timeout=timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 217, in _receive_event data = await self._network_stream.read( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_backends/anyio.py", line 32, in read with map_exceptions(exc_map): File "/usr/lib/python3.12/contextlib.py", line 158, in __exit__ self.gen.throw(value) File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_exceptions.py", line 14, in map_exceptions raise to_exc(exc) from exc httpcore.ReadError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/opt/strategy-factory/src/agents/backtest_agent.py", line 49, in expand_rolling_options_into_config extra_i, extra_bt, sched = await expand_rolling_options(collector, spec, start, end) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/data/option_chain.py", line 242, in expand_rolling_options contracts = await discover_deribit_chain( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/data/option_chain.py", line 143, in discover_deribit_chain perp_bars = await collector.fetch_ohlcv(perp, start_ms, end_ms, "1D") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/data/collectors/deribit_collector.py", line 169, in fetch_ohlcv result = await self._get("/public/get_tradingview_chart_data", { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/data/collectors/deribit_collector.py", line 86, in _get response = await self._client.get(f"{DERIBIT_API_URL}{endpoint}", params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1768, in get return await self.request( ^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1540, in request return await self.send(request, auth=auth, follow_redirects=follow_redirects) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1629, in send response = await self._send_handling_auth( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1657, in _send_handling_auth response = await self._send_handling_redirects( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1694, in _send_handling_redirects response = await self._send_single_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1730, in _send_single_request response = await transport.handle_async_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 393, in handle_async_request with map_httpcore_exceptions(): File "/usr/lib/python3.12/contextlib.py", line 158, in __exit__ self.gen.throw(value) File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 118, in map_httpcore_exceptions raise mapped_exc(message) from exc httpx.ReadError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/opt/strategy-factory/src/agents/backtest_agent.py", line 184, in _run_backtest config = await self._maybe_expand_rolling_options(config, catalog_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/agents/backtest_agent.py", line 427, in _maybe_expand_rolling_options config = await expand_rolling_options_into_config(config, catalog_path, self._logger) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/agents/backtest_agent.py", line 59, in expand_rolling_options_into_config raise RuntimeError( RuntimeError: rolling_options expansion failed (ReadError: ); refusing to run with an empty option schedule

Implementation

Single-leg, cash-secured weekly OTM put-writing on BTC Deribit European options, trend-gated only, on a daily roll clock. Each week the framework resolves the historical Deribit BTC weekly put chain (targeting a ~25-delta OTM strike via a -6% moneyness offset) and rolls it; the strategy SELLS one put ~7 days to expiry and closes it ~24h before settlement. The ONLY gate is a price-only trend filter: it writes the put only when BTC spot is above its 50-day SMA, sitting out confirmed downtrends where put-writing has its worst tail. No IV-percentile window, so it trades every eligible week (~45-52/yr over the 365-day window) for a statistically reliable trade count. Cash-secured sizing (risk_frac 0.8), no leverage, 2 tuned parameters (put offset, sma_window).

Verification Results

CLEAN RESTART 2026-09-04 — this run's verdict history and learning records were removed and it was restarted from verification. Its previous abandonment came from the pipeline, not from the market: the Layer-2 harness mis-bound @staticmethod helpers (fixed), QA issued terminal performance verdicts on an unoptimized smoke test (removed — QA now judges correctness only), and sandbox timeouts came from backtest-slot starvation (fixed). The hypothesis and the strategy code are unchanged. Verify the code on its merits; performance is decided later by the full backtest and the optimizer.

Verification Results

None needed.

Verification Results

Layer-1 unbounded-append warning is a false positive; on_bar trims the deque to sma_window each bar.

Iteration History

Verification failed (Layer 3 — sandbox backtest): smoke test exceeded the 300s wall-clock limit. This almost always means per-bar work that scales with history — e.g. rescanning the full funding/supplementary series, or rebuilding a list and calling min()/sorted() inside calculate_signal()/on_bar() on every bar. Precompute sorted timestamp arrays ONCE in __init__ and use bisect, or cache lookups keyed by timestamp, so per-bar cost is O(log n) not O(n).

Iteration History

RuntimeError: rolling_options expansion failed (ReadError: ); refusing to run with an empty option schedule Traceback (most recent call last): File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 101, in map_httpcore_exceptions yield File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 394, in handle_async_request resp = await self._pool.handle_async_request(req) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/connection_pool.py", line 256, in handle_async_request raise exc from None File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/connection_pool.py", line 236, in handle_async_request response = await connection.handle_async_request( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/connection.py", line 103, in handle_async_request return await self._connection.handle_async_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 136, in handle_async_request raise exc File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 106, in handle_async_request ) = await self._receive_response_headers(**kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 177, in _receive_response_headers event = await self._receive_event(timeout=timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 217, in _receive_event data = await self._network_stream.read( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_backends/anyio.py", line 32, in read with map_exceptions(exc_map): File "/usr/lib/python3.12/contextlib.py", line 158, in __exit__ self.gen.throw(value) File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_exceptions.py", line 14, in map_exceptions raise to_exc(exc) from exc httpcore.ReadError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/opt/strategy-factory/src/agents/backtest_agent.py", line 49, in expand_rolling_options_into_config extra_i, extra_bt, sched = await expand_rolling_options(collector, spec, start, end) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/data/option_chain.py", line 242, in expand_rolling_options contracts = await discover_deribit_chain( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/data/option_chain.py", line 143, in discover_deribit_chain perp_bars = await collector.fetch_ohlcv(perp, start_ms, end_ms, "1D") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/data/collectors/deribit_collector.py", line 169, in fetch_ohlcv result = await self._get("/public/get_tradingview_chart_data", { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/data/collectors/deribit_collector.py", line 86, in _get response = await self._client.get(f"{DERIBIT_API_URL}{endpoint}", params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1768, in get return await self.request( ^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1540, in request return await self.send(request, auth=auth, follow_redirects=follow_redirects) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1629, in send response = await self._send_handling_auth( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1657, in _send_handling_auth response = await self._send_handling_redirects( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1694, in _send_handling_redirects response = await self._send_single_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1730, in _send_single_request response = await transport.handle_async_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 393, in handle_async_request with map_httpcore_exceptions(): File "/usr/lib/python3.12/contextlib.py", line 158, in __exit__ self.gen.throw(value) File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 118, in map_httpcore_exceptions raise mapped_exc(message) from exc httpx.ReadError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/opt/strategy-factory/src/agents/backtest_agent.py", line 184, in _run_backtest config = await self._maybe_expand_rolling_options(config, catalog_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/agents/backtest_agent.py", line 427, in _maybe_expand_rolling_options config = await expand_rolling_options_into_config(config, catalog_path, self._logger) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/agents/backtest_agent.py", line 59, in expand_rolling_options_into_config raise RuntimeError( RuntimeError: rolling_options expansion failed (ReadError: ); refusing to run with an empty option schedule

Abandon Reason

backtest_failed: RuntimeError: rolling_options expansion failed (ReadError: ); refusing to run with an empty option schedule Traceback (most recent call last): File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 101, in map_httpcore_exceptions yield File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 394, in handle_async_request resp = await self._pool.handle_async_request(req) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/connection_pool.py", line 256, in handle_async_request raise exc from None File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/connection_pool.py", line 236, in handle_async_request response = await connection.handle_async_request( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/connection.py", line 103, in handle_async_request return await self._connection.handle_async_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 136, in handle_async_request raise exc File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 106, in handle_async_request ) = await self._receive_response_headers(**kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 177, in _receive_response_headers event = await self._receive_event(timeout=timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_async/http11.py", line 217, in _receive_event data = await self._network_stream.read( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_backends/anyio.py", line 32, in read with map_exceptions(exc_map): File "/usr/lib/python3.12/contextlib.py", line 158, in __exit__ self.gen.throw(value) File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpcore/_exceptions.py", line 14, in map_exceptions raise to_exc(exc) from exc httpcore.ReadError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/opt/strategy-factory/src/agents/backtest_agent.py", line 49, in expand_rolling_options_into_config extra_i, extra_bt, sched = await expand_rolling_options(collector, spec, start, end) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/data/option_chain.py", line 242, in expand_rolling_options contracts = await discover_deribit_chain( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/data/option_chain.py", line 143, in discover_deribit_chain perp_bars = await collector.fetch_ohlcv(perp, start_ms, end_ms, "1D") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/data/collectors/deribit_collector.py", line 169, in fetch_ohlcv result = await self._get("/public/get_tradingview_chart_data", { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/data/collectors/deribit_collector.py", line 86, in _get response = await self._client.get(f"{DERIBIT_API_URL}{endpoint}", params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1768, in get return await self.request( ^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1540, in request return await self.send(request, auth=auth, follow_redirects=follow_redirects) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1629, in send response = await self._send_handling_auth( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1657, in _send_handling_auth response = await self._send_handling_redirects( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1694, in _send_handling_redirects response = await self._send_single_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_client.py", line 1730, in _send_single_request response = await transport.handle_async_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 393, in handle_async_request with map_httpcore_exceptions(): File "/usr/lib/python3.12/contextlib.py", line 158, in __exit__ self.gen.throw(value) File "/opt/strategy-factory/.venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 118, in map_httpcore_exceptions raise mapped_exc(message) from exc httpx.ReadError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/opt/strategy-factory/src/agents/backtest_agent.py", line 184, in _run_backtest config = await self._maybe_expand_rolling_options(config, catalog_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/agents/backtest_agent.py", line 427, in _maybe_expand_rolling_options config = await expand_rolling_options_into_config(config, catalog_path, self._logger) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/strategy-factory/src/agents/backtest_agent.py", line 59, in expand_rolling_options_into_config raise RuntimeError( RuntimeError: rolling_options expansion failed (ReadError: ); refusing to run with an empty option schedule
Strategy report

Backtest and paper results are hypothetical. Trading involves risk of loss.