Method
How it works.
Every number in this app is computed by hand-written pandas and numpy — no backtesting library, no TA library. This page explains what those computations do and, more usefully, where they can mislead you.
How a backtest runs
Daily closing prices are fetched for your ticker and date range. The strategy turns those prices into a position for each day: +1 long, −1 short, 0 flat. That position is multiplied by the next day's return, transaction costs are deducted in proportion to how much the position changed, and the results are compounded into an equity curve starting at 1.0.
Everything else — drawdown, Sharpe, the monthly heatmap — is derived from that one series of daily net returns.
Why results here are lower than elsewhere
A signal computed from Monday's close cannot be traded at Monday's close — you only know it once the day is over. Every strategy here shifts its signal forward one bar, so a signal derived from Monday is acted on at Tuesday's price.
Skipping that shift is the single most common way a backtest manufactures returns that do not exist. It is also invisible: the equity curve simply looks better. If a result here is worse than one you got elsewhere from the same idea, this is the first thing to check.
The same principle governs stop-losses (evaluated at the close, so a bar that gaps through your stop costs you the whole gap) and volatility sizing (measured on a trailing window ending yesterday).
The three strategies
Momentum
MACD
Bollinger
Each has its own page with the rule written out, its parameters and how it did on data it was never tuned on: Momentum, MACD, Bollinger.
Stops and position sizing
Stop-loss / take-profit
Volatility targeting
target ÷ trailing volatility, capped by max leverage. Smaller in turbulent markets, larger in calm ones. It usually lowers return and lowers drawdown more — whether that is an improvement depends on what you are optimising.Portfolios
Portfolio mode runs the same strategy on 2–10 tickers and combines the legs. Each leg is a complete backtest with its own signals, stops, sizing and costs.
Only days on which every holding traded are used. That matters: if one name listed recently, the whole portfolio is measured over its shorter history, and the app tells you how many bars that cost. Filling in the missing days instead would invent flat returns and quietly understate the portfolio's risk.
The diversification ratio is the weighted average volatility of the legs divided by the volatility of the portfolio. 1.0 means your holdings move as one and you gained nothing by splitting between them.
Validation — the part that matters
Any strategy can be tuned until its backtest looks good. Two checks here are designed to find out whether that has happened.
Longer explanations, with examples: walk-forward validation, overfitting and the permutation test.
Walk-forward
Permutation test
Deflated Sharpe ratio
Probability of backtest overfitting
Whole-grid test
Confidence intervals
Reading the metrics
Sharpe ratio
Max drawdown
Calmar ratio
Profit factor
Win rate
What a backtest cannot tell you
Survivorship bias. Price history only exists for companies that still trade. Every ticker you can type here is one that survived; the ones that went to zero are absent from the data and from your results.
Idealised execution. Every trade fills at the closing price at a flat cost. Real slippage widens exactly when you least want it to — in fast markets, and when you are trading size.
One sample. A single backtest is one draw from a distribution of possible histories. It is not a forecast, and this app is not financial advice.