Case study · Backtest
🗓 Backtest period: 2018-01-01..2023-01-01
Spec ID: spec-sector-momentum-rotation-etf-top50-1767027941 · Generated: 2026-09-24 23:38 UTC
Cluster: Momentum · Sub Cluster: Sector Etf Relative Strength Rotation
Each month, the strategy ranks eligible sector ETFs by their relative strength versus SPY over 3, 6, and 12 months and targets the top three at equal weights.
Sector leadership can persist as earnings expectations, investor flows, and macroeconomic conditions adjust gradually. Comparing sector ETFs with SPY seeks to capture that persistence while emphasizing relative leadership rather than broad-market momentum.
[code omitted from public view] The specification requests a one-day signal lag and next-open trading; the recorded cost and execution convention instead identifies daily-bar market-on-close fills. The fill timing should be reconciled against the blotter before treating either description as the implemented entry rule.
| Param | Value | Notes |
|---|---|---|
| Universe | Top 50 ETFs by capitalization | Further restricted to sector ETFs using provider metadata or name matching; allowed sectors: GICS 11. |
| Backtest window | 2018-01-01..2023-01-01 | Daily bars. |
| Benchmark and lookbacks | SPY; 63, 126, 252 trading days | Relative strength defined as total_return(etf,LB)/total_return(benchmark,LB); composite is the mean z-score across lookbacks. |
| Eligibility | 252 days of price history; no missing lookback; 63-day average volume ≥250,000 shares | Applied to candidate selection. |
| Rebalance and selection | Monthly, first trading day; top 3 | Equal weight; minimum 3 positions; cash_if_fewer_candidates=false. |
| Exposure and risk | Gross leverage 1.0; maximum position weight 0.4; maximum sector allocation 0.4 | No stop loss or volatility targeting. |
| Requested trade execution | next_open; signal lag 1 day; turnover threshold 0.0 |
Differs from the recorded platform-default MOC execution; verify actual fills. |
| Commissions | $0.0040 per share, minimum $1.00 per order, capped at 1.00% of trade value | Charged per fill by the results module; all metrics are net of them |
| Slippage | 0 bps — not applied | Not an omission — MOC (market-on-close) fills at the auction print the backtest uses |
| Costs not modelled | short borrow fees / rebate, margin financing on leverage, market impact, exchange/regulatory/clearing pass-through fees, taxes | Excluded deliberately, not unknown |
| # | Concern | Status |
|---|---|---|
| 1 | ETF universe and sector classifications are available as of each historical selection date. | ⚠ Confirm point-in-time screening and metadata; the stated top-50 universe alone does not establish this. |
| 2 | Return, z-score, and volume inputs use only observations available when the signal is formed. | ⚠ Verify timestamped inputs and the specified signal lag in the executed run. |
| 3 | Closing-price or closing-volume signals do not fill at that same day's open. | ⚠ Reconcile the requested next-open rule with recorded MOC fills; any same-day-open fill using that day's close, high, low, or volume is a violation. |
| 4 | Candidates satisfy the full-history and missing-data rules at each rebalance. | ⚠ Verify eligibility is evaluated historically rather than using future availability. |
| 5 | Commissions are reflected in performance. | ✓ commissions $0.0040/share (min $1.00/order); slippage 0 bps — not applied |
The backtest returned 50.68% in total, with a 0.71 Sharpe ratio and a −22.45% maximum drawdown across 24 trades. Reported performance is net of charged commissions. These results suggest positive historical performance but leave meaningful drawdown and implementation-fidelity questions.
Recomputed here from the run's stored daily returns, because every annualized figure in the table above is derived from the LENGTH of that array (years = n / 252). Only total return and max drawdown do not depend on the row count, so when the recomputed and stored values differ by a common factor, those two are the numbers to trust.
| Check | From the run's own returns | Note |
|---|---|---|
| Daily-return rows | 1,259 | 1.00x the 1,260 trading days in 2018-01-01..2023-01-01 |
| Distinct dates | 1,259 | one row per date |
| Date span | 2018-01-02 .. 2022-12-30 | |
| Sum of daily returns | 50.68% | matches the reported total return |
| Sharpe from these rows | 0.71 | stored 0.71 |
| Volatility from these rows | 14.28% | stored 14.28% |
| Max drawdown from these rows | -22.45% | stored -22.45% |
| Lowest the book stood | -4.46% | low-water mark, in units of starting capital |
| CAGR from these rows | 8.55% | stored 8.55% |
| Metric | Value |
|---|---|
| Total Return | 50.68% |
| Sharpe | 0.71 |
| Sortino | 0.86 |
| Calmar | 0.38 |
| Max Drawdown | -22.45% |
| Volatility | 14.28% |
| Beta vs SPY | 0.54 |
| Win Rate | 66.67% |
| Profit Factor | 4.84 |
| Total Trades | 24 |
| Symbols | 50 (AGG, BIL, BIV, BND, BNDX, BSV, DIA, EFA, GLD, IEFA, +40 more) |