OPEN-SOURCE SCRIPT
Candle Suite PRO – Engulf + Pin + Regime Filters + Trigger

//version=5
indicator("Candle Suite PRO – Engulf + Pin + Regime Filters + Trigger", overlay=true, max_labels_count=500)
//===================== Inputs =====================
grpPtn = "Patterns"
useEngulf = input.bool(true, "Enable Engulfing", group=grpPtn)
usePin = input.bool(true, "Enable Pin Bar", group=grpPtn)
pinRatio = input.float(2.0, "PinBar shadow >= body ×", group=grpPtn, step=0.1, minval=1)
minBodyP = input.float(0.15, "Min Body% of Range (0~1)", group=grpPtn, step=0.01, minval=0, maxval=1)
coolBars = input.int(3, "Cooldown bars", group=grpPtn, minval=0)
grpReg = "Regime Filters"
useHTF = input.bool(true, "Use HTF EMA50 Filter", group=grpReg)
htfTF = input.timeframe("60", "HTF timeframe", group=grpReg) // 5m/15m → 60 권장
useADX = input.bool(true, "Use ADX Trend Filter", group=grpReg)
adxLen = input.int(14, "ADX Length", group=grpReg, minval=5)
adxMin = input.int(18, "ADX Min Threshold", group=grpReg, minval=5)
useVOL = input.bool(true, "Use Volume Filter (> SMA×k)",group=grpReg)
volMult = input.float(1.10, "k for Volume", group=grpReg, step=0.05)
emaPinchPc = input.float(0.15, "No-Trade if |EMA20-50| < %", group=grpReg, step=0.05)/100.0
maxDistATR = input.float(1.5, "No-Trade if |Close-EMA20| > ATR×", group=grpReg, step=0.1)
useVWAP = input.bool(true, "Require close above/below VWAP", group=grpReg)
//===================== Helpers ====================
ema20 = ta.ema(close, 20)
ema50 = ta.ema(close, 50)
atr14 = ta.atr(14)
vwap = ta.vwap(hlc3)
rng = high - low
body = math.abs(close - open)
upper = high - math.max(open, close)
lower = math.min(open, close) - low
bull = close > open
bear = close < open
bodyOK = rng > 0 ? (body / rng) >= minBodyP : false
//===================== Patterns ===================
prevOpen = open[1]
prevClose = close[1]
prevBull = prevClose > prevOpen
prevBear = prevClose < prevOpen
bullEngulf_raw = useEngulf and prevBear and bull and (open <= prevClose) and (close >= prevOpen) and bodyOK
bearEngulf_raw = useEngulf and prevBull and bear and (open >= prevClose) and (close <= prevOpen) and bodyOK
bullPin_raw = usePin and (lower >= pinRatio * body) and (upper <= body) and bodyOK // Hammer
bearPin_raw = usePin and (upper >= pinRatio * body) and (lower <= body) and bodyOK // Shooting Star
//================= Regime & No-trade ===============
// HTF trend (EMA50 on higher TF)
emaHTF50 = request.security(syminfo.tickerid, htfTF, ta.ema(close, 50))
htfLong = not useHTF or close > emaHTF50
htfShort = not useHTF or close < emaHTF50
// ADX (manual, version-safe)
len = adxLen
upMove = high - high[1]
downMove = low[1] - low
plusDM = (upMove > downMove and upMove > 0) ? upMove : 0.0
minusDM = (downMove > upMove and downMove > 0) ? downMove : 0.0
trur = ta.rma(ta.tr(true), len)
plusDI = 100 * ta.rma(plusDM, len) / trur
minusDI = 100 * ta.rma(minusDM, len) / trur
dx = 100 * math.abs(plusDI - minusDI) / math.max(plusDI + minusDI, 1e-10)
adxVal = ta.rma(dx, len)
trendOK = not useADX or adxVal >= adxMin
// Volume
volOK = not useVOL or (volume >= ta.sma(volume, 20) * volMult)
// Alignment & slope
slopeUp = ema20 > ema20[3]
slopeDown = ema20 < ema20[3]
alignLong = ema20 > ema50 and slopeUp
alignShort = ema20 < ema50 and slopeDown
// Chop / distance / VWAP
pinch = math.abs(ema20 - ema50) / close < emaPinchPc
tooFar = math.abs(close - ema20) / atr14 > maxDistATR
vwapOKL = not useVWAP or close > vwap
vwapOKS = not useVWAP or close < vwap
//================= Final Setups ====================
longSetup_raw = bullEngulf_raw or bullPin_raw
shortSetup_raw = bearEngulf_raw or bearPin_raw
longSetup = longSetup_raw and alignLong and htfLong and trendOK and volOK and not pinch and not tooFar and vwapOKL
shortSetup = shortSetup_raw and alignShort and htfShort and trendOK and volOK and not pinch and not tooFar and vwapOKS
// Trigger: 다음 봉이 전봉의 고/저 돌파 + 종가 확인
longTrig = longSetup[1] and high > high[1] and close > ema20
shortTrig = shortSetup[1] and low < low[1] and close < ema20
// Cooldown & final signals
var int lastLong = na
var int lastShort = na
canLong = na(lastLong) or (bar_index - lastLong > coolBars)
canShort = na(lastShort) or (bar_index - lastShort > coolBars)
finalLong = longTrig and canLong
finalShort = shortTrig and canShort
if finalLong
lastLong := bar_index
if finalShort
lastShort := bar_index
//==================== Plots ========================
plot(ema20, "EMA 20", color=color.new(color.orange, 0))
plot(ema50, "EMA 50", color=color.new(color.blue, 0))
plot(useVWAP ? vwap : na, "VWAP", color=color.new(color.purple, 0))
plotshape(finalLong, title="LONG ▶", style=shape.labelup, location=location.belowbar, text="Long▶", color=color.new(color.blue, 0), size=size.tiny)
plotshape(finalShort, title="SHORT ▶", style=shape.labeldown, location=location.abovebar, text="Short▶", color=color.new(color.red, 0), size=size.tiny)
// Alerts
alertcondition(finalLong, "LONG ▶", "Long trigger")
alertcondition(finalShort, "SHORT ▶", "Short trigger")
// 시각적 노트레이드 힌트
bgcolor(pinch ? color.new(color.gray, 92) : na)
indicator("Candle Suite PRO – Engulf + Pin + Regime Filters + Trigger", overlay=true, max_labels_count=500)
//===================== Inputs =====================
grpPtn = "Patterns"
useEngulf = input.bool(true, "Enable Engulfing", group=grpPtn)
usePin = input.bool(true, "Enable Pin Bar", group=grpPtn)
pinRatio = input.float(2.0, "PinBar shadow >= body ×", group=grpPtn, step=0.1, minval=1)
minBodyP = input.float(0.15, "Min Body% of Range (0~1)", group=grpPtn, step=0.01, minval=0, maxval=1)
coolBars = input.int(3, "Cooldown bars", group=grpPtn, minval=0)
grpReg = "Regime Filters"
useHTF = input.bool(true, "Use HTF EMA50 Filter", group=grpReg)
htfTF = input.timeframe("60", "HTF timeframe", group=grpReg) // 5m/15m → 60 권장
useADX = input.bool(true, "Use ADX Trend Filter", group=grpReg)
adxLen = input.int(14, "ADX Length", group=grpReg, minval=5)
adxMin = input.int(18, "ADX Min Threshold", group=grpReg, minval=5)
useVOL = input.bool(true, "Use Volume Filter (> SMA×k)",group=grpReg)
volMult = input.float(1.10, "k for Volume", group=grpReg, step=0.05)
emaPinchPc = input.float(0.15, "No-Trade if |EMA20-50| < %", group=grpReg, step=0.05)/100.0
maxDistATR = input.float(1.5, "No-Trade if |Close-EMA20| > ATR×", group=grpReg, step=0.1)
useVWAP = input.bool(true, "Require close above/below VWAP", group=grpReg)
//===================== Helpers ====================
ema20 = ta.ema(close, 20)
ema50 = ta.ema(close, 50)
atr14 = ta.atr(14)
vwap = ta.vwap(hlc3)
rng = high - low
body = math.abs(close - open)
upper = high - math.max(open, close)
lower = math.min(open, close) - low
bull = close > open
bear = close < open
bodyOK = rng > 0 ? (body / rng) >= minBodyP : false
//===================== Patterns ===================
prevOpen = open[1]
prevClose = close[1]
prevBull = prevClose > prevOpen
prevBear = prevClose < prevOpen
bullEngulf_raw = useEngulf and prevBear and bull and (open <= prevClose) and (close >= prevOpen) and bodyOK
bearEngulf_raw = useEngulf and prevBull and bear and (open >= prevClose) and (close <= prevOpen) and bodyOK
bullPin_raw = usePin and (lower >= pinRatio * body) and (upper <= body) and bodyOK // Hammer
bearPin_raw = usePin and (upper >= pinRatio * body) and (lower <= body) and bodyOK // Shooting Star
//================= Regime & No-trade ===============
// HTF trend (EMA50 on higher TF)
emaHTF50 = request.security(syminfo.tickerid, htfTF, ta.ema(close, 50))
htfLong = not useHTF or close > emaHTF50
htfShort = not useHTF or close < emaHTF50
// ADX (manual, version-safe)
len = adxLen
upMove = high - high[1]
downMove = low[1] - low
plusDM = (upMove > downMove and upMove > 0) ? upMove : 0.0
minusDM = (downMove > upMove and downMove > 0) ? downMove : 0.0
trur = ta.rma(ta.tr(true), len)
plusDI = 100 * ta.rma(plusDM, len) / trur
minusDI = 100 * ta.rma(minusDM, len) / trur
dx = 100 * math.abs(plusDI - minusDI) / math.max(plusDI + minusDI, 1e-10)
adxVal = ta.rma(dx, len)
trendOK = not useADX or adxVal >= adxMin
// Volume
volOK = not useVOL or (volume >= ta.sma(volume, 20) * volMult)
// Alignment & slope
slopeUp = ema20 > ema20[3]
slopeDown = ema20 < ema20[3]
alignLong = ema20 > ema50 and slopeUp
alignShort = ema20 < ema50 and slopeDown
// Chop / distance / VWAP
pinch = math.abs(ema20 - ema50) / close < emaPinchPc
tooFar = math.abs(close - ema20) / atr14 > maxDistATR
vwapOKL = not useVWAP or close > vwap
vwapOKS = not useVWAP or close < vwap
//================= Final Setups ====================
longSetup_raw = bullEngulf_raw or bullPin_raw
shortSetup_raw = bearEngulf_raw or bearPin_raw
longSetup = longSetup_raw and alignLong and htfLong and trendOK and volOK and not pinch and not tooFar and vwapOKL
shortSetup = shortSetup_raw and alignShort and htfShort and trendOK and volOK and not pinch and not tooFar and vwapOKS
// Trigger: 다음 봉이 전봉의 고/저 돌파 + 종가 확인
longTrig = longSetup[1] and high > high[1] and close > ema20
shortTrig = shortSetup[1] and low < low[1] and close < ema20
// Cooldown & final signals
var int lastLong = na
var int lastShort = na
canLong = na(lastLong) or (bar_index - lastLong > coolBars)
canShort = na(lastShort) or (bar_index - lastShort > coolBars)
finalLong = longTrig and canLong
finalShort = shortTrig and canShort
if finalLong
lastLong := bar_index
if finalShort
lastShort := bar_index
//==================== Plots ========================
plot(ema20, "EMA 20", color=color.new(color.orange, 0))
plot(ema50, "EMA 50", color=color.new(color.blue, 0))
plot(useVWAP ? vwap : na, "VWAP", color=color.new(color.purple, 0))
plotshape(finalLong, title="LONG ▶", style=shape.labelup, location=location.belowbar, text="Long▶", color=color.new(color.blue, 0), size=size.tiny)
plotshape(finalShort, title="SHORT ▶", style=shape.labeldown, location=location.abovebar, text="Short▶", color=color.new(color.red, 0), size=size.tiny)
// Alerts
alertcondition(finalLong, "LONG ▶", "Long trigger")
alertcondition(finalShort, "SHORT ▶", "Short trigger")
// 시각적 노트레이드 힌트
bgcolor(pinch ? color.new(color.gray, 92) : na)
Open-source Skript
Ganz im Sinne von TradingView hat dieser Autor sein/ihr Script als Open-Source veröffentlicht. Auf diese Weise können nun auch andere Trader das Script rezensieren und die Funktionalität überprüfen. Vielen Dank an den Autor! Sie können das Script kostenlos verwenden, aber eine Wiederveröffentlichung des Codes unterliegt unseren Hausregeln.
Haftungsausschluss
Die Informationen und Veröffentlichungen sind nicht als Finanz-, Anlage-, Handels- oder andere Arten von Ratschlägen oder Empfehlungen gedacht, die von TradingView bereitgestellt oder gebilligt werden, und stellen diese nicht dar. Lesen Sie mehr in den Nutzungsbedingungen.
Open-source Skript
Ganz im Sinne von TradingView hat dieser Autor sein/ihr Script als Open-Source veröffentlicht. Auf diese Weise können nun auch andere Trader das Script rezensieren und die Funktionalität überprüfen. Vielen Dank an den Autor! Sie können das Script kostenlos verwenden, aber eine Wiederveröffentlichung des Codes unterliegt unseren Hausregeln.
Haftungsausschluss
Die Informationen und Veröffentlichungen sind nicht als Finanz-, Anlage-, Handels- oder andere Arten von Ratschlägen oder Empfehlungen gedacht, die von TradingView bereitgestellt oder gebilligt werden, und stellen diese nicht dar. Lesen Sie mehr in den Nutzungsbedingungen.