Profitable Pair Correlation Divergence Scanner v6
Source: Dev.to
Overview
This strategy identifies divergence opportunities between two correlated assets using a combination of Z‑Score spread analysis, trend confirmation, RSI & MACD momentum checks, correlation filters, and ATR‑based stop‑loss/take‑profit management. It’s optimized for positive P&L and realistic trade execution.
Key Features
- Pair Divergence Detection – Measures the spread between the returns of two assets and normalizes it with a Z‑Score.
- Trend Alignment – Uses fast and slow EMAs to ensure trades are taken in the direction of the prevailing trend.
- Momentum Confirmation – RSI and MACD filters confirm bullish or bearish momentum.
- Correlation Filter – Requires a minimum correlation between the pair (default > 0.5) to reduce false signals.
- Risk Management – ATR‑based stop‑loss and take‑profit levels, with a reward‑to‑risk ratio greater than 1.
- Exit Conditions – Positions are closed when the Z‑Score re‑enters a tight “normalization” zone.
How It Works
Calculate Returns
ret1 = ta.roc(s1, 1)
ret2 = ta.roc(s2, 1)
Z‑Score Spread
spread = ret1 - ret2
spreadMA = ta.sma(spread, zLen)
spreadSD = ta.stdev(spread, zLen)
zScore = (spread - spreadMA) / spreadSD
Trend Filter
emaFast = ta.ema(s1, fastEMA)
emaSlow = ta.ema(s1, slowEMA)
trendLong = emaFast > emaSlow
trendShort = emaFast 50
rsiShort = rsiVal signalLine
macdShort = macdLine 0.5
Trade Execution
longCond = zScore entryZ and trendShort and rsiShort and macdShort and corrFilter
if (longCond)
strategy.entry("LongSpread", strategy.long)
if (shortCond)
strategy.entry("ShortSpread", strategy.short)
Exit Logic
exitLong = math.abs(zScore) emaSlow
trendShort = emaFast 50
rsiShort = rsiVal signalLine
macdShort = macdLine 0.5
// ATR FOR SL/TP
atrVal = ta.atr(atrLen)
sl = atrVal * atrMult
tp = atrVal * atrMult * 2 // reward > risk
// ENTRY CONDITIONS
longCond = zScore entryZ and trendShort and rsiShort and macdShort and corrFilter
exitLong = math.abs(zScore) < exitZ
exitShort = math.abs(zScore) < exitZ
// EXECUTION
if (longCond)
strategy.entry("LongSpread", strategy.long)
if (shortCond)
strategy.entry("ShortSpread", strategy.short)
if (exitLong)
strategy.close("LongSpread")
if (exitShort)
strategy.close("ShortSpread")
// ATR‑BASED EXIT
strategy.exit("Exit Long", "LongSpread", stop=close - sl, limit=close + tp)
strategy.exit("Exit Short", "ShortSpread", stop=close + sl, limit=close - tp)
// PLOTTING
plot(zScore, "Z-Score", color=color.new(color.blue, 0))
hline( entryZ, "Upper Entry", color=color.red)
hline(-entryZ, "Lower Entry", color=color.green)
hline( exitZ, "Exit Zone", color=color.gray)
hline(-exitZ, "Exit Zone", color=color.gray)
plot(emaFast, "Fast EMA", color=color.new(color.purple, 0))
plot(emaSlow, "Slow EMA", color=color.new(color.orange, 0))
plot(corrVal, "Correlation", color=color.new(color.teal, 40))