OPEN-SOURCE SCRIPT
XAUUSD 1m SMC Zones (BOS + Flexible TP Modes + Trailing Runner)

//version=6
strategy("XAUUSD 1m SMC Zones (BOS + Flexible TP Modes + Trailing Runner)",
overlay = true,
initial_capital = 10000,
pyramiding = 10,
process_orders_on_close = true)
//━━━━━━━━━━━━━━━━━━━
// 1. INPUTS
//━━━━━━━━━━━━━━━━━━━
// TP / SL
tp1Pips = input.int(10, "TP1 (pips)", minval = 1)
fixedSLpips = input.int(50, "Fixed SL (pips)", minval = 5)
runnerRR = input.float(3.0, "Runner RR (TP2 = SL * RR)", step = 0.1, minval = 1.0)
// Daily risk
maxDailyLossPct = input.float(5.0, "Max daily loss % (stop trading)", step = 0.5)
maxDailyProfitPct = input.float(20.0, "Max daily profit % (stop trading)", step = 1.0)
// HTF S/R (1H)
htfTF = input.string("60", "HTF timeframe (minutes) for S/R block")
// Profit strategy (Option C)
profitStrategy = input.string("Minimal Risk | Full BE after TP1", "Profit Strategy", options = [ "Minimal Risk | Full BE after TP1", "Hybrid | Scalp TP + Runner TP"])
// Runner stop mode (your option 4)
runnerStopMode = input.string( "BE only", "Runner Stop Mode", options = ["BE only", "Structure trail", "ATR trail" ])
// ATR trail settings (only used if ATR mode selected)
atrTrailLen = input.int(14, "ATR Length (trail)", minval = 1)
atrTrailMult = input.float(1.0, "ATR Multiplier (trail)", step = 0.1, minval = 0.1)
// Pip size (for XAUUSD: 1 pip = 0.10 if tick = 0.01)
pipSize = syminfo.mintick * 10.0
tp1Points = tp1Pips * pipSize
slPoints = fixedSLpips * pipSize
baseQty = input.float (1.0, "Base order size" , step = 0.01, minval = 0.01)
//━━━━━━━━━━━━━━━━━━━
// 2. DAILY RISK MANAGEMENT
//━━━━━━━━━━━━━━━━━━━
isNewDay = ta.change(time("D")) != 0
var float dayStartEquity = na
var bool dailyStopped = false
equityNow = strategy.initial_capital + strategy.netprofit
if isNewDay or na(dayStartEquity)
dayStartEquity := equityNow
dailyStopped := false
dailyPnL = equityNow - dayStartEquity
dailyPnLPct = dayStartEquity != 0 ? (dailyPnL / dayStartEquity) * 100.0 : 0.0
if not dailyStopped
if dailyPnLPct <= -maxDailyLossPct
dailyStopped := true
if dailyPnLPct >= maxDailyProfitPct
dailyStopped := true
canTradeToday = not dailyStopped
//━━━━━━━━━━━━━━━━━━━
// 3. 1H S/R ZONES (for direction block)
//━━━━━━━━━━━━━━━━━━━
htOpen = request.security(syminfo.tickerid, htfTF, open)
htHigh = request.security(syminfo.tickerid, htfTF, high)
htLow = request.security(syminfo.tickerid, htfTF, low)
htClose = request.security(syminfo.tickerid, htfTF, close)
// Engulf logic on HTF
htBullPrev = htClose[1] > htOpen[1]
htBearPrev = htClose[1] < htOpen[1]
htBearEngulf = htClose < htOpen and htBullPrev and htOpen >= htClose[1] and htClose <= htOpen[1]
htBullEngulf = htClose > htOpen and htBearPrev and htOpen <= htClose[1] and htClose >= htOpen[1]
// Liquidity sweep on HTF previous candle
htSweepHigh = htHigh[1] > ta.highest(htHigh, 5)[2]
htSweepLow = htLow[1] < ta.lowest(htLow, 5)[2]
// Store last HTF zones
var float htResHigh = na
var float htResLow = na
var float htSupHigh = na
var float htSupLow = na
if htBearEngulf and htSweepHigh
htResHigh := htHigh[1]
htResLow := htLow[1]
if htBullEngulf and htSweepLow
htSupHigh := htHigh[1]
htSupLow := htLow[1]
// Are we inside HTF zones?
inHtfRes = not na(htResHigh) and close <= htResHigh and close >= htResLow
inHtfSup = not na(htSupLow) and close >= htSupLow and close <= htSupHigh
// Block direction against HTF zones
longBlockedByZone = inHtfRes // no buys in HTF resistance
shortBlockedByZone = inHtfSup // no sells in HTF support
//━━━━━━━━━━━━━━━━━━━
// 4. 1m LOCAL ZONES (LIQUIDITY SWEEP + ENGULF + QUALITY SCORE)
//━━━━━━━━━━━━━━━━━━━
// 1m engulf patterns
bullPrev1 = close[1] > open[1]
bearPrev1 = close[1] < open[1]
bearEngulfNow = close < open and bullPrev1 and open >= close[1] and close <= open[1]
bullEngulfNow = close > open and bearPrev1 and open <= close[1] and close >= open[1]
// Liquidity sweep by previous candle on 1m
sweepHighPrev = high[1] > ta.highest(high, 5)[2]
sweepLowPrev = low[1] < ta.lowest(low, 5)[2]
// Local zone storage (one active support + one active resistance)
// Quality score: 1 = engulf only, 2 = engulf + sweep (we only trade ≥2)
var float supLow = na
var float supHigh = na
var int supQ = 0
var bool supUsed = false
var float resLow = na
var float resHigh = na
var int resQ = 0
var bool resUsed = false
// New resistance zone: previous bullish candle -> bear engulf
if bearEngulfNow
resLow := low[1]
resHigh := high[1]
resQ := sweepHighPrev ? 2 : 1
resUsed := false
// New support zone: previous bearish candle -> bull engulf
if bullEngulfNow
supLow := low[1]
supHigh := high[1]
supQ := sweepLowPrev ? 2 : 1
supUsed := false
// Raw "inside zone" detection
inSupRaw = not na(supLow) and close >= supLow and close <= supHigh
inResRaw = not na(resHigh) and close <= resHigh and close >= resLow
// QUALITY FILTER: only trade zones with quality ≥ 2 (engulf + sweep)
highQualitySup = supQ >= 2
highQualityRes = resQ >= 2
inSupZone = inSupRaw and highQualitySup and not supUsed
inResZone = inResRaw and highQualityRes and not resUsed
// Plot zones
plot(supLow, "Sup Low", color = color.new(color.lime, 60), style = plot.style_linebr)
plot(supHigh, "Sup High", color = color.new(color.lime, 60), style = plot.style_linebr)
plot(resLow, "Res Low", color = color.new(color.red, 60), style = plot.style_linebr)
plot(resHigh, "Res High", color = color.new(color.red, 60), style = plot.style_linebr)
//━━━━━━━━━━━━━━━━━━━
// 5. MODERATE BOS (3-BAR FRACTAL STRUCTURE)
//━━━━━━━━━━━━━━━━━━━
// 3-bar swing highs/lows
swHigh = high[1] > high[0] and high[1] > high[2]
swLow = low[1] < low[0] and low[1] < low[2]
var float lastSwingHigh = na
var float lastSwingLow = na
if swHigh
lastSwingHigh := high[1]
if swLow
lastSwingLow := low[1]
// BOS conditions
bosUp = not na(lastSwingHigh) and close > lastSwingHigh
bosDown = not na(lastSwingLow) and close < lastSwingLow
// Zone “arming” and BOS validation
var bool supArmed = false
var bool resArmed = false
var bool supBosOK = false
var bool resBosOK = false
// Arm zones when first touched
if inSupZone
supArmed := true
if inResZone
resArmed := true
// BOS after arming → zone becomes valid for entries
if supArmed and bosUp
supBosOK := true
if resArmed and bosDown
resBosOK := true
// Reset BOS flags when new zones are created
if bullEngulfNow
supArmed := false
supBosOK := false
if bearEngulfNow
resArmed := false
resBosOK := false
//━━━━━━━━━━━━━━━━━━━
// 6. ENTRY CONDITIONS (ZONE + BOS + RISK STATE)
//━━━━━━━━━━━━━━━━━━━
flatOrShort = strategy.position_size <= 0
flatOrLong = strategy.position_size >= 0
longSignal = canTradeToday and not longBlockedByZone and inSupZone and supBosOK and flatOrShort
shortSignal = canTradeToday and not shortBlockedByZone and inResZone and resBosOK and flatOrLong
//━━━━━━━━━━━━━━━━━━━
// 7. ORDER LOGIC – TWO PROFIT STRATEGIES
//━━━━━━━━━━━━━━━━━━━
// Common metrics
atrTrail = ta.atr(atrTrailLen)
// MINIMAL MODE: single trade, BE after TP1, optional trailing
// HYBRID MODE: two trades (Scalp @ TP1, Runner @ TP2)
// Persistent tracking
var float longEntry = na
var float longTP1 = na
var float longTP2 = na
var float longSL = na
var bool longBE = false
var float longRunEntry = na
var float longRunTP1 = na
var float longRunTP2 = na
var float longRunSL = na
var bool longRunBE = false
var float shortEntry = na
var float shortTP1 = na
var float shortTP2 = na
var float shortSL = na
var bool shortBE = false
var float shortRunEntry = na
var float shortRunTP1 = na
var float shortRunTP2 = na
var float shortRunSL = na
var bool shortRunBE = false
isMinimal = profitStrategy == "Minimal Risk | Full BE after TP1"
isHybrid = profitStrategy == "Hybrid | Scalp TP + Runner TP"
//━━━━━━━━━━ LONG ENTRIES ━━━━━━━━━━
if longSignal
if isMinimal
longEntry := close
longSL := longEntry - slPoints
longTP1 := longEntry + tp1Points
longTP2 := longEntry + slPoints * runnerRR
longBE := false
strategy.entry("Long", strategy.long)
supUsed := true
supArmed := false
supBosOK := false
else if isHybrid
longRunEntry := close
longRunSL := longRunEntry - slPoints
longRunTP1 := longRunEntry + tp1Points
longRunTP2 := longRunEntry + slPoints * runnerRR
longRunBE := false
// Two separate entries, each 50% of baseQty (for backtest)
strategy.entry("LongScalp", strategy.long, qty = baseQty * 0.5)
strategy.entry("LongRun", strategy.long, qty = baseQty * 0.5)
supUsed := true
supArmed := false
supBosOK := false
//━━━━━━━━━━ SHORT ENTRIES ━━━━━━━━━━
if shortSignal
if isMinimal
shortEntry := close
shortSL := shortEntry + slPoints
shortTP1 := shortEntry - tp1Points
shortTP2 := shortEntry - slPoints * runnerRR
shortBE := false
strategy.entry("Short", strategy.short)
resUsed := true
resArmed := false
resBosOK := false
else if isHybrid
shortRunEntry := close
shortRunSL := shortRunEntry + slPoints
shortRunTP1 := shortRunEntry - tp1Points
shortRunTP2 := shortRunEntry - slPoints * runnerRR
shortRunBE := false
strategy.entry("ShortScalp", strategy.short, qty = baseQty * 50)
strategy.entry("ShortRun", strategy.short, qty = baseQty * 50)
resUsed := true
resArmed := false
resBosOK := false
//━━━━━━━━━━━━━━━━━━━
// 8. EXIT LOGIC – MINIMAL MODE
//━━━━━━━━━━━━━━━━━━━
// LONG – Minimal Risk: 1 trade, BE after TP1, runner to TP2
if isMinimal and strategy.position_size > 0 and not na(longEntry)
// Move to BE once TP1 is touched
if not longBE and high >= longTP1
longBE := true
// Base SL: BE or initial SL
float dynLongSL = longBE ? longEntry : longSL
// Optional trailing after BE
if longBE
if runnerStopMode == "Structure trail" and not na(lastSwingLow) and lastSwingLow > longEntry
dynLongSL := math.max(dynLongSL, lastSwingLow)
if runnerStopMode == "ATR trail"
trailSL = close - atrTrailMult * atrTrail
dynLongSL := math.max(dynLongSL, trailSL)
strategy.exit("Long Exit", "Long", stop = dynLongSL, limit = longTP2)
// SHORT – Minimal Risk: 1 trade, BE after TP1, runner to TP2
if isMinimal and strategy.position_size < 0 and not na(shortEntry)
if not shortBE and low <= shortTP1
shortBE := true
float dynShortSL = shortBE ? shortEntry : shortSL
if shortBE
if runnerStopMode == "Structure trail" and not na(lastSwingHigh) and lastSwingHigh < shortEntry
dynShortSL := math.min(dynShortSL, lastSwingHigh)
if runnerStopMode == "ATR trail"
trailSLs = close + atrTrailMult * atrTrail
dynShortSL := math.min(dynShortSL, trailSLs)
strategy.exit("Short Exit", "Short", stop = dynShortSL, limit = shortTP2)
//━━━━━━━━━━━━━━━━━━━
// 9. EXIT LOGIC – HYBRID MODE
//━━━━━━━━━━━━━━━━━━━
// LONG – Hybrid: Scalp + Runner
if isHybrid
// Scalp leg: full TP at TP1
if strategy.opentrades > 0
strategy.exit("LScalp TP", "LongScalp", stop = longRunSL, limit = longRunTP1)
// Runner leg
if strategy.position_size > 0 and not na(longRunEntry)
if not longRunBE and high >= longRunTP1
longRunBE := true
float dynLongRunSL = longRunBE ? longRunEntry : longRunSL
if longRunBE
if runnerStopMode == "Structure trail" and not na(lastSwingLow) and lastSwingLow > longRunEntry
dynLongRunSL := math.max(dynLongRunSL, lastSwingLow)
if runnerStopMode == "ATR trail"
trailRunSL = close - atrTrailMult * atrTrail
dynLongRunSL := math.max(dynLongRunSL, trailRunSL)
strategy.exit("LRun TP", "LongRun", stop = dynLongRunSL, limit = longRunTP2)
// SHORT – Hybrid: Scalp + Runner
if isHybrid
if strategy.opentrades > 0
strategy.exit("SScalp TP", "ShortScalp", stop = shortRunSL, limit = shortRunTP1)
if strategy.position_size < 0 and not na(shortRunEntry)
if not shortRunBE and low <= shortRunTP1
shortRunBE := true
float dynShortRunSL = shortRunBE ? shortRunEntry : shortRunSL
if shortRunBE
if runnerStopMode == "Structure trail" and not na(lastSwingHigh) and lastSwingHigh < shortRunEntry
dynShortRunSL := math.min(dynShortRunSL, lastSwingHigh)
if runnerStopMode == "ATR trail"
trailRunSLs = close + atrTrailMult * atrTrail
dynShortRunSL := math.min(dynShortRunSL, trailRunSLs)
strategy.exit("SRun TP", "ShortRun", stop = dynShortRunSL, limit = shortRunTP2)
//━━━━━━━━━━━━━━━━━━━
// 10. RESET STATE WHEN FLAT
//━━━━━━━━━━━━━━━━━━━
if strategy.position_size == 0
longEntry := na
shortEntry := na
longBE := false
shortBE := false
longRunEntry := na
shortRunEntry := na
longRunBE := false
shortRunBE := false
//━━━━━━━━━━━━━━━━━━━
// 11. VISUAL ENTRY MARKERS
//━━━━━━━━━━━━━━━━━━━
plotshape(longSignal, title = "Long Signal", style = shape.triangleup,
location = location.belowbar, color = color.lime, size = size.tiny, text = "L")
plotshape(shortSignal, title = "Short Signal", style = shape.triangledown,
location = location.abovebar, color = color.red, size = size.tiny, text = "S")
strategy("XAUUSD 1m SMC Zones (BOS + Flexible TP Modes + Trailing Runner)",
overlay = true,
initial_capital = 10000,
pyramiding = 10,
process_orders_on_close = true)
//━━━━━━━━━━━━━━━━━━━
// 1. INPUTS
//━━━━━━━━━━━━━━━━━━━
// TP / SL
tp1Pips = input.int(10, "TP1 (pips)", minval = 1)
fixedSLpips = input.int(50, "Fixed SL (pips)", minval = 5)
runnerRR = input.float(3.0, "Runner RR (TP2 = SL * RR)", step = 0.1, minval = 1.0)
// Daily risk
maxDailyLossPct = input.float(5.0, "Max daily loss % (stop trading)", step = 0.5)
maxDailyProfitPct = input.float(20.0, "Max daily profit % (stop trading)", step = 1.0)
// HTF S/R (1H)
htfTF = input.string("60", "HTF timeframe (minutes) for S/R block")
// Profit strategy (Option C)
profitStrategy = input.string("Minimal Risk | Full BE after TP1", "Profit Strategy", options = [ "Minimal Risk | Full BE after TP1", "Hybrid | Scalp TP + Runner TP"])
// Runner stop mode (your option 4)
runnerStopMode = input.string( "BE only", "Runner Stop Mode", options = ["BE only", "Structure trail", "ATR trail" ])
// ATR trail settings (only used if ATR mode selected)
atrTrailLen = input.int(14, "ATR Length (trail)", minval = 1)
atrTrailMult = input.float(1.0, "ATR Multiplier (trail)", step = 0.1, minval = 0.1)
// Pip size (for XAUUSD: 1 pip = 0.10 if tick = 0.01)
pipSize = syminfo.mintick * 10.0
tp1Points = tp1Pips * pipSize
slPoints = fixedSLpips * pipSize
baseQty = input.float (1.0, "Base order size" , step = 0.01, minval = 0.01)
//━━━━━━━━━━━━━━━━━━━
// 2. DAILY RISK MANAGEMENT
//━━━━━━━━━━━━━━━━━━━
isNewDay = ta.change(time("D")) != 0
var float dayStartEquity = na
var bool dailyStopped = false
equityNow = strategy.initial_capital + strategy.netprofit
if isNewDay or na(dayStartEquity)
dayStartEquity := equityNow
dailyStopped := false
dailyPnL = equityNow - dayStartEquity
dailyPnLPct = dayStartEquity != 0 ? (dailyPnL / dayStartEquity) * 100.0 : 0.0
if not dailyStopped
if dailyPnLPct <= -maxDailyLossPct
dailyStopped := true
if dailyPnLPct >= maxDailyProfitPct
dailyStopped := true
canTradeToday = not dailyStopped
//━━━━━━━━━━━━━━━━━━━
// 3. 1H S/R ZONES (for direction block)
//━━━━━━━━━━━━━━━━━━━
htOpen = request.security(syminfo.tickerid, htfTF, open)
htHigh = request.security(syminfo.tickerid, htfTF, high)
htLow = request.security(syminfo.tickerid, htfTF, low)
htClose = request.security(syminfo.tickerid, htfTF, close)
// Engulf logic on HTF
htBullPrev = htClose[1] > htOpen[1]
htBearPrev = htClose[1] < htOpen[1]
htBearEngulf = htClose < htOpen and htBullPrev and htOpen >= htClose[1] and htClose <= htOpen[1]
htBullEngulf = htClose > htOpen and htBearPrev and htOpen <= htClose[1] and htClose >= htOpen[1]
// Liquidity sweep on HTF previous candle
htSweepHigh = htHigh[1] > ta.highest(htHigh, 5)[2]
htSweepLow = htLow[1] < ta.lowest(htLow, 5)[2]
// Store last HTF zones
var float htResHigh = na
var float htResLow = na
var float htSupHigh = na
var float htSupLow = na
if htBearEngulf and htSweepHigh
htResHigh := htHigh[1]
htResLow := htLow[1]
if htBullEngulf and htSweepLow
htSupHigh := htHigh[1]
htSupLow := htLow[1]
// Are we inside HTF zones?
inHtfRes = not na(htResHigh) and close <= htResHigh and close >= htResLow
inHtfSup = not na(htSupLow) and close >= htSupLow and close <= htSupHigh
// Block direction against HTF zones
longBlockedByZone = inHtfRes // no buys in HTF resistance
shortBlockedByZone = inHtfSup // no sells in HTF support
//━━━━━━━━━━━━━━━━━━━
// 4. 1m LOCAL ZONES (LIQUIDITY SWEEP + ENGULF + QUALITY SCORE)
//━━━━━━━━━━━━━━━━━━━
// 1m engulf patterns
bullPrev1 = close[1] > open[1]
bearPrev1 = close[1] < open[1]
bearEngulfNow = close < open and bullPrev1 and open >= close[1] and close <= open[1]
bullEngulfNow = close > open and bearPrev1 and open <= close[1] and close >= open[1]
// Liquidity sweep by previous candle on 1m
sweepHighPrev = high[1] > ta.highest(high, 5)[2]
sweepLowPrev = low[1] < ta.lowest(low, 5)[2]
// Local zone storage (one active support + one active resistance)
// Quality score: 1 = engulf only, 2 = engulf + sweep (we only trade ≥2)
var float supLow = na
var float supHigh = na
var int supQ = 0
var bool supUsed = false
var float resLow = na
var float resHigh = na
var int resQ = 0
var bool resUsed = false
// New resistance zone: previous bullish candle -> bear engulf
if bearEngulfNow
resLow := low[1]
resHigh := high[1]
resQ := sweepHighPrev ? 2 : 1
resUsed := false
// New support zone: previous bearish candle -> bull engulf
if bullEngulfNow
supLow := low[1]
supHigh := high[1]
supQ := sweepLowPrev ? 2 : 1
supUsed := false
// Raw "inside zone" detection
inSupRaw = not na(supLow) and close >= supLow and close <= supHigh
inResRaw = not na(resHigh) and close <= resHigh and close >= resLow
// QUALITY FILTER: only trade zones with quality ≥ 2 (engulf + sweep)
highQualitySup = supQ >= 2
highQualityRes = resQ >= 2
inSupZone = inSupRaw and highQualitySup and not supUsed
inResZone = inResRaw and highQualityRes and not resUsed
// Plot zones
plot(supLow, "Sup Low", color = color.new(color.lime, 60), style = plot.style_linebr)
plot(supHigh, "Sup High", color = color.new(color.lime, 60), style = plot.style_linebr)
plot(resLow, "Res Low", color = color.new(color.red, 60), style = plot.style_linebr)
plot(resHigh, "Res High", color = color.new(color.red, 60), style = plot.style_linebr)
//━━━━━━━━━━━━━━━━━━━
// 5. MODERATE BOS (3-BAR FRACTAL STRUCTURE)
//━━━━━━━━━━━━━━━━━━━
// 3-bar swing highs/lows
swHigh = high[1] > high[0] and high[1] > high[2]
swLow = low[1] < low[0] and low[1] < low[2]
var float lastSwingHigh = na
var float lastSwingLow = na
if swHigh
lastSwingHigh := high[1]
if swLow
lastSwingLow := low[1]
// BOS conditions
bosUp = not na(lastSwingHigh) and close > lastSwingHigh
bosDown = not na(lastSwingLow) and close < lastSwingLow
// Zone “arming” and BOS validation
var bool supArmed = false
var bool resArmed = false
var bool supBosOK = false
var bool resBosOK = false
// Arm zones when first touched
if inSupZone
supArmed := true
if inResZone
resArmed := true
// BOS after arming → zone becomes valid for entries
if supArmed and bosUp
supBosOK := true
if resArmed and bosDown
resBosOK := true
// Reset BOS flags when new zones are created
if bullEngulfNow
supArmed := false
supBosOK := false
if bearEngulfNow
resArmed := false
resBosOK := false
//━━━━━━━━━━━━━━━━━━━
// 6. ENTRY CONDITIONS (ZONE + BOS + RISK STATE)
//━━━━━━━━━━━━━━━━━━━
flatOrShort = strategy.position_size <= 0
flatOrLong = strategy.position_size >= 0
longSignal = canTradeToday and not longBlockedByZone and inSupZone and supBosOK and flatOrShort
shortSignal = canTradeToday and not shortBlockedByZone and inResZone and resBosOK and flatOrLong
//━━━━━━━━━━━━━━━━━━━
// 7. ORDER LOGIC – TWO PROFIT STRATEGIES
//━━━━━━━━━━━━━━━━━━━
// Common metrics
atrTrail = ta.atr(atrTrailLen)
// MINIMAL MODE: single trade, BE after TP1, optional trailing
// HYBRID MODE: two trades (Scalp @ TP1, Runner @ TP2)
// Persistent tracking
var float longEntry = na
var float longTP1 = na
var float longTP2 = na
var float longSL = na
var bool longBE = false
var float longRunEntry = na
var float longRunTP1 = na
var float longRunTP2 = na
var float longRunSL = na
var bool longRunBE = false
var float shortEntry = na
var float shortTP1 = na
var float shortTP2 = na
var float shortSL = na
var bool shortBE = false
var float shortRunEntry = na
var float shortRunTP1 = na
var float shortRunTP2 = na
var float shortRunSL = na
var bool shortRunBE = false
isMinimal = profitStrategy == "Minimal Risk | Full BE after TP1"
isHybrid = profitStrategy == "Hybrid | Scalp TP + Runner TP"
//━━━━━━━━━━ LONG ENTRIES ━━━━━━━━━━
if longSignal
if isMinimal
longEntry := close
longSL := longEntry - slPoints
longTP1 := longEntry + tp1Points
longTP2 := longEntry + slPoints * runnerRR
longBE := false
strategy.entry("Long", strategy.long)
supUsed := true
supArmed := false
supBosOK := false
else if isHybrid
longRunEntry := close
longRunSL := longRunEntry - slPoints
longRunTP1 := longRunEntry + tp1Points
longRunTP2 := longRunEntry + slPoints * runnerRR
longRunBE := false
// Two separate entries, each 50% of baseQty (for backtest)
strategy.entry("LongScalp", strategy.long, qty = baseQty * 0.5)
strategy.entry("LongRun", strategy.long, qty = baseQty * 0.5)
supUsed := true
supArmed := false
supBosOK := false
//━━━━━━━━━━ SHORT ENTRIES ━━━━━━━━━━
if shortSignal
if isMinimal
shortEntry := close
shortSL := shortEntry + slPoints
shortTP1 := shortEntry - tp1Points
shortTP2 := shortEntry - slPoints * runnerRR
shortBE := false
strategy.entry("Short", strategy.short)
resUsed := true
resArmed := false
resBosOK := false
else if isHybrid
shortRunEntry := close
shortRunSL := shortRunEntry + slPoints
shortRunTP1 := shortRunEntry - tp1Points
shortRunTP2 := shortRunEntry - slPoints * runnerRR
shortRunBE := false
strategy.entry("ShortScalp", strategy.short, qty = baseQty * 50)
strategy.entry("ShortRun", strategy.short, qty = baseQty * 50)
resUsed := true
resArmed := false
resBosOK := false
//━━━━━━━━━━━━━━━━━━━
// 8. EXIT LOGIC – MINIMAL MODE
//━━━━━━━━━━━━━━━━━━━
// LONG – Minimal Risk: 1 trade, BE after TP1, runner to TP2
if isMinimal and strategy.position_size > 0 and not na(longEntry)
// Move to BE once TP1 is touched
if not longBE and high >= longTP1
longBE := true
// Base SL: BE or initial SL
float dynLongSL = longBE ? longEntry : longSL
// Optional trailing after BE
if longBE
if runnerStopMode == "Structure trail" and not na(lastSwingLow) and lastSwingLow > longEntry
dynLongSL := math.max(dynLongSL, lastSwingLow)
if runnerStopMode == "ATR trail"
trailSL = close - atrTrailMult * atrTrail
dynLongSL := math.max(dynLongSL, trailSL)
strategy.exit("Long Exit", "Long", stop = dynLongSL, limit = longTP2)
// SHORT – Minimal Risk: 1 trade, BE after TP1, runner to TP2
if isMinimal and strategy.position_size < 0 and not na(shortEntry)
if not shortBE and low <= shortTP1
shortBE := true
float dynShortSL = shortBE ? shortEntry : shortSL
if shortBE
if runnerStopMode == "Structure trail" and not na(lastSwingHigh) and lastSwingHigh < shortEntry
dynShortSL := math.min(dynShortSL, lastSwingHigh)
if runnerStopMode == "ATR trail"
trailSLs = close + atrTrailMult * atrTrail
dynShortSL := math.min(dynShortSL, trailSLs)
strategy.exit("Short Exit", "Short", stop = dynShortSL, limit = shortTP2)
//━━━━━━━━━━━━━━━━━━━
// 9. EXIT LOGIC – HYBRID MODE
//━━━━━━━━━━━━━━━━━━━
// LONG – Hybrid: Scalp + Runner
if isHybrid
// Scalp leg: full TP at TP1
if strategy.opentrades > 0
strategy.exit("LScalp TP", "LongScalp", stop = longRunSL, limit = longRunTP1)
// Runner leg
if strategy.position_size > 0 and not na(longRunEntry)
if not longRunBE and high >= longRunTP1
longRunBE := true
float dynLongRunSL = longRunBE ? longRunEntry : longRunSL
if longRunBE
if runnerStopMode == "Structure trail" and not na(lastSwingLow) and lastSwingLow > longRunEntry
dynLongRunSL := math.max(dynLongRunSL, lastSwingLow)
if runnerStopMode == "ATR trail"
trailRunSL = close - atrTrailMult * atrTrail
dynLongRunSL := math.max(dynLongRunSL, trailRunSL)
strategy.exit("LRun TP", "LongRun", stop = dynLongRunSL, limit = longRunTP2)
// SHORT – Hybrid: Scalp + Runner
if isHybrid
if strategy.opentrades > 0
strategy.exit("SScalp TP", "ShortScalp", stop = shortRunSL, limit = shortRunTP1)
if strategy.position_size < 0 and not na(shortRunEntry)
if not shortRunBE and low <= shortRunTP1
shortRunBE := true
float dynShortRunSL = shortRunBE ? shortRunEntry : shortRunSL
if shortRunBE
if runnerStopMode == "Structure trail" and not na(lastSwingHigh) and lastSwingHigh < shortRunEntry
dynShortRunSL := math.min(dynShortRunSL, lastSwingHigh)
if runnerStopMode == "ATR trail"
trailRunSLs = close + atrTrailMult * atrTrail
dynShortRunSL := math.min(dynShortRunSL, trailRunSLs)
strategy.exit("SRun TP", "ShortRun", stop = dynShortRunSL, limit = shortRunTP2)
//━━━━━━━━━━━━━━━━━━━
// 10. RESET STATE WHEN FLAT
//━━━━━━━━━━━━━━━━━━━
if strategy.position_size == 0
longEntry := na
shortEntry := na
longBE := false
shortBE := false
longRunEntry := na
shortRunEntry := na
longRunBE := false
shortRunBE := false
//━━━━━━━━━━━━━━━━━━━
// 11. VISUAL ENTRY MARKERS
//━━━━━━━━━━━━━━━━━━━
plotshape(longSignal, title = "Long Signal", style = shape.triangleup,
location = location.belowbar, color = color.lime, size = size.tiny, text = "L")
plotshape(shortSignal, title = "Short Signal", style = shape.triangledown,
location = location.abovebar, color = color.red, size = size.tiny, text = "S")
Open-source script
In true TradingView spirit, the creator of this script has made it open-source, so that traders can review and verify its functionality. Kudos to the author! While you can use it for free, remember that republishing the code is subject to our House Rules.
Disclaimer
The information and publications are not meant to be, and do not constitute, financial, investment, trading, or other types of advice or recommendations supplied or endorsed by TradingView. Read more in the Terms of Use.
Open-source script
In true TradingView spirit, the creator of this script has made it open-source, so that traders can review and verify its functionality. Kudos to the author! While you can use it for free, remember that republishing the code is subject to our House Rules.
Disclaimer
The information and publications are not meant to be, and do not constitute, financial, investment, trading, or other types of advice or recommendations supplied or endorsed by TradingView. Read more in the Terms of Use.