TradingView has become one of the most widely used platforms among traders, thanks to its powerful charting tools, real-time data, and customizable features. At the heart of its functionality lies Pine Script, a domain-specific language designed for creating custom technical indicators, strategies, and alerts. With Pine Script, traders can implement, test, and refine their trading ideas directly on charts—without needing extensive programming experience.
In this guide, we’ll walk through how to build and backtest a practical Donchian Channels / Exponential Moving Average (EMA) strategy using Pine Script. This step-by-step tutorial is ideal for those looking to deepen their understanding of algorithmic trading logic and automated backtesting on TradingView.
Understanding the Strategy Logic
The core of our approach combines two well-known technical tools:
- Donchian Channels: A volatility-based indicator that identifies breakout levels by tracking the highest high and lowest low over a defined period.
- Exponential Moving Average (EMA): A trend-following tool that smooths price data, helping filter out noise and confirm market direction.
Trading Rules
Here’s how the strategy works:
- Entry (Long): On the daily timeframe, go long when the price crosses above the upper Donchian band and the current closing price is above the EMA.
- Exit (Sell): Close the long position immediately when the price drops below the lower Donchian band.
- Trade Execution: Orders are triggered intraday using stop orders placed one tick beyond the Donchian bands—no need to wait for candle closure.
This setup ensures timely entries during strong momentum moves while using the EMA as a directional filter to avoid false breakouts in downtrends.
👉 Discover how algorithmic strategies can enhance your trading performance
Setting Up the Strategy in TradingView
To begin, open TradingView and load your preferred asset—such as the BOTZ ETF—on a daily chart. Then follow these steps:
- Search for “ChannelBreakOutStrategy” in the Indicators panel.
- Apply it to your chart.
- Adjust the Length input to
3days (this defines the Donchian Channel window). - Set Order Size to 100% equity to enable full compounding in backtests.
While this built-in strategy gives us a starting point, it doesn’t include our EMA filter or allow precise control over trade logic. That’s where customizing Pine Script comes in.
Customizing Pine Script: Step-by-Step Guide
We’ll now modify the default strategy to include our enhanced rules.
Step 1: Access and Duplicate the Script
Click the “Source Code” button next to the applied strategy. This opens the Pine Editor. To preserve the original, duplicate the script and rename it—e.g., “DC/EMA Strategy.”
Now you’re ready to edit safely.
Step 2: Plotting Donchian Channels
Add visual clarity by plotting the upper and lower bands directly on the chart. Paste this code at the bottom of your script:
plot(upBound, color=color.green, linewidth=1, title="Upper Band")
plot(downBound, color=color.red, linewidth=1, title="Lower Band")This enhances visualization so you can see entry and exit zones clearly.
Step 3: Adding EMA Filter
Insert this snippet just after downBound = ta.lowest(low, length):
emaLength = input.int(title="EMA Length", minval=1, maxval=1000, defval=200)
emaFilter = ta.ema(close, emaLength)Then add the plotting line at the end:
plot(emaFilter, color=color.blue, linewidth=1, title="EMA Filter")You now have an adjustable EMA (default 200-period) that helps confirm trend bias before entering trades.
Step 4: Enabling Long-Only Mode
To restrict trading to long positions only, add:
longOnly = input.bool(title="Long Only", defval=true)This creates a toggle in the settings panel, giving you flexibility between long-only and dual-sided trading.
👉 Learn how professional traders automate their strategies
Rewriting Trade Logic in Pine Script
Replace the existing execution block (from if (not na(close[length])) onward) with this updated logic:
if (close > emaFilter)
if (not na(close[length]))
strategy.entry("ChBrkLE", strategy.long, stop=upBound + syminfo.mintick, comment="ChBrkLE")
if (strategy.position_size > 0)
strategy.exit("Exit Long", "ChBrkLE", stop=downBound - syminfo.mintick)
if (close < emaFilter) and (longOnly == false)
if (not na(close[length]))
strategy.entry("ChBrkSE", strategy.short, stop=downBound - syminfo.mintick, comment="ChBrkSE")
if (strategy.position_size < 0)
strategy.exit("Exit Short", "ChBrkSE", stop=upBound + syminfo.mintick)This code ensures:
- Long entries only occur above both the upper Donchian band and EMA.
- Exits trigger when price falls below the lower band.
- Short trades are disabled by default but can be enabled via settings.
Using syminfo.mintick ensures orders execute at the first possible price beyond the band—critical for accurate backtesting of intraday breakouts.
Final Pine Script Code
Here’s the complete script you can copy into Pine Editor:
//@version=5
strategy("DC/EMA Strategy", overlay=true)
length = input.int(title="Length", minval=1, maxval=1000, defval=3)
upBound = ta.highest(high, length)
downBound = ta.lowest(low, length)
emaLength = input.int(title="EMA Length", minval=1, maxval=1000, defval=200)
emaFilter = ta.ema(close, emaLength)
longOnly = input.bool(title="Long Only", defval=true)
if (close > emaFilter)
if (not na(close[length]))
strategy.entry("ChBrkLE", strategy.long, stop=upBound + syminfo.mintick, comment="ChBrkLE")
if (strategy.position_size > 0)
strategy.exit("Exit Long", "ChBrkLE", stop=downBound - syminfo.mintick)
if (close < emaFilter) and (longOnly == false)
if (not na(close[length]))
strategy.entry("ChBrkSE", strategy.short, stop=downBound - syminfo.mintick, comment="ChBrkSE")
if (strategy.position_size < 0)
strategy.exit("Exit Short", "ChBrkSE", stop=upBound + syminfo.mintick)
plot(upBound, color=color.green, linewidth=1, title="Upper Band")
plot(downBound, color=color.red, linewidth=1, title="Lower Band")
plot(emaFilter, color=color.blue, linewidth=1, title="EMA Filter")After saving and clicking “Add to Chart,” you’ll see all components visualized: green/red Donchian lines and blue EMA. Trade entries and exits will appear as markers on the chart.
Backtesting Results Overview
Once applied, use the Strategy Tester tab to review performance metrics like net profit, drawdowns, win rate, and equity curve. While detailed results are covered elsewhere, this framework allows you to:
- Optimize parameters (e.g., Donchian length from 2–20, EMA from 50–300).
- Test robustness across different assets and timeframes.
- Validate consistency under varying market conditions.
This kind of iterative testing is essential for developing robust trading strategies resistant to overfitting.
👉 See how top traders analyze backtest results for better decisions
Frequently Asked Questions
What is Pine Script used for?
Pine Script is used to create custom indicators, strategies, and alerts on TradingView. It enables traders to automate analysis and backtest rules-based systems directly on price charts.
Can I backtest breakout strategies accurately with Pine Script?
Yes. By using strategy.entry() with stop orders and syminfo.mintick, you can simulate real-time breakout execution with high precision—critical for accurate backtesting.
How do I add multiple filters to a Pine Script strategy?
You can stack conditions using logical operators (and, or). In this example, we combined Donchian breakout signals with an EMA trend filter to improve signal quality.
Why use a 200-period EMA?
The 200-day EMA is widely regarded as a benchmark for long-term trend direction. It helps traders stay aligned with major market momentum and avoid counter-trend trades.
Can I make this strategy short-selling enabled?
Yes. The script includes conditional logic for short entries when longOnly is disabled. Just toggle it off in the input settings.
Is coding knowledge required to use Pine Script?
Basic scripting helps, but TradingView provides templates and documentation that let beginners modify strategies with simple copy-paste edits—just like in this tutorial.
By mastering Pine Script fundamentals like plotting indicators, setting dynamic inputs, and defining entry/exit logic, you gain full control over your trading systems. Whether you're testing ideas or refining proven strategies, this skillset is invaluable in today’s algorithmic trading landscape.