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)
Açık kaynak kodlu komut dosyası
Gerçek TradingView ruhuna uygun olarak, bu komut dosyasının oluşturucusu bunu açık kaynaklı hale getirmiştir, böylece yatırımcılar betiğin işlevselliğini inceleyip doğrulayabilir. Yazara saygı! Ücretsiz olarak kullanabilirsiniz, ancak kodu yeniden yayınlamanın Site Kurallarımıza tabi olduğunu unutmayın.
Feragatname
Bilgiler ve yayınlar, TradingView tarafından sağlanan veya onaylanan finansal, yatırım, işlem veya diğer türden tavsiye veya tavsiyeler anlamına gelmez ve teşkil etmez. Kullanım Şartları'nda daha fazlasını okuyun.
Açık kaynak kodlu komut dosyası
Gerçek TradingView ruhuna uygun olarak, bu komut dosyasının oluşturucusu bunu açık kaynaklı hale getirmiştir, böylece yatırımcılar betiğin işlevselliğini inceleyip doğrulayabilir. Yazara saygı! Ücretsiz olarak kullanabilirsiniz, ancak kodu yeniden yayınlamanın Site Kurallarımıza tabi olduğunu unutmayın.
Feragatname
Bilgiler ve yayınlar, TradingView tarafından sağlanan veya onaylanan finansal, yatırım, işlem veya diğer türden tavsiye veya tavsiyeler anlamına gelmez ve teşkil etmez. Kullanım Şartları'nda daha fazlasını okuyun.