Markets have a general trend of moving up in the long run, even with the occasional dips and bear markets. These dips, or pullbacks, aren’t just challenges; they're opportunities. If you can spot them and act at the right time, there's profit to be made.
One effective way to spot these pullbacks is by using a combination of two tried-and-true indicators: the Relative Strength Index (RSI) and the Exponential Moving Average (EMA). The RSI helps identify when a market is oversold, suggesting it might be due for a rebound. Meanwhile, if the price is above the EMA, it indicates the overall trend is still bullish.
That's where our RSI Pullback Strategy comes in. It merges the strengths of the RSI and EMA, providing a clear method to identify and capitalize on market pullbacks. We're happy to share this strategy with our readers at no cost, hoping it can be a valuable tool in your trading toolkit.
Disclaimer: The RSI Pullback Strategy presented here is purely for educational purposes. It showcases how one might structure and code a strategy in Pine Script. This isn't an investment advice or a recommendation for trading. Before applying any strategy in real-time trading, it's crucial to conduct thorough backtesting, optimization, and paper trading. Our goal is to offer a deep dive into Pine Script strategy creation, serving as a blueprint for enthusiasts wishing to design their unique strategies.
Strategy Approach
The RSI Pullback Strategy integrates the Relative Strength Index (RSI) with the Exponential Moving Average (EMA) of close prices, aiming to detect and act on potential buy signals during market retracements.
Strategy Settings
Timeframe: This strategy was developed for 2-hour NQ futures bars.
RSI Setup: The RSI, with a period of 11, identifies oversold conditions. A buy signal triggers when the RSI value dips below 25, suggesting a pullback within a bullish trend.
EMA Setup: The strategy employs a 290-period Exponential Moving Average (EMA) of the close prices to ensure we're in line with the broader trend.
Entry Conditions:
1. The RSI value should fall below the threshold of 25, indicating potential oversold conditions amidst an uptrend.
2. The closing price must be positioned above its 290-period EMA, confirming the overarching bullish trend.
Exit Conditions:
1. The RSI value exceeds the threshold of 79, suggesting overbought conditions.
2. A stop loss set at 1.4% below the entry price gets triggered.
3. The price reaches a predetermined take profit level, set at 3.5% above the entry price.
At the heart of the RSI Pullback Strategy is its ability to detect moments when the market temporarily retracts within an ongoing bullish trend. Such pullbacks, as identified by the RSI dipping below its entry threshold, represent potential entry opportunities. The strategy's objective is to seize these moments, speculating that the market will soon resume its upward trajectory. The inclusion of EMA ensures that traders act in harmony with the prevailing trend, adding an extra layer of security.
Backtest Results
We've backtested the RSI Pullback Long Strategy for the last 4 years, and the results are shown below. By trading 1 NQ contract at all times, the strategy registered 38 long trades since September 2019 and delivered the total Net Profit of $117K while keeping the max drawdown at $13K. The win rate is 64% and the Profit Factor is almost 2.8.
Strategy Performance: Last 4 Years
Below is the Pine Script code for the RSI Pullback strategy:
//@version=5
strategy("RSI Pullback Strategy NQ 2hr", overlay=true, calc_on_order_fills = false, calc_on_every_tick = false, process_orders_on_close = true)
// Parameters
rsiPeriod = input.int(11, title="RSI Period")
rsiSource = close
rsiEntryValue = input.float(25, title="RSI Value for Entry", step=0.1)
rsiExitValue = input.float(79, title="RSI Value for Exit", step=0.1)
emaPeriod = input.int(290, title="EMA Period")
stopLossPercent = input.float(1.4, title="Stop Loss (%)") / 100 // Convert percentage to a decimal.
takeProfitPercent = input.float(3.5, title="Take Profit (%)") / 100 // Convert percentage to a decimal.
// Calculate RSI and EMA
rsiValue = ta.rsi(rsiSource, rsiPeriod)
longEma = ta.ema(rsiSource, emaPeriod)
// Plot the EMA
plot(longEma, title="EMA", color=color.blue, linewidth=1)
// Entry conditions for long trades
longCondition = rsiValue < rsiEntryValue and close > longEma
// Exit conditions for long trades
rsiExitCondition = rsiValue > rsiExitValue
// Tracking the entry price, setting stop loss, and take profit
var float entryPrice = na
if (longCondition)
entryPrice := close
stopLossPrice = entryPrice * (1 - stopLossPercent)
takeProfitPrice = entryPrice * (1 + takeProfitPercent)
stopLossHit = close < stopLossPrice
takeProfitHit = close > takeProfitPrice
// Execute trades using the if statement
if (longCondition)
strategy.entry("Long", strategy.long)
// Distinct exit conditions
if (rsiExitCondition)
strategy.close("Long", comment="RSI Exit")
if (stopLossHit)
strategy.close("Long", comment="Stop Loss Hit")
if (takeProfitHit)
strategy.close("Long", comment="Take Profit Hit")
Comments