OPEN-SOURCE SCRIPT
Updated

Crypto Strategy: Pattern Retest + EMA/RSI

//version=5
strategy("Crypto Strategy: Pattern Retest + EMA/RSI", overlay=true, margin_long=100, margin_short=100)

// ~~~~~~~~~~~~~~ INPUTS ~~~~~~~~~~~~~~
emaLength = input.int(50, "EMA Length")
rsiLength = input.int(14, "RSI Length")
overbought = input(70, "RSI Overbought Level")
oversold = input(30, "RSI Oversold Level")
patternLookback = input.int(20, "Pattern Lookback")

// ~~~~~~~~~~~~~~ INDICATORS ~~~~~~~~~~~~~~
ema = ta.ema(close, emaLength)
rsi = ta.rsi(close, rsiLength)

// ============== BULLISH PATTERN (Double Bottom Retest) ==============
var float necklineBullish = na
var bool breakoutBullish = false

// Detect Double Bottom
swingLow = ta.lowest(low, 5)
swingLowPrev = ta.lowest(low, 5)[5]
swingHighBetween = ta.highest(high, 5)
isDoubleBottom = swingLow >= swingLowPrev * 0.99 and swingLow <= swingLowPrev * 1.01 and swingHighBetween > swingLow

// Update neckline on pattern detection
if isDoubleBottom
necklineBullish := swingHighBetween
breakoutBullish := false

// Breakout and Retest Logic
breakoutBullish := close > necklineBullish and not breakoutBullish
retestBullish = breakoutBullish and low <= necklineBullish and close > necklineBullish and rsi < oversold

// ============== BEARISH PATTERN (Double Top Retest) ==============
var float necklineBearish = na
var bool breakoutBearish = false

// Detect Double Top
swingHigh = ta.highest(high, 5)
swingHighPrev = ta.highest(high, 5)[5]
swingLowBetween = ta.lowest(low, 5)
isDoubleTop = swingHigh <= swingHighPrev * 1.01 and swingHigh >= swingHighPrev * 0.99 and swingLowBetween < swingHigh

// Update neckline on pattern detection
if isDoubleTop
necklineBearish := swingLowBetween
breakoutBearish := false

// Breakdown and Retest Logic
breakoutBearish := close < necklineBearish and not breakoutBearish
retestBearish = breakoutBearish and high >= necklineBearish and close < necklineBearish and rsi > overbought

// ~~~~~~~~~~~~~~ BUY/SELL CONDITIONS ~~~~~~~~~~~~~~
// BUY Signal: Bullish retest OR EMA crossover + RSI oversold
buyCondition = retestBullish or (ta.crossover(close, ema) and rsi < oversold)

// SELL Signal: Bearish retest OR EMA crossunder + RSI overbought
sellCondition = retestBearish or (ta.crossunder(close, ema) and rsi > overbought)

// ~~~~~~~~~~~~~~ EXECUTE ORDERS ~~~~~~~~~~~~~~
if (buyCondition)
strategy.entry("BUY", strategy.long)
alert("BUY Signal: Price Retest + RSI/EMA Confirmation", alert.freq_once_per_bar)

if (sellCondition)
strategy.close("BUY")
alert("SELL Signal: Price Retest + RSI/EMA Confirmation", alert.freq_once_per_bar)

// ~~~~~~~~~~~~~~ PLOTTING ~~~~~~~~~~~~~~
plot(ema, "EMA", color=color.blue)
plot(necklineBullish, "Bullish Neckline", color=color.green, linewidth=2)
plot(necklineBearish, "Bearish Neckline", color=color.red, linewidth=2)

// Plot BUY/SELL labels on chart
plotshape(buyCondition, title="BUY", location=location.belowbar, color=color.green, style=shape.labelup, text="BUY")
plotshape(sellCondition, title="SELL", location=location.abovebar, color=color.red, style=shape.labeldown, text="SELL")
Release Notes
//version=5
strategy("Crypto Buy/Sell Strategy: Patterns + Trendlines", overlay=true, initial_capital=1000, default_qty_type=strategy.percent_of_equity, default_qty_value=90)

// ~~~~~~~~~~~~~~~~~~~~ INPUTS ~~~~~~~~~~~~~~~~~~~~
rsiLength = input.int(14, "RSI Length")
overbought = input(70, "RSI Overbought")
oversold = input(30, "RSI Oversold")
trendlineLength = input.int(20, "Trendline Length")

// ~~~~~~~~~~~~~~~~~~~~ INDICATORS ~~~~~~~~~~~~~~~~~~~~
rsi = ta.rsi(close, rsiLength)

// ==================== PATTERNS ====================
// 1. Double Bottom (Bullish)
var float bullishNeckline = na
var bool bullishBreakout = false
swingLow1 = ta.lowest(low, 5)
swingLow2 = ta.lowest(low, 5)[5]
swingHighBetween = ta.highest(high, 5)
isDoubleBottom = swingLow1 >= swingLow2 * 0.99 and swingLow1 <= swingLow2 * 1.01 and swingHighBetween > swingLow1
if isDoubleBottom
bullishNeckline := swingHighBetween
bullishBreakout := false
bullishBreakout := close > bullishNeckline and not bullishBreakout
retestBullish = bullishBreakout and low <= bullishNeckline and close > bullishNeckline and rsi < oversold

// 2. Double Top (Bearish)
var float bearishNeckline = na
var bool bearishBreakout = false
swingHigh1 = ta.highest(high, 5)
swingHigh2 = ta.highest(high, 5)[5]
swingLowBetween = ta.lowest(low, 5)
isDoubleTop = swingHigh1 <= swingHigh2 * 1.01 and swingHigh1 >= swingHigh2 * 0.99 and swingLowBetween < swingHigh1
if isDoubleTop
bearishNeckline := swingLowBetween
bearishBreakout := false
bearishBreakout := close < bearishNeckline and not bearishBreakout
retestBearish = bearishBreakout and high >= bearishNeckline and close < bearishNeckline and rsi > overbought

// 3. Trendline Breakout/Breakdown
upTrendline = ta.lowest(low, trendlineLength)
downTrendline = ta.highest(high, trendlineLength)
breakout = close > upTrendline and volume > ta.sma(volume, 20)
breakdown = close < downTrendline and volume > ta.sma(volume, 20)

// ~~~~~~~~~~~~~~~~~~~~ BUY/SELL SIGNALS ~~~~~~~~~~~~~~~~~~~~
buyCondition = retestBullish or breakout
sellCondition = retestBearish or breakdown

// ~~~~~~~~~~~~~~~~~~~~ PLOT "BUY" AND "SELL" TEXT ON CHART ~~~~~~~~~~~~~~~~~~~~
plotshape(buyCondition, title="BUY", location=location.belowbar, color=color.green, style=shape.labelup, text="BUY", textcolor=color.white, size=size.normal)
plotshape(sellCondition, title="SELL", location=location.abovebar, color=color.red, style=shape.labeldown, text="SELL", textcolor=color.white, size=size.normal)

// ~~~~~~~~~~~~~~~~~~~~ EXECUTE ORDERS ~~~~~~~~~~~~~~~~~~~~
if (buyCondition)
strategy.entry("BUY", strategy.long)
if (sellCondition)
strategy.close("BUY")

// ~~~~~~~~~~~~~~~~~~~~ PLOT TRENDLINES & NECKLINES ~~~~~~~~~~~~~~~~~~~~
plot(upTrendline, "Up Trendline", color=color.blue)
plot(downTrendline, "Down Trendline", color=color.orange)
plot(bullishNeckline, "Bullish Neckline", color=color.green, linewidth=2)
plot(bearishNeckline, "Bearish Neckline", color=color.red, linewidth=2)

Disclaimer