Pine Script strategy backtest: test an idea, step by step
A strategy script runs your rule over years of past candles in seconds. That's a fast way to learn about an idea. It's also a fast way to fool yourself, unless you know the traps.
Indicator or strategy?
Pine Script has 2 main kinds of script:
- An indicator draws things on the chart.
- A strategy also places pretend trades on past candles, then reports how they went.
That report is a Backtesting result: your rule, tested on history. TradingView shows it in a panel usually called the Strategy Tester. Look for it under the chart once a strategy is added.
New to Pine Script? Start with Pine Script for beginners first.
Read this before the code
Every number a strategy shows is hypothetical. No real orders were placed, and the past won't repeat exactly.
A backtest can tell you a rule is probably broken. It can't tell you a rule will work. Treat it as a first filter, not a verdict.
A full strategy, with a stop and a target
This one buys when a fast average crosses above a slow one. It puts the stop under the lowest low of the last 10 candles, aims for 2 times the risk, and sizes each trade so the stop costs about 1% of the test account:
//@version=6
strategy("Average cross test", overlay=true, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.05, slippage=2)
fastLen = input.int(10, "Fast average", minval=1)
slowLen = input.int(30, "Slow average", minval=2)
fast = ta.sma(close, fastLen)
slow = ta.sma(close, slowLen)
plot(fast, "Fast", color=color.orange)
plot(slow, "Slow", color=color.blue)
recentLow = ta.lowest(low, 10)
crossUp = ta.crossover(fast, slow)
var float stopPrice = na
var float targetPrice = na
if crossUp and strategy.position_size == 0
risk = close - recentLow
size = math.floor(strategy.equity * 0.01 / risk)
if risk > 0 and size >= 1
stopPrice := recentLow
targetPrice := close + 2 * risk
strategy.entry("Long", strategy.long, qty=size)
strategy.exit("Exit", from_entry="Long", stop=stopPrice, limit=targetPrice)
Every line, in plain words
- Line 1 says this is Pine Script version 6.
- Line 2 says this is a strategy, not an indicator. It starts the test with 10,000 in account money, charges 0.05% a trade in costs, and assumes 2 ticks of Slippage (getting filled a little worse than the price you wanted).
- Lines 3 and 4 make both average lengths settings. See Pine Script inputs.
- Lines 5 and 6 work out the 2 averages.
- Lines 7 and 8 draw them.
- Line 9 finds the lowest low of the last 10 candles. That's where the stop goes.
- Line 10 is true when the fast average crosses above the slow one.
- Lines 11 and 12 make 2 boxes that remember the stop and target. var means "keep this value from candle to candle".
- Line 13 says: on a cross, and only if we're not already in a trade…
- Line 14 works out the risk per share: the distance from the close down to the stop.
- Line 15 works out the size: 1% of the account, divided by the risk per share, rounded down to whole shares.
- Line 16 skips the trade if the distance is zero or less, or the size rounds down to nothing.
- Lines 17 and 18 save the stop and a target 2 times the risk away.
- Line 19 buys that many shares.
- Line 20 sets the exit: get out at the stop or the target, whichever comes first.
Why size from the stop?
Line 15 is the heart of good risk control. The stop comes from the chart, and the size comes from the math. A wide stop means a small size. A tight stop means a bigger one. Either way, a loss costs about the same slice of the account.
It's the same math as our position size calculator. More in how much to risk per trade.
One honest note: the order fills at the next candle's open, not this candle's close. So the real risk on each test trade is a little different from the plan. And if a size costs more than the test account holds, TradingView may shrink or close the trade.
How to run it
- Paste the script into the Pine Editor, on a computer.
- Save it and click Add to chart.
- Pretend trades appear as small arrows on the chart.
- Open the Strategy Tester panel. Look for tabs like an overview, a performance summary and a list of trades.
Reading the results without fooling yourself
The report shows many numbers. The useful ones for a first look:
- Number of trades. Under about 100, chance plays a big part. Test more history or more charts.
- Biggest drop from a high point. Often called max Drawdown. Could you sit through that with real money?
- Average win vs average loss. Together with how often it wins, this gives Expectancy: the average result per trade. Try the expectancy calculator.
- The list of trades. Check 10 of them on the chart. Do they match what you meant?
Think in units of risk, not money. If a trade risked 1 unit and hit the target, that's +2 units. Hit the stop, that's −1 unit. Losses are part of every rule. A math example, not a promise.
Trap 1: look-ahead (using the future)
A test can accidentally use information that wasn't known yet. Then the results look far better than anything you could have done live.
Common ways it sneaks in:
- Bigger-timeframe data pulled the wrong way. See Pine Script request.security for the safe pattern.
- Indicators that repaint, meaning they change past values after new candles arrive.
- Acting on the close at the close. The script above fills at the next open, which is honest. Settings that fill on the same candle's close can be too kind.
If results look too smooth to be true, check for look-ahead first.
Trap 2: overfitting
Inputs make it easy to try 10, 12, 14… until the result looks great. That setting fits the past. It isn't likely to fit the future the same way.
Ways to keep yourself honest:
- Pick settings for a reason before you test.
- Test on one stretch of history. Then check the same settings on a different stretch you didn't look at.
- Test on other charts too. A rule that only works on one chart, with one exact number, is fragile.
- Keep the costs and slippage in. Taking them out makes every test look better.
The tester can't test you. It doesn't feel nervous, skip trades or move stops. That's why the next step is replay, by hand.
The next step: replay by hand
A strategy script tests the rule. Bar replay tests you following it, with the future hidden. Log every trade in a trading journal. Full method: how to backtest a trading strategy. Then paper trade, then go small.
Learning from a real script
Our course includes the full source code of the StructureX chart tool. You could build your own strategy test on top of it. It's source code, not a ready-made trading bot.
Common mistakes
- Trusting a test with 15 trades. Too few to say much.
- Tuning until it looks perfect. That's overfitting.
- No stop in the code. Without strategy.exit, a test trade can sit through any drop.
Questions
Are TradingView strategy tester results reliable?
They're hypothetical. They can't include every real cost, fill or emotion, and look-ahead or overfitting can make them look better than live trading would. Use them as a first filter.
What is the difference between strategy.entry and strategy.exit?
strategy.entry opens a trade. strategy.exit sets how it closes, for example at a stop price and a target price.
How do I add a stop loss to a Pine Script strategy?
Use strategy.exit with stop= set to your stop price and from_entry= set to the name of your entry.
How many trades do I need in a backtest?
More is better. Many traders aim for at least 100, across different charts and time periods, before reading much into the results.
Want the next step? We'll walk you through it.
Four free lessons by email, one every few days — each with a 10-minute exercise on a real chart.
Send Me the Free Lessons 4 short emails · No spam · Unsubscribe anytimeOr see the whole method, step by step:
See What’s Inside the Course Try everything free first. Decide when you're ready. · Open the free chart tool (works in the TradingView phone app)One chart idea a day, in plain English. Follow along: