XAUUSD 1m SMC Zones (BOS + Flexible TP Modes + Trailing Runner) — Strategy by amart24
By version
Performance Metrics
- Author: version
- Symbol: OANDA:XAUUSD
- Timeframe: 15 minutes
- Net P&L: +421.21 USD (+4.21%)
- Win Rate: 60.7%
- Profit Factor: 2.598
- Max Drawdown: 97.69 USD (0.94%)
- Total Trades: 56
Description
//version=6strategy("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 / SLtp1Pips = 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 riskmaxDailyLossPct = 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.0tp1Points = tp1Pips * pipSizeslPoints = fixedSLpips * pipSizebaseQty = input.float (1.0, "Base order size" , step = 0.01, minval = 0.01)//━━━━━━━━━━━━━━━━━━━// 2. DAILY RISK MANAGEMENT//━━━━━━━━━━━━━━━━━━━isNewDay = ta.change(time("D")) != 0var float dayStartEquity = navar bool dailyStopped = falseequityNow = strategy.initial_capital + strategy.netprofitif isNewDay or na(dayStartEquity) dayStartEquity := equityNow dailyStopped := falsedailyPnL = equityNow - dayStartEquitydailyPnLPct = dayStartEquity != 0 ? (dailyPnL / dayStartEquity) * 100.0 : 0.0if not dailyStopped if dailyPnLPct = maxDailyProfitPct dailyStopped := truecanTradeToday = 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 HTFhtBullPrev = htClose[1] > htOpen[1]htBearPrev = htClose[1] = htClose[1] and htClose htOpen and htBearPrev and htOpen = htOpen[1]// Liquidity sweep on HTF previous candlehtSweepHigh = htHigh[1] > ta.highest(htHigh, 5)[2]htSweepLow = htLow[1] = htResLowinHtfSup = not na(htSupLow) and close >= htSupLow and close open[1]bearPrev1 = close[1] = close[1] and close open and bearPrev1 and open = open[1]// Liquidity sweep by previous candle on 1msweepHighPrev = high[1] > ta.highest(high, 5)[2]sweepLowPrev = low[1] bear engulfif bearEngulfNow resLow := low[1] resHigh := high[1] resQ := sweepHighPrev ? 2 : 1 resUsed := false// New support zone: previous bearish candle -> bull engulfif bullEngulfNow supLow := low[1] supHigh := high[1] supQ := sweepLowPrev ? 2 : 1 supUsed := false// Raw "inside zone" detectioninSupRaw = not na(supLow) and close >= supLow and close = resLow// QUALITY FILTER: only trade zones with quality ≥ 2 (engulf + sweep)highQualitySup = supQ >= 2highQualityRes = resQ >= 2inSupZone = inSupRaw and highQualitySup and not supUsedinResZone = inResRaw and highQualityRes and not resUsed// Plot zonesplot(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/lowsswHigh = high[1] > high[0] and high[1] > high[2]swLow = low[1] lastSwingHighbosDown = not na(lastSwingLow) and close = 0longSignal = canTradeToday and not longBlockedByZone and inSupZone and supBosOK and flatOrShortshortSignal = canTradeToday and not shortBlockedByZone and inResZone and resBosOK and flatOrLong//━━━━━━━━━━━━━━━━━━━// 7. ORDER LOGIC – TWO PROFIT STRATEGIES//━━━━━━━━━━━━━━━━━━━// Common metricsatrTrail = ta.atr(atrTrailLen)// MINIMAL MODE: single trade, BE after TP1, optional trailing// HYBRID MODE: two trades (Scalp @ TP1, Runner @ TP2)// Persistent trackingvar float longEntry = navar float longTP1 = navar float longTP2 = navar float longSL = navar bool longBE = falsevar float longRunEntry = navar float longRunTP1 = navar float longRunTP2 = navar float longRunSL = navar bool longRunBE = falsevar float shortEntry = navar float shortTP1 = navar float shortTP2 = navar float shortSL = navar bool shortBE = falsevar float shortRunEntry = navar float shortRunTP1 = navar float shortRunTP2 = navar float shortRunSL = navar bool shortRunBE = falseisMinimal = 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 TP2if 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 TP2if isMinimal and strategy.position_size 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 + Runnerif 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")