Methodology
Every backtest published on this site rests on assumptions. This page states them once so individual posts don't have to re-explain them — and so you can judge the numbers rather than take them on faith.
Data sources
Daily bars come from Yahoo Finance via yfinance, always split- and
dividend-adjusted. Intraday bars (15-minute and 30-minute) come from Interactive
Brokers historical data, cached locally in SQLite. IBKR caps 15-minute history at
one year, which is why intraday backtests here cover twelve months and daily
backtests cover five years.
Earnings dates are sourced from yfinance with a Finnhub fallback, cached and refreshed monthly. Where a strategy skips trades around earnings, that filter is only as good as the cache.
Position sizing
Size is derived from risk, not from a fixed share count:
qty = floor((capital × risk_pct) / (entry − stop)) Risk per trade is 1% on daily strategies and 0.5% on intraday. "1R" means one unit of that risk. A trade that closes at +2R returned twice what it risked — it does not mean the position doubled.
How the metrics are defined
| Metric | Definition | What it hides |
|---|---|---|
| Win rate | Trades closed above break-even ÷ all closed trades. | Nothing about size. A 30% win rate with fat winners beats 70% with fat losers. |
| Profit factor | Gross profit ÷ absolute gross loss. | Path. A 1.5× PF can arrive smoothly or via one enormous winner. |
| Average R | Mean of per-trade R-multiples — expectancy per trade. | Tail dependence. The mean can rest on a handful of trades. |
| Max drawdown | Largest peak-to-trough decline of the closed-trade equity curve. | Open-position drawdown. Intraday pain is worse than this number. |
| Sharpe | Annualised daily-return Sharpe. | Concurrency. See the warning below — this metric is no longer reported for uncapped simulations. |
What is excluded from every backtest
Results published here are gross. None of the following are modelled:
- Commission and exchange fees. At a few thousand round trips, even $2 each removes five figures.
- Bid-ask spread. Entries and exits fill at bar prices, not at the offer.
- Slippage. Stops fill exactly at the stop level, which real markets do not honour on gaps.
- Partial fills. Every order is assumed filled in full.
- Borrow cost and availability on short trades.
- Overnight gap risk beyond what the price series itself shows.
Treat every headline figure as an optimistic upper bound. The gap between gross backtest and net live result is not a rounding error.
Known limitations
- Regime bias. Backtests covering 2025–2026 ran through a market that was above its 200-day average nearly throughout. Long-biased strategies have not been tested against a sustained downtrend.
- Survivorship. Index-constituent universes are current membership lists, so names that dropped out are missing.
- Fat tails. In several strategies the top 5% of trades carry roughly half the gross profit. Any rule that arbitrarily drops signals — a position cap, an outage, a day away from the desk — may remove the tail that made the result.
- Parameter selection. Where parameters were chosen after seeing results on the same dataset, that is in-sample fitting. Posts flag it where it applies; walk-forward validation is not yet standard here.
Corrections
When a published number turns out to be wrong or misleading, the original post is annotated in place rather than quietly edited, and the correction is explained in the follow-up. Findings that get weaker on a larger sample are reported as such. A research log that only ever improves is not a research log.