v5: optional entry filters (ATR buffer, confirm bars, ADX) + alertconditions for final signals

This commit is contained in:
root
2025-10-19 19:57:38 +02:00
parent e1067f211a
commit 04900aefc8

View File

@@ -38,6 +38,15 @@ macdFastLen = input.int(12, "Fast", minval=1, inline="macdLens")
macdSlowLen = input.int(26, "Slow", minval=1, inline="macdLens") macdSlowLen = input.int(26, "Slow", minval=1, inline="macdLens")
macdSigLen = input.int(9, "Signal", minval=1, inline="macdLens") macdSigLen = input.int(9, "Signal", minval=1, inline="macdLens")
// Entry filters (optional)
groupFilters = "Entry filters"
useEntryBuffer = input.bool(false, "Require entry buffer (ATR)", group=groupFilters, tooltip="If enabled, the close must be beyond the Money Line by the buffer amount to avoid wick flips.")
entryBufferATR = input.float(0.15, "Buffer size (in ATR)", minval=0.0, step=0.05, group=groupFilters, tooltip="0.100.20 works well on 1h.")
confirmBars = input.int(0, "Bars to confirm after flip", minval=0, maxval=2, group=groupFilters, tooltip="0 = signal on flip bar. 1 = wait one bar.")
useAdx = input.bool(false, "Use ADX trend-strength filter", group=groupFilters, tooltip="If enabled, require ADX to be above a threshold to reduce chop.")
adxLen = input.int(14, "ADX Length", minval=1, group=groupFilters)
adxMin = input.int(20, "ADX minimum", minval=0, maxval=100, group=groupFilters)
// Determine effective parameters based on selected mode/profile // Determine effective parameters based on selected mode/profile
var string activeProfile = "" var string activeProfile = ""
resSec = timeframe.in_seconds(timeframe.period) resSec = timeframe.in_seconds(timeframe.period)
@@ -129,8 +138,28 @@ shortOk = not useMacd or (macdLine < macdSignal)
buyFlip = trend == 1 and trend[1] == -1 buyFlip = trend == 1 and trend[1] == -1
sellFlip = trend == -1 and trend[1] == 1 sellFlip = trend == -1 and trend[1] == 1
plotshape(buyFlip and longOk, title="Buy Signal", location=location.belowbar, color=color.green, style=shape.circle, size=size.small) // ADX computation and gate
plotshape(sellFlip and shortOk, title="Sell Signal", location=location.abovebar, color=color.red, style=shape.circle, size=size.small) adxVal = ta.adx(adxLen)
adxOk = not useAdx or (adxVal > adxMin)
// Entry buffer gates relative to current Money Line
longBufferOk = not useEntryBuffer or (calcC > supertrend + entryBufferATR * atr)
shortBufferOk = not useEntryBuffer or (calcC < supertrend - entryBufferATR * atr)
// Confirmation bars after flip
buyReady = ta.barssince(buyFlip) == confirmBars
sellReady = ta.barssince(sellFlip) == confirmBars
// Final gated signals
finalLongSignal = buyReady and longOk and adxOk and longBufferOk
finalShortSignal = sellReady and shortOk and adxOk and shortBufferOk
plotshape(finalLongSignal, title="Buy Signal", location=location.belowbar, color=color.green, style=shape.circle, size=size.small)
plotshape(finalShortSignal, title="Sell Signal", location=location.abovebar, color=color.red, style=shape.circle, size=size.small)
// Alerts for final signals (set to 'Once per bar close' in the alert dialog)
alertcondition(finalLongSignal, title="Bullmania Buy", message="Buy {{ticker}} {{interval}} | Profile={{activeProfile}} ATR={{atrPeriod}} Mult={{multiplier}}")
alertcondition(finalShortSignal, title="Bullmania Sell", message="Sell {{ticker}} {{interval}} | Profile={{activeProfile}} ATR={{atrPeriod}} Mult={{multiplier}}")
// Fill area between price and Money Line // Fill area between price and Money Line
fill(plot(close, display=display.none), plot(upTrend, display=display.none), color=color.new(color.green, 90)) fill(plot(close, display=display.none), plot(upTrend, display=display.none), color=color.new(color.green, 90))