A backtest is just a question: "If I had run these exact rules on past data, what would have happened?" The hard part isn't running it — your charting platform does that in seconds. The hard part is trusting the answer. Many backtests look great because they're quietly cheating: peeking at data that didn't exist yet, repainting signals after the fact, or testing a strategy that's secretly different from the one you'll trade. This page walks through how to backtest a trading strategy honestly — the steps, the traps, and the specific errors that turn a "promising" curve into a fantasy. Nothing here predicts the future, and no backtest can: past results are illustrative only, and trading carries real risk of loss. The goal is narrower and more useful — to make sure the test you ran is the test you think you ran.
Backtesting replays your rules over historical price data, bar by bar, and records what each rule would have done. Done right, it follows a simple discipline:
The mechanics are easy. The integrity is where most backtests quietly fall apart — which is the rest of this page.
Ask an AI chatbot to "write a backtest for a moving-average crossover" and you'll usually get code that runs. Running and being correct are different things. Here are the failures we see most often in AI-generated and hand-written strategies — the ones that can inflate a backtest without anyone noticing:
The ForexCodes Strategy Validator is built specifically to surface these. It takes a plain-English or AI-generated strategy, converts it to validated Pine Script v6, and flags look-ahead bias, repainting, and intent mismatches before you read too much into the curve. It doesn't promise a profitable strategy — no tool honestly can. It checks that the strategy you test is the strategy you meant, tested fairly.
Here's a minimal RSI strategy in valid Pine Script v6. Note the structure that keeps it honest: signals are computed on confirmed values, orders are placed through the strategy engine (so market fills are simulated on the next bar by default), and costs are declared up front. This is for education and illustration only — it is not a recommendation, and it makes no claim about results.
//@version=6 strategy("RSI Example (illustrative only)", overlay=false, commission_type=strategy.commission.percent, commission_value=0.04, slippage=2)
length = input.int(14, "RSI Length") oversold = input.int(30, "Oversold") overbought = input.int(70, "Overbought")
r = ta.rsi(close, length)
longCond = ta.crossover(r, oversold) exitCond = ta.crossunder(r, overbought)
if longCond strategy.entry("Long", strategy.long) if exitCond strategy.close("Long")
plot(r, "RSI") hline(oversold, "Oversold") hline(overbought, "Overbought")
Why this is harder to fool yourself with: ta.crossover and ta.crossunder evaluate on the current bar's values, and strategy.entry/strategy.close route through the backtest engine so market orders are filled on the next bar rather than at an impossible same-bar price. commission_value and slippage are set, so the simulated curve isn't free of friction. (For a stricter live-only test, you can also confirm signals on closed bars — for instance by gating entries on barstate.isconfirmed.) What this code does not do is tell you the strategy is any good — that judgment is yours, and the backtest is only one input. Treat the equity curve as a description of one historical path, not a forecast.
It's easy to keep tweaking a strategy until the backtest looks great — and that's exactly the danger. The more you adjust parameters to fit past data, the more you may be describing history rather than discovering anything that holds up later. This is called overfitting, and a gorgeous curve is often its first symptom, not a green light.
Validation changes the question you're asking. Instead of "how good does this look?" it asks "is this result even real?" A strategy that secretly looks ahead, repaints, or tests different logic than you intended will tend to look better than it should. Catch those issues first, and whatever the curve shows is at least an honest reflection of the rules — still not a prediction, but no longer a lie.
A few habits that keep you honest, beyond the validator: test across different market periods (trending, ranging, volatile) rather than one flattering stretch; hold out data you didn't use while building the rules; and always keep costs in the model. None of this guarantees anything — markets change and any approach can lose money. It simply means that when you do trade, you're acting on a test you can actually trust.
No. A backtest describes how rules behaved on past data — nothing more. It cannot predict future results, market conditions change, and any strategy can lose money. A clean, honest backtest is useful because it tells you the truth about the past, not because it promises anything about the future. Treat it as one input to your own judgment, never as a forecast.
Look-ahead bias is when a backtest uses information that wasn't actually available at the moment a decision was made — for example, acting on a bar's closing price as if you could have traded earlier in that same bar, or using a higher-timeframe value before that bar had closed. It can make results look far better than anything achievable live, because the test effectively had access to the future. The ForexCodes Strategy Validator is built to flag this class of error specifically.
Chatbots optimize for code that runs, not code that's correct. The output can contain repainting signals, subtle look-ahead bias, or an intent mismatch — logic that quietly differs from what you described. It may execute cleanly and produce an impressive curve for the wrong or unrealistic strategy. Running a generated strategy through validation helps catch these issues before you base any decision on the numbers.
Educational & software only — not financial advice. Trading involves substantial risk of loss.