2026-04-17-bbmr-sampled-report-design.md 7.2 KB

BBMR Sampled Report Design

Goal

Add a new real backtest report path for short-horizon Bollinger Band mean reversion.

The feature must:

  • fetch one larger pool of recent public OKX candles
  • randomly sample multiple non-overlapping time windows from that pool
  • run the same Bollinger mean reversion strategy on each sampled window
  • output one HTML report file with a segment switcher instead of many separate report pages

Non-Goals

This feature does not:

  • replace the existing 10/20 SMA backtest path
  • replace the existing backtest-report command
  • add fees or slippage
  • add TP/SL trailing logic
  • auto-optimize parameters
  • support spot symbols

Command

Add one new CLI command:

  • backtest-bbmr-report

Required arguments:

  • --symbol with value BTC-USDT-SWAP or ETH-USDT-SWAP
  • --bar for candle timeframe
  • --history-limit for the total candle pool
  • --leverage in 1..3
  • --segments for the number of sampled windows
  • --window-size for bars per sampled window
  • --output-file for the final single-page HTML report

Optional arguments are not added in v1. Parameters are fixed except where the user explicitly asked for configurability.

Strategy Contract

This v1 strategy is fixed:

  • strategy family: Bollinger Band mean reversion
  • indicator length: 20
  • standard deviation multiplier: 2
  • bandwidth filter lookback: 50
  • stop loss: 0.5% relative to entry
  • initial equity per sampled segment: 10_000 USDT
  • position sizing: use 100% of current segment equity as isolated margin for each trade
  • leverage: CLI input, limited to integer 1..3
  • fees: 0
  • slippage: 0

Entry Rules

  • if candle close is below lower band, enter long at next candle open
  • if candle close is above upper band, enter short at next candle open
  • entry signals are only evaluated on reported candles that still have a next reported candle inside the same sampled window
  • the final reported candle of a sampled window cannot generate a new entry

Filter Rule

  • Bollinger bandwidth is defined as (upper_band - lower_band) / middle_band
  • only allow entries when current Bollinger bandwidth is less than or equal to the rolling median of the previous 50 completed bandwidth values
  • the current bar is excluded from the median window

Warm-Up Rule

  • each sampled report window must have 69 warm-up candles immediately before its first reported candle
  • warm-up candles are used only to compute:
    • Bollinger bands with length = 20
    • previous 50 completed bandwidth values for the filter
  • warm-up candles are never shown in the sampled range labels, trade journal, or per-segment metrics
  • sampling must reserve these 69 warm-up candles per segment
  • sampled segments must be non-overlapping after including their warm-up context

Exit Rules

  • mean-reversion exits are close-based:
    • if a long position is open and candle close is greater than or equal to the middle band, exit at next candle open
    • if a short position is open and candle close is less than or equal to the middle band, exit at next candle open
  • mean-reversion exit signals are only evaluated on reported candles that still have a next reported candle inside the same sampled window
  • the final reported candle of a sampled window cannot generate a new mean-reversion exit
  • stop-loss exits are intrabar:
    • if a long position is open and a later candle low is less than or equal to the stop price, exit on that bar at the stop price
    • if a short position is open and a later candle high is greater than or equal to the stop price, exit on that bar at the stop price
  • if both a stop-loss condition and a mean-reversion exit condition would occur on the same bar, stop-loss takes precedence
  • same-bar sequencing is fixed:
    • first evaluate intrabar stop-loss for an already open position
    • if stop-loss exits the position on that bar, the bar is exhausted and no new entry or reversal may be generated from that same bar
    • if no stop-loss exit occurs, evaluate close-based mean-reversion exit for an already open position
    • if a close-based exit signal is generated on that bar, do not also generate an opposite-side entry from that same bar
    • entry signals are only allowed when the strategy is flat at the close of that bar and no exit occurred on that bar

End-Of-Window Rule

  • keep current project behavior
  • do not force-close an open trade at the final bar
  • report realized trades only in the trade journal
  • if a position remains open at the end of a sampled window:
    • per-segment trade_count and journal rows remain realized-only
    • per-segment total return and max drawdown use final-bar-close mark-to-market equity
    • aggregate return statistics use those per-segment mark-to-market totals

Sampling Contract

Sampling must avoid concentrating on one market regime.

Rules:

  • fetch history-limit candles first
  • sample exactly segments non-overlapping windows
  • each sampled window must have exactly window-size candles
  • windows are chosen randomly from the fetched pool
  • sampling must fail if history-limit is too small to fit the requested non-overlapping windows plus 69 warm-up candles per segment

The random process must be reproducible:

  • use a deterministic RNG seed
  • expose the chosen sampled ranges in the output report

Output Shape

The command outputs one HTML file and supporting plot files.

Main HTML

The main report page is a single journal-first page with:

  • summary header
  • strategy description
  • sampling summary
  • segment switcher
  • current segment metrics
  • current segment trade journal
  • current segment interactive plot

Segment Switching

The single HTML file must allow switching between sampled windows without opening separate top-level pages.

Implementation rule for v1:

  • generate one plot file per sampled window if needed
  • keep one main wrapper HTML
  • the wrapper switches the visible segment content client-side

Summary Metrics

Top-level page must include:

  • symbol
  • timeframe
  • history limit
  • segment count
  • window size
  • strategy parameters
  • aggregate trade count
  • average return across segments
  • median return across segments
  • best segment return
  • worst segment return

Per-Segment Metrics

Each segment view must show:

  • sampled range start time
  • sampled range end time
  • trade count
  • total return
  • win rate
  • max drawdown

Data Model

Add report-side models for:

  • sampled segment definition
    • start index
    • end index
    • start timestamp
    • end timestamp
  • sampled segment result
    • summary metrics
    • trade journal rows
    • plot filename

These models are local to report generation and do not affect existing paper state files.

Error Handling

Allowed failures:

  • history-limit too small for requested segments * window-size
  • invalid sampling result
  • public OKX market data failure
  • report generation failure

No fallback logic.

Testing

Add tests for:

  • CLI parses backtest-bbmr-report
  • report generator rejects insufficient history pool
  • sampler returns non-overlapping windows
  • sampler is deterministic for the same seed
  • report HTML contains aggregate summary and segment switcher
  • report HTML contains per-segment trade journal and plot reference
  • strategy generates long and short trades on controlled fixtures