Algorithmic trading has shifted dramatically. Retail traders no longer rely solely on static indicators; instead, they build multi-layered confluence systems that filter out market noise. One of the most robust setups combines trend identification using Exponential Moving Averages (EMAs) with momentum validation through Relative Strength Index (RSI) divergence.
This guide details how to build, test, and optimize an automated trading strategy using Pine Script v5 for TradingView, incorporating strict risk management parameters.
1. The Core Strategy Logic
To minimize false breakouts, a robust algorithmic model requires two distinct conditions to align before triggering a position:
-
Trend Filter (EMA 20 & EMA 50): Price action must remain strictly above the 20-period and 50-period Exponential Moving Averages for long entries, ensuring the strategy only trades in the direction of the intermediate trend.
-
Momentum Confirmation (RSI Divergence): Even in an uptrend, buying local tops leads to drawdowns. By scanning for bullish RSI divergence—where the price makes a lower low while the RSI indicator makes a higher low—the script identifies hidden accumulation phases.
2. Pine Script v5 Implementation
Below is a clean, optimized Pine Script v5 strategy framework that you can paste directly into your TradingView Pine Editor. This script executes long entries upon detecting a bullish RSI divergence backed by an EMA trend filter.
//@version=5
strategy(“EMA Trend + RSI Divergence Strategy”, overlay=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=10)
// — Inputs —
emaFastLen = input.int(20, title=”Fast EMA Length”)
emaSlowLen = input.int(50, title=”Slow EMA Length”)
rsiLen = input.int(14, title=”RSI Length”)
rsiOversold = input.int(30, title=”RSI Oversold Level”)
riskRewardRatio = input.float(2.0, title=”Risk-to-Reward Ratio”)
stopLossPct = input.float(1.5, title=”Stop Loss (%)”)
// — Indicator Calculations —
fastEMA = ta.ema(close, emaFastLen)
slowEMA = ta.ema(close, emaSlowLen)
srcRsi = close
rsiValue = ta.rsi(srcRsi, rsiLen)
// Plotting Moving Averages to Chart
plot(fastEMA, color=color.blue, title=”Fast EMA”)
plot(slowEMA, color=color.orange, title=”Slow EMA”)
// — Trend Conditions —
isUptrend = fastEMA > slowEMA and close > slowEMA
// — RSI Divergence Detection Logic —
// Scanning for a simple swing low divergence setup
priceLow = ta.low(5) == ta.lowest(low, 5)
rsiLow = rsiValue < rsiOversold bullishCondition = priceLow and rsiLow and isUptrend // — Execution & Risk Management — var float longStopPrice = na var float longTargetPrice = na if (bullishCondition and strategy.position_size == 0) longStopPrice := close * (1 – (stopLossPct / 100)) longTargetPrice := close + ((close – longStopPrice) * riskRewardRatio) strategy.entry(“Long Entry”, strategy.long) // Exit orders based on calculated Risk-to-Reward targets if (strategy.position_size > 0)
strategy.exit(“Exit Long”, “Long Entry”, stop=longStopPrice, limit=longTargetPrice)
3. Backtesting Performance Metrics and Optimization
When backtesting this strategy across 1-hour (H1) and 4-hour (H4) timeframes on major liquid assets like Bitcoin or tech equities, pay close attention to three critical risk benchmarks:
| Performance Metric | Target Benchmark | Why It Matters |
| Profit Factor | $> 1.50$ | Ensures gross profits comfortably outstrip gross losses including spread overhead. |
| Max Drawdown | $< 15\%$ | Keeps equity curves stable during prolonged sideways consolidation phases. |
| Win Rate vs. RR | $40\% \text{ at } 1:2\text{ RR}$ | A lower win rate is completely sustainable if your risk-to-reward ratio reliably yields positive expectancy. |
4. Common Pitfalls to Avoid in Live Deployment
-
Over-Optimization (Curve Fitting): Do not adjust the EMA lengths or RSI thresholds to match historical chart data perfectly. Doing so destroys forward-looking predictive validity.
-
Ignoring Execution Slippage: Automated backtests assume zero slippage on market orders. Always build a buffer of 0.1% to 0.2% per trade into your manual assumptions to account for real-world order execution delays.


