For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Add a backtest-bbmr-report command that samples multiple non-overlapping historical windows, runs a fixed Bollinger Band mean-reversion strategy on each window, and outputs one single-page HTML report with client-side segment switching.
Architecture: Extend the current report pipeline instead of replacing it. Add a dedicated BBMR sampler/runner module that fetches one public candle pool, derives deterministic sampled windows with warm-up context, runs one backtest per sampled window, and feeds a single wrapper HTML that switches per-segment journals and plots client-side.
Tech Stack: Python 3.11+, backtesting.py, pandas, existing OKX public candle client, existing CLI test harness, plain HTML/CSS/JS
/home/lxy/okx-codex-trader/okx_codex_trader/cli.py
backtest-bbmr-report CLI command and dispatch/home/lxy/okx-codex-trader/okx_codex_trader/bbmr_report.py
/home/lxy/okx-codex-trader/okx_codex_trader/report.py
/home/lxy/okx-codex-trader/tests/test_cli.py
/home/lxy/okx-codex-trader/tests/test_bbmr_report.py
/home/lxy/okx-codex-trader/README.md
backtest-bbmr-reportFiles:
/home/lxy/okx-codex-trader/tests/test_cli.pyModify: /home/lxy/okx-codex-trader/okx_codex_trader/cli.py
[ ] Step 1: Write the failing CLI test
def test_backtest_bbmr_report_generates_single_page_report(capsys, tmp_path):
main, client, bbmr_calls = build_main_with_stubs()
output_file = tmp_path / "bbmr.html"
exit_code = main(
[
"backtest-bbmr-report",
"--symbol",
"BTC-USDT-SWAP",
"--bar",
"3m",
"--history-limit",
"5000",
"--leverage",
"2",
"--segments",
"8",
"--window-size",
"300",
"--output-file",
str(output_file),
]
)
assert exit_code == 0
assert client.get_candles_called_with == ("BTC-USDT-SWAP", "3m", 5000)
assert bbmr_calls[0]["segments"] == 8
assert bbmr_calls[0]["window_size"] == 300
Run: cd /home/lxy/okx-codex-trader && .venv/bin/python -m pytest tests/test_cli.py -k bbmr -q
Expected: FAIL because backtest-bbmr-report is not implemented
bbmr_report = subparsers.add_parser("backtest-bbmr-report")
bbmr_report.add_argument("--symbol", choices=SUPPORTED_SYMBOLS, required=True)
bbmr_report.add_argument("--bar", required=True)
bbmr_report.add_argument("--history-limit", type=int, required=True)
bbmr_report.add_argument("--leverage", type=int, choices=(1, 2, 3), required=True)
bbmr_report.add_argument("--segments", type=int, required=True)
bbmr_report.add_argument("--window-size", type=int, required=True)
bbmr_report.add_argument("--output-file", required=True)
if args.command == "backtest-bbmr-report":
candles = client.get_candles(args.symbol, args.bar, args.history_limit)
report = bbmr_report_fn(
candles=candles,
leverage=args.leverage,
output_file=Path(args.output_file),
symbol=args.symbol,
bar=args.bar,
segments=args.segments,
window_size=args.window_size,
)
print(_dump_json(report))
return 0
def main_factory(
*,
...,
report_fn: Callable = generate_backtest_report,
bbmr_report_fn: Callable = generate_bbmr_sampled_report,
):
...
def build_main_with_stubs(...):
...
def fake_bbmr_report(...):
...
main = main_factory(..., bbmr_report_fn=fake_bbmr_report)
Run: cd /home/lxy/okx-codex-trader && .venv/bin/python -m pytest tests/test_cli.py -k bbmr -q
Expected: PASS
git -C /home/lxy/okx-codex-trader add okx_codex_trader/cli.py tests/test_cli.py
git -C /home/lxy/okx-codex-trader commit -m "feat: add bbmr report cli contract"
Files:
/home/lxy/okx-codex-trader/tests/test_bbmr_report.pyCreate: /home/lxy/okx-codex-trader/okx_codex_trader/bbmr_report.py
[ ] Step 1: Write the failing sampler tests
def test_sample_segments_rejects_history_pool_too_small():
candles = build_candles(count=1000)
with pytest.raises(ValueError, match="history pool is too small"):
sample_segments(candles=candles, segments=8, window_size=300, warmup_bars=69, seed=7)
def test_sample_segments_returns_non_overlapping_ranges():
candles = build_candles(count=5000)
sampled = sample_segments(candles=candles, segments=4, window_size=300, warmup_bars=69, seed=7)
ranges = [(segment.context_start, segment.report_end) for segment in sampled]
assert len(ranges) == len(set(ranges))
for left, right in zip(ranges, ranges[1:]):
assert left[1] < right[0] or right[1] < left[0]
def test_sample_segments_is_deterministic_for_same_seed():
candles = build_candles(count=5000)
a = sample_segments(candles=candles, segments=4, window_size=300, warmup_bars=69, seed=7)
b = sample_segments(candles=candles, segments=4, window_size=300, warmup_bars=69, seed=7)
assert a == b
def test_generate_bbmr_sampled_report_rejects_insufficient_history_pool(tmp_path):
candles = build_candles(count=1000)
with pytest.raises(ValueError, match="history pool is too small"):
generate_bbmr_sampled_report(
candles=candles,
leverage=2,
output_file=tmp_path / "bbmr.html",
symbol="BTC-USDT-SWAP",
bar="3m",
segments=8,
window_size=300,
)
Run: cd /home/lxy/okx-codex-trader && .venv/bin/python -m pytest tests/test_bbmr_report.py -k sample_segments -q
Expected: FAIL because sampler functions do not exist
WARMUP_BARS = 69
SAMPLER_SEED = 7
def sample_segments(...):
required = segments * (window_size + warmup_bars)
if len(candles) < required:
raise ValueError("history pool is too small")
...
Run: cd /home/lxy/okx-codex-trader && .venv/bin/python -m pytest tests/test_bbmr_report.py -k sample_segments -q
Expected: PASS
git -C /home/lxy/okx-codex-trader add okx_codex_trader/bbmr_report.py tests/test_bbmr_report.py
git -C /home/lxy/okx-codex-trader commit -m "feat: add deterministic bbmr segment sampler"
Files:
/home/lxy/okx-codex-trader/tests/test_bbmr_report.pyModify: /home/lxy/okx-codex-trader/okx_codex_trader/bbmr_report.py
[ ] Step 1: Write the failing strategy tests
def test_run_bbmr_segment_produces_long_trade_on_lower_band_reversion():
candles = build_lower_band_reversion_fixture()
result = run_bbmr_segment(candles=candles, leverage=2)
assert result.trade_count == 1
assert result.trades[0]["side"] == "Long"
def test_run_bbmr_segment_produces_short_trade_on_upper_band_reversion():
candles = build_upper_band_reversion_fixture()
result = run_bbmr_segment(candles=candles, leverage=2)
assert result.trade_count == 1
assert result.trades[0]["side"] == "Short"
def test_run_bbmr_segment_marks_open_position_to_market_but_keeps_journal_realized_only():
candles = build_open_tail_fixture()
result = run_bbmr_segment(candles=candles, leverage=2)
assert result.trade_count == 0
assert result.trades == []
assert result.total_return != 0
Run: cd /home/lxy/okx-codex-trader && .venv/bin/python -m pytest tests/test_bbmr_report.py -k run_bbmr_segment -q
Expected: FAIL because BBMR runner does not exist
Implement fixed rules from the spec and lock them with explicit tests:
20/2(upper-lower)/middle50 completed bandwidth valuesAdd failing tests for:
def test_run_bbmr_segment_excludes_warmup_from_reported_trade_times():
...
def test_run_bbmr_segment_does_not_generate_entry_from_final_reported_candle():
...
def test_run_bbmr_segment_stop_loss_takes_precedence_over_close_exit():
...
def test_run_bbmr_segment_does_not_reverse_on_exit_bar():
...
Run: cd /home/lxy/okx-codex-trader && .venv/bin/python -m pytest tests/test_bbmr_report.py -k run_bbmr_segment -q
Expected: PASS
git -C /home/lxy/okx-codex-trader add okx_codex_trader/bbmr_report.py tests/test_bbmr_report.py
git -C /home/lxy/okx-codex-trader commit -m "feat: add bbmr segment backtest rules"
Files:
/home/lxy/okx-codex-trader/tests/test_bbmr_report.py/home/lxy/okx-codex-trader/okx_codex_trader/report.pyModify: /home/lxy/okx-codex-trader/okx_codex_trader/bbmr_report.py
[ ] Step 1: Write the failing HTML wrapper tests
def test_render_bbmr_sampled_report_contains_summary_and_segment_switcher():
html = render_bbmr_sampled_report(...)
assert "history limit" in html.lower()
assert "segment count" in html.lower()
assert "window size" in html.lower()
assert "average return across segments" in html.lower()
assert "median return across segments" in html.lower()
assert "best segment return" in html.lower()
assert "worst segment return" in html.lower()
assert "segment-selector" in html
assert "data-segment-index=\"0\"" in html
def test_render_bbmr_sampled_report_contains_trade_journal_and_plot_reference():
html = render_bbmr_sampled_report(...)
assert "Trade Journal" in html
assert "/files/segment-0.plot.html" in html
assert "sampled range start time" in html.lower()
assert "sampled range end time" in html.lower()
assert "trade count" in html.lower()
assert "total return" in html.lower()
assert "win rate" in html.lower()
assert "max drawdown" in html.lower()
Run: cd /home/lxy/okx-codex-trader && .venv/bin/python -m pytest tests/test_bbmr_report.py -k render_bbmr -q
Expected: FAIL because sampled report wrapper does not exist
Render:
client-side JS to switch visible panel and iframe
[ ] Step 4: Run tests to verify they pass
Run: cd /home/lxy/okx-codex-trader && .venv/bin/python -m pytest tests/test_bbmr_report.py -k render_bbmr -q
Expected: PASS
git -C /home/lxy/okx-codex-trader add okx_codex_trader/report.py okx_codex_trader/bbmr_report.py tests/test_bbmr_report.py
git -C /home/lxy/okx-codex-trader commit -m "feat: add bbmr sampled single-page html report"
Files:
/home/lxy/okx-codex-trader/tests/test_cli.py/home/lxy/okx-codex-trader/tests/test_bbmr_report.py/home/lxy/okx-codex-trader/okx_codex_trader/bbmr_report.pyModify: /home/lxy/okx-codex-trader/README.md
[ ] Step 1: Write the failing end-to-end generator test
def test_generate_bbmr_sampled_report_writes_wrapper_and_plot_files(tmp_path):
candles = build_candles(count=5000)
result = generate_bbmr_sampled_report(
candles=candles,
leverage=2,
output_file=tmp_path / "bbmr.html",
symbol="BTC-USDT-SWAP",
bar="3m",
segments=3,
window_size=300,
)
assert Path(result["report_file"]).exists()
assert result["segment_count"] == 3
assert (tmp_path / "bbmr.segment-0.plot.html").exists()
Run: cd /home/lxy/okx-codex-trader && .venv/bin/python -m pytest tests/test_bbmr_report.py -k generate_bbmr -q
Expected: FAIL because the assembled generator does not exist
Implement:
README command example
[ ] Step 4: Run focused tests to verify they pass
Run: cd /home/lxy/okx-codex-trader && .venv/bin/python -m pytest tests/test_cli.py tests/test_bbmr_report.py -q
Expected: PASS
git -C /home/lxy/okx-codex-trader add README.md okx_codex_trader/bbmr_report.py okx_codex_trader/report.py tests/test_bbmr_report.py tests/test_cli.py
git -C /home/lxy/okx-codex-trader commit -m "feat: add sampled bbmr backtest report"
Files:
Verify only: /home/lxy/okx-codex-trader
[ ] Step 1: Run full automated tests
Run: cd /home/lxy/okx-codex-trader && .venv/bin/python -m pytest -q
Expected: PASS
Run:
cd /home/lxy/okx-codex-trader
.venv/bin/python -m okx_codex_trader.cli backtest-bbmr-report \
--symbol BTC-USDT-SWAP \
--bar 3m \
--history-limit 5000 \
--leverage 2 \
--segments 8 \
--window-size 300 \
--output-file bbmr-sampled-report.html
Expected: one wrapper HTML plus segment plot files written next to it
git -C /home/lxy/okx-codex-trader add README.md okx_codex_trader/cli.py okx_codex_trader/bbmr_report.py okx_codex_trader/report.py tests/test_bbmr_report.py tests/test_cli.py
git -C /home/lxy/okx-codex-trader commit -m "feat: ship sampled bbmr report flow"