The Ultimate XAUUSD Scalping Indicator (Pine Script v5) - Trend + Momentum Confluence
Re: The Ultimate XAUUSD Scalping Indicator (Pine Script v5) - Trend + Momentum Confluence
How to Best Utilize the Pro Settings:
Trading Hours (Killzones): By default, I set it to 0800-1600 EST (8 AM to 4 PM New York time). A light blue background will highlight on your chart when this session is active. If a setup forms outside of these hours, the script ignores it.
The Break-Even Toggle: In the script settings under "Risk Management", you will see "Move SL to Break-Even at 1R?". Leave this checked. You'll notice in your backtest that your win rate might drop slightly, but your maximum drawdown will drastically improve because you are cutting risk immediately.
ADX Minimum Strength: Set to 20 by default. If the backtest shows too few trades, you can lower this to 15. If it's taking too many losing trades in choppy consolidation, bump it to 25.
Let me know what your equity curves are looking like after running this through the Strategy Tester!
Trading Hours (Killzones): By default, I set it to 0800-1600 EST (8 AM to 4 PM New York time). A light blue background will highlight on your chart when this session is active. If a setup forms outside of these hours, the script ignores it.
The Break-Even Toggle: In the script settings under "Risk Management", you will see "Move SL to Break-Even at 1R?". Leave this checked. You'll notice in your backtest that your win rate might drop slightly, but your maximum drawdown will drastically improve because you are cutting risk immediately.
ADX Minimum Strength: Set to 20 by default. If the backtest shows too few trades, you can lower this to 15. If it's taking too many losing trades in choppy consolidation, bump it to 25.
Let me know what your equity curves are looking like after running this through the Strategy Tester!
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: The Ultimate XAUUSD Scalping Indicator (Pine Script v5) - Trend + Momentum Confluence
Here is the updated script configured for partial profit-taking.
In Pine Script v5, the cleanest and most reliable way to execute partial closes is by assigning two distinct strategy.exit() exit orders to the same entry:
Target 1 (TP1 at 1R): Liquidates 50% of the position (qty_percent = 50) and banks guaranteed profit.
Target 2 (TP2 at 2R): Keeps the remaining 50% open to ride the momentum.
Auto Break-Even on Runner: The moment TP1 is struck, the script automatically trails the Stop Loss of the remaining 50% to your entry price, ensuring the second half is a 100% risk-free trade.
The Updated Pine Script v5 Code
In Pine Script v5, the cleanest and most reliable way to execute partial closes is by assigning two distinct strategy.exit() exit orders to the same entry:
Target 1 (TP1 at 1R): Liquidates 50% of the position (qty_percent = 50) and banks guaranteed profit.
Target 2 (TP2 at 2R): Keeps the remaining 50% open to ride the momentum.
Auto Break-Even on Runner: The moment TP1 is struck, the script automatically trails the Stop Loss of the remaining 50% to your entry price, ensuring the second half is a 100% risk-free trade.
The Updated Pine Script v5 Code
Code: Select all
//@version=5
strategy("Institutional XAUUSD Scalper Pro (Partial TP) [Forex-Scalping.com]", overlay=true, initial_capital=1000, default_qty_type=strategy.percent_of_equity, default_qty_value=5, commission_type=strategy.commission.cash_per_order, commission_value=3, slippage=2)
// ==========================================
// 1. USER INPUTS
// ==========================================
grp1 = "Trend & Trigger Settings"
fastEmaLen = input.int(9, title="Fast EMA Length", group=grp1)
slowEmaLen = input.int(21, title="Slow EMA Length", group=grp1)
trendEmaLen = input.int(200, title="Baseline Trend EMA", group=grp1)
grp2 = "Momentum, Volatility & Chop Filter"
rsiLen = input.int(14, title="RSI Length", group=grp2)
atrLen = input.int(14, title="ATR Length", group=grp2)
useAdxFilter = input.bool(true, title="Use ADX Chop Filter?", group=grp2)
adxLen = input.int(14, title="ADX Length", group=grp2)
adxThreshold = input.int(20, title="ADX Minimum Strength", group=grp2)
grp3 = "Risk Management (Scaling & SL/TP)"
slMultiplier = input.float(1.5, title="Stop Loss ATR Multiplier", step=0.1, group=grp3)
tp1Ratio = input.float(1.0, title="TP1 Ratio (Closes 50%)", step=0.1, group=grp3)
tp2Ratio = input.float(2.0, title="TP2 Ratio (Closes Runner)", step=0.1, group=grp3)
useBreakEven = input.bool(true, title="Move SL to Break-Even after TP1?", group=grp3)
grp4 = "Session & Time Filters"
useSession = input.bool(true, title="Only Trade Specific Sessions?", group=grp4)
sessionTime = input.session("0800-1600", title="Trading Hours (EST)", group=grp4)
// ==========================================
// 2. CALCULATIONS
// ==========================================
fastEma = ta.ema(close, fastEmaLen)
slowEma = ta.ema(close, slowEmaLen)
trendEma = ta.ema(close, trendEmaLen)
rsiVal = ta.rsi(close, rsiLen)
atrVal = ta.atr(atrLen)
// ADX Calculation
[diPlus, diMinus, adx] = ta.dmi(14, adxLen)
// Session Logic
inSession = not useSession or not na(time(timeframe.period, sessionTime, "America/New_York"))
// ==========================================
// 3. LOGIC & CONDITIONS
// ==========================================
bullishTrend = close > trendEma
bearishTrend = close < trendEma
trendStrong = not useAdxFilter or adx > adxThreshold
buySignal = ta.crossover(fastEma, slowEma) and bullishTrend and rsiVal > 50 and trendStrong and inSession
sellSignal = ta.crossunder(fastEma, slowEma) and bearishTrend and rsiVal < 50 and trendStrong and inSession
// ==========================================
// 4. STRATEGY EXECUTION & PARTIAL EXITS
// ==========================================
var float entryPrice = na
var float slLevel = na
var float tp1Level = na
var float tp2Level = na
var bool tp1Hit = false
var float riskDist = na
// --- ENTRY EXECUTION ---
if buySignal and strategy.position_size == 0
entryPrice := close
riskDist := atrVal * slMultiplier
slLevel := entryPrice - riskDist
tp1Level := entryPrice + (riskDist * tp1Ratio)
tp2Level := entryPrice + (riskDist * tp2Ratio)
tp1Hit := false
strategy.entry("Long", strategy.long)
// Order 1: Closes 50% at TP1
strategy.exit("Exit L-TP1", from_entry="Long", qty_percent=50, stop=slLevel, limit=tp1Level)
// Order 2: Manages remaining 50% to TP2
strategy.exit("Exit L-TP2", from_entry="Long", stop=slLevel, limit=tp2Level)
if sellSignal and strategy.position_size == 0
entryPrice := close
riskDist := atrVal * slMultiplier
slLevel := entryPrice + riskDist
tp1Level := entryPrice - (riskDist * tp1Ratio)
tp2Level := entryPrice - (riskDist * tp2Ratio)
tp1Hit := false
strategy.entry("Short", strategy.short)
// Order 1: Closes 50% at TP1
strategy.exit("Exit S-TP1", from_entry="Short", qty_percent=50, stop=slLevel, limit=tp1Level)
// Order 2: Manages remaining 50% to TP2
strategy.exit("Exit S-TP2", from_entry="Short", stop=slLevel, limit=tp2Level)
// --- TRADE MANAGEMENT (BREAK-EVEN ON RUNNER) ---
if strategy.position_size > 0 and not tp1Hit
if high >= tp1Level
tp1Hit := true
if useBreakEven
slLevel := entryPrice
// Update the stop loss of the remaining 50% runner to Breakeven
strategy.exit("Exit L-TP2", from_entry="Long", stop=slLevel, limit=tp2Level)
if strategy.position_size < 0 and not tp1Hit
if low <= tp1Level
tp1Hit := true
if useBreakEven
slLevel := entryPrice
// Update the stop loss of the remaining 50% runner to Breakeven
strategy.exit("Exit S-TP2", from_entry="Short", stop=slLevel, limit=tp2Level)
// Reset levels when flat
if strategy.position_size == 0
slLevel := na
tp1Level := na
tp2Level := na
entryPrice := na
tp1Hit := false
// ==========================================
// 5. PLOTTING
// ==========================================
plot(fastEma, color=color.new(color.blue, 0), title="Fast EMA", linewidth=1)
plot(slowEma, color=color.new(color.orange, 0), title="Slow EMA", linewidth=1)
plot(trendEma, color=color.new(color.white, 0), title="200 EMA Baseline", linewidth=2)
// Stop Loss Line (Turns Gray when moved to Breakeven)
plot(strategy.position_size != 0 ? slLevel : na, title="Stop Loss", color=tp1Hit ? color.new(color.gray, 20) : color.new(color.red, 20), style=plot.style_linebr, linewidth=2)
// TP1 Line (Hides once TP1 is hit)
plot(strategy.position_size != 0 and not tp1Hit ? tp1Level : na, title="Take Profit 1 (50%)", color=color.new(color.teal, 0), style=plot.style_linebr, linewidth=2)
// TP2 Line (Remains active for runner)
plot(strategy.position_size != 0 ? tp2Level : na, title="Take Profit 2 (Final)", color=color.new(color.green, 0), style=plot.style_linebr, linewidth=2)
// Session background shading
bgcolor(inSession and useSession ? color.new(color.blue, 95) : na, title="Session Window")
// ==========================================
// 6. PRO DASHBOARD
// ==========================================
var table dash = table.new(position.top_right, 2, 5, border_color=color.new(color.gray, 80), border_width=1, frame_color=color.new(color.gray, 80), frame_width=1)
string posStatus = "FLAT"
color statusBg = color.new(color.black, 0)
if strategy.position_size > 0
posStatus := tp1Hit ? "LONG (50% Runner)" : "LONG (Full)"
statusBg := color.new(color.green, 30)
else if strategy.position_size < 0
posStatus := tp1Hit ? "SHORT (50% Runner)" : "SHORT (Full)"
statusBg := color.new(color.red, 30)
if barstate.islast
table.cell(dash, 0, 0, "PRO SCALPER", text_color=color.white, bgcolor=color.new(#0800ff, 20), text_size=size.small)
table.cell(dash, 1, 0, "STATUS", text_color=color.white, bgcolor=color.new(#0800ff, 20), text_size=size.small)
table.cell(dash, 0, 1, "Macro Trend", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 1, bullishTrend ? "BULL" : "BEAR", text_color=bullishTrend ? color.green : color.red, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 0, 2, "ADX Filter (>20)", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 2, str.tostring(math.round(adx, 1)), text_color=trendStrong ? color.green : color.orange, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 0, 3, "Session Active", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 3, inSession ? "YES" : "NO", text_color=inSession ? color.green : color.red, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 0, 4, "Open Position", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 4, posStatus, text_color=color.white, bgcolor=statusBg, text_size=size.small)Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: The Ultimate XAUUSD Scalping Indicator (Pine Script v5) - Trend + Momentum Confluence
Visual & Backtest Improvements:
Dual Target Lines: A teal line indicates your 1R Target (TP1), and a bright green line indicates your 2R Target (TP2).
Dynamic Visual Clean-Up: As soon as TP1 is hit, the teal line disappears, the Stop Loss line turns gray and moves directly onto your entry price, and the green line stays plotted until the remaining 50% hits target.
Position Tracker: The dashboard now dynamically displays whether you are FLAT, in a LONG/SHORT (Full) position, or managing a risk-free LONG/SHORT (50% Runner).
Dual Target Lines: A teal line indicates your 1R Target (TP1), and a bright green line indicates your 2R Target (TP2).
Dynamic Visual Clean-Up: As soon as TP1 is hit, the teal line disappears, the Stop Loss line turns gray and moves directly onto your entry price, and the green line stays plotted until the remaining 50% hits target.
Position Tracker: The dashboard now dynamically displays whether you are FLAT, in a LONG/SHORT (Full) position, or managing a risk-free LONG/SHORT (50% Runner).
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: The Ultimate XAUUSD Scalping Indicator (Pine Script v5) - Trend + Momentum Confluence
Adding a Multi-Timeframe (MTF) filter is one of the most powerful upgrades you can make to a scalping algorithm. It guarantees that your 1-minute or 5-minute entries are always swimming with the current of the 1-hour macro trend, rather than fighting against it.
When im sharing scripts on Forex-Scalping.com, the biggest mistake amateur coders make with MTF data is repainting. If you simply request the live 1-hour EMA on a 5-minute chart, TradingView peeks into the future during backtesting, giving you a falsely inflated 100% win rate. However, in live trading, that unclosed 1-hour candle fluctuates, causing signals to vanish.
To make this institutional-grade, I used the barmerge.lookahead_on and [1] syntax. This forces the script to only look at the last fully closed 1-hour candle. It is 100% repainting-free, meaning your backtest results will perfectly match live execution.
When im sharing scripts on Forex-Scalping.com, the biggest mistake amateur coders make with MTF data is repainting. If you simply request the live 1-hour EMA on a 5-minute chart, TradingView peeks into the future during backtesting, giving you a falsely inflated 100% win rate. However, in live trading, that unclosed 1-hour candle fluctuates, causing signals to vanish.
To make this institutional-grade, I used the barmerge.lookahead_on and [1] syntax. This forces the script to only look at the last fully closed 1-hour candle. It is 100% repainting-free, meaning your backtest results will perfectly match live execution.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: The Ultimate XAUUSD Scalping Indicator (Pine Script v5) - Trend + Momentum Confluence
The MTF Pro Strategy Code
Copy and replace your script with this updated version:
Copy and replace your script with this updated version:
Code: Select all
//@version=5
strategy("Institutional XAUUSD Scalper Pro (MTF) [Forex-Scalping.com]", overlay=true, initial_capital=1000, default_qty_type=strategy.percent_of_equity, default_qty_value=5, commission_type=strategy.commission.cash_per_order, commission_value=3, slippage=2)
// ==========================================
// 1. USER INPUTS
// ==========================================
grp1 = "Trend & Trigger Settings (LTF)"
fastEmaLen = input.int(9, title="Fast EMA Length", group=grp1)
slowEmaLen = input.int(21, title="Slow EMA Length", group=grp1)
trendEmaLen = input.int(200, title="LTF Baseline EMA", group=grp1)
grp2 = "Higher Timeframe (MTF) Filter"
useHtfFilter = input.bool(true, title="Use HTF Filter?", group=grp2)
htfRes = input.timeframe("60", title="Higher Timeframe", group=grp2)
htfEmaLen = input.int(200, title="HTF EMA Length", group=grp2)
grp3 = "Momentum, Volatility & Chop Filter"
rsiLen = input.int(14, title="RSI Length", group=grp3)
atrLen = input.int(14, title="ATR Length", group=grp3)
useAdxFilter = input.bool(true, title="Use ADX Chop Filter?", group=grp3)
adxLen = input.int(14, title="ADX Length", group=grp3)
adxThreshold = input.int(20, title="ADX Minimum Strength", group=grp3)
grp4 = "Risk Management (Scaling & SL/TP)"
slMultiplier = input.float(1.5, title="Stop Loss ATR Multiplier", step=0.1, group=grp4)
tp1Ratio = input.float(1.0, title="TP1 Ratio (Closes 50%)", step=0.1, group=grp4)
tp2Ratio = input.float(2.0, title="TP2 Ratio (Closes Runner)", step=0.1, group=grp4)
useBreakEven = input.bool(true, title="Move SL to Break-Even after TP1?", group=grp4)
grp5 = "Session & Time Filters"
useSession = input.bool(true, title="Only Trade Specific Sessions?", group=grp5)
sessionTime = input.session("0800-1600", title="Trading Hours (EST)", group=grp5)
// ==========================================
// 2. CALCULATIONS (LTF & HTF)
// ==========================================
fastEma = ta.ema(close, fastEmaLen)
slowEma = ta.ema(close, slowEmaLen)
trendEma = ta.ema(close, trendEmaLen)
rsiVal = ta.rsi(close, rsiLen)
atrVal = ta.atr(atrLen)
// ADX Calculation
[diPlus, diMinus, adx] = ta.dmi(14, adxLen)
// MTF Calculation (Non-Repainting)
// We request the [1] value with lookahead_on to lock in the last closed HTF candle.
// This prevents the HTF EMA from repainting during real-time trading.
htfEma = request.security(syminfo.tickerid, htfRes, ta.ema(close, htfEmaLen)[1], lookahead=barmerge.lookahead_on)
// Session Logic
inSession = not useSession or not na(time(timeframe.period, sessionTime, "America/New_York"))
// ==========================================
// 3. LOGIC & CONDITIONS
// ==========================================
bullishTrend = close > trendEma
bearishTrend = close < trendEma
trendStrong = not useAdxFilter or adx > adxThreshold
// MTF Alignment
htfBullish = not useHtfFilter or close > htfEma
htfBearish = not useHtfFilter or close < htfEma
buySignal = ta.crossover(fastEma, slowEma) and bullishTrend and rsiVal > 50 and trendStrong and inSession and htfBullish
sellSignal = ta.crossunder(fastEma, slowEma) and bearishTrend and rsiVal < 50 and trendStrong and inSession and htfBearish
// ==========================================
// 4. STRATEGY EXECUTION & PARTIAL EXITS
// ==========================================
var float entryPrice = na
var float slLevel = na
var float tp1Level = na
var float tp2Level = na
var bool tp1Hit = false
var float riskDist = na
// --- ENTRY EXECUTION ---
if buySignal and strategy.position_size == 0
entryPrice := close
riskDist := atrVal * slMultiplier
slLevel := entryPrice - riskDist
tp1Level := entryPrice + (riskDist * tp1Ratio)
tp2Level := entryPrice + (riskDist * tp2Ratio)
tp1Hit := false
strategy.entry("Long", strategy.long)
strategy.exit("Exit L-TP1", from_entry="Long", qty_percent=50, stop=slLevel, limit=tp1Level)
strategy.exit("Exit L-TP2", from_entry="Long", stop=slLevel, limit=tp2Level)
if sellSignal and strategy.position_size == 0
entryPrice := close
riskDist := atrVal * slMultiplier
slLevel := entryPrice + riskDist
tp1Level := entryPrice - (riskDist * tp1Ratio)
tp2Level := entryPrice - (riskDist * tp2Ratio)
tp1Hit := false
strategy.entry("Short", strategy.short)
strategy.exit("Exit S-TP1", from_entry="Short", qty_percent=50, stop=slLevel, limit=tp1Level)
strategy.exit("Exit S-TP2", from_entry="Short", stop=slLevel, limit=tp2Level)
// --- TRADE MANAGEMENT (BREAK-EVEN ON RUNNER) ---
if strategy.position_size > 0 and not tp1Hit
if high >= tp1Level
tp1Hit := true
if useBreakEven
slLevel := entryPrice
strategy.exit("Exit L-TP2", from_entry="Long", stop=slLevel, limit=tp2Level)
if strategy.position_size < 0 and not tp1Hit
if low <= tp1Level
tp1Hit := true
if useBreakEven
slLevel := entryPrice
strategy.exit("Exit S-TP2", from_entry="Short", stop=slLevel, limit=tp2Level)
// Reset levels when flat
if strategy.position_size == 0
slLevel := na
tp1Level := na
tp2Level := na
entryPrice := na
tp1Hit := false
// ==========================================
// 5. PLOTTING
// ==========================================
// LTF EMAs
plot(fastEma, color=color.new(color.blue, 0), title="Fast EMA", linewidth=1)
plot(slowEma, color=color.new(color.orange, 0), title="Slow EMA", linewidth=1)
plot(trendEma, color=color.new(color.white, 0), title="LTF 200 EMA Baseline", linewidth=2)
// HTF EMA (Plotted as a Step Line)
plot(useHtfFilter ? htfEma : na, color=color.new(color.yellow, 0), title="HTF 200 EMA", linewidth=3, style=plot.style_stepline)
// Stop Loss Line (Turns Gray when moved to Breakeven)
plot(strategy.position_size != 0 ? slLevel : na, title="Stop Loss", color=tp1Hit ? color.new(color.gray, 20) : color.new(color.red, 20), style=plot.style_linebr, linewidth=2)
// TP1 Line (Hides once TP1 is hit)
plot(strategy.position_size != 0 and not tp1Hit ? tp1Level : na, title="Take Profit 1 (50%)", color=color.new(color.teal, 0), style=plot.style_linebr, linewidth=2)
// TP2 Line (Remains active for runner)
plot(strategy.position_size != 0 ? tp2Level : na, title="Take Profit 2 (Final)", color=color.new(color.green, 0), style=plot.style_linebr, linewidth=2)
// Session background shading
bgcolor(inSession and useSession ? color.new(color.blue, 95) : na, title="Session Window")
// ==========================================
// 6. PRO DASHBOARD
// ==========================================
var table dash = table.new(position.top_right, 2, 6, border_color=color.new(color.gray, 80), border_width=1, frame_color=color.new(color.gray, 80), frame_width=1)
string posStatus = "FLAT"
color statusBg = color.new(color.black, 0)
if strategy.position_size > 0
posStatus := tp1Hit ? "LONG (50% Runner)" : "LONG (Full)"
statusBg := color.new(color.green, 30)
else if strategy.position_size < 0
posStatus := tp1Hit ? "SHORT (50% Runner)" : "SHORT (Full)"
statusBg := color.new(color.red, 30)
// HTF Status String Processing
string htfStatus = not useHtfFilter ? "OFF" : (close > htfEma ? "BULL" : "BEAR")
color htfColor = not useHtfFilter ? color.gray : (close > htfEma ? color.green : color.red)
if barstate.islast
table.cell(dash, 0, 0, "PRO SCALPER (MTF)", text_color=color.white, bgcolor=color.new(#0800ff, 20), text_size=size.small)
table.cell(dash, 1, 0, "STATUS", text_color=color.white, bgcolor=color.new(#0800ff, 20), text_size=size.small)
table.cell(dash, 0, 1, "LTF Trend", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 1, bullishTrend ? "BULL" : "BEAR", text_color=bullishTrend ? color.green : color.red, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 0, 2, "HTF Trend (" + htfRes + ")", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 2, htfStatus, text_color=htfColor, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 0, 3, "ADX Filter (>20)", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 3, str.tostring(math.round(adx, 1)), text_color=trendStrong ? color.green : color.orange, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 0, 4, "Session Active", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 4, inSession ? "YES" : "NO", text_color=inSession ? color.green : color.red, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 0, 5, "Open Position", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 5, posStatus, text_color=color.white, bgcolor=statusBg, text_size=size.small)Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: The Ultimate XAUUSD Scalping Indicator (Pine Script v5) - Trend + Momentum Confluence
What Changed:
The HTF Input Tab: You can now toggle the Higher Timeframe filter on or off. By default, it looks at the 60-minute chart's 200 EMA (even if you are trading on the 1m or 5m timeframe).
Visual Overlay: The 1-hour EMA plots as a bold, yellow plot.style_stepline. It draws flat horizontal lines that step down only when the 1-hour candle formally closes, giving you a perfect visualization of true support and resistance from the higher timeframe.
The Dashboard Expansion: The UI panel now tracks your lower timeframe trend and your higher timeframe trend independently so you know exactly when the alignment happens.
The HTF Input Tab: You can now toggle the Higher Timeframe filter on or off. By default, it looks at the 60-minute chart's 200 EMA (even if you are trading on the 1m or 5m timeframe).
Visual Overlay: The 1-hour EMA plots as a bold, yellow plot.style_stepline. It draws flat horizontal lines that step down only when the 1-hour candle formally closes, giving you a perfect visualization of true support and resistance from the higher timeframe.
The Dashboard Expansion: The UI panel now tracks your lower timeframe trend and your higher timeframe trend independently so you know exactly when the alignment happens.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: The Ultimate XAUUSD Scalping Indicator (Pine Script v5) - Trend + Momentum Confluence
This is the holy grail of scalping logic. By removing the fixed Take Profit on the second half of your position, you transform the strategy from a standard scalp into an asymmetric trend-following system.
When price chops, you take small losses. When it makes a standard move, you bank your 1R and break even. But when a macro headline drops or massive institutional volume steps in, that remaining 50% will ride the trend until the momentum mathematically breaks.
To achieve this, I’ve implemented a Chandelier-style ATR Trailing Stop. Once your first 50% target is hit, the script immediately pulls your Stop Loss to break-even (or better), and then ratchets it behind the price step-by-step as the trend pushes forward.
When price chops, you take small losses. When it makes a standard move, you bank your 1R and break even. But when a macro headline drops or massive institutional volume steps in, that remaining 50% will ride the trend until the momentum mathematically breaks.
To achieve this, I’ve implemented a Chandelier-style ATR Trailing Stop. Once your first 50% target is hit, the script immediately pulls your Stop Loss to break-even (or better), and then ratchets it behind the price step-by-step as the trend pushes forward.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: The Ultimate XAUUSD Scalping Indicator (Pine Script v5) - Trend + Momentum Confluence
The Asymmetric Trend-Rider Strategy (Pine Script v5)
Replace your code in the Pine Editor with this final version:
Replace your code in the Pine Editor with this final version:
Code: Select all
//@version=5
strategy("Institutional XAUUSD Scalper Pro (ATR Trail) [Forex-Scalping.com]", overlay=true, initial_capital=1000, default_qty_type=strategy.percent_of_equity, default_qty_value=5, commission_type=strategy.commission.cash_per_order, commission_value=3, slippage=2)
// ==========================================
// 1. USER INPUTS
// ==========================================
grp1 = "Trend & Trigger Settings (LTF)"
fastEmaLen = input.int(9, title="Fast EMA Length", group=grp1)
slowEmaLen = input.int(21, title="Slow EMA Length", group=grp1)
trendEmaLen = input.int(200, title="LTF Baseline EMA", group=grp1)
grp2 = "Higher Timeframe (MTF) Filter"
useHtfFilter = input.bool(true, title="Use HTF Filter?", group=grp2)
htfRes = input.timeframe("60", title="Higher Timeframe", group=grp2)
htfEmaLen = input.int(200, title="HTF EMA Length", group=grp2)
grp3 = "Momentum & Chop Filter"
rsiLen = input.int(14, title="RSI Length", group=grp3)
atrLen = input.int(14, title="ATR Length", group=grp3)
useAdxFilter = input.bool(true, title="Use ADX Chop Filter?", group=grp3)
adxLen = input.int(14, title="ADX Length", group=grp3)
adxThreshold = input.int(20, title="ADX Minimum Strength", group=grp3)
grp4 = "Risk Management & Trailing Stop"
slMultiplier = input.float(1.5, title="Initial SL ATR Multiplier", step=0.1, group=grp4)
tp1Ratio = input.float(1.0, title="TP1 Ratio (Closes 50%)", step=0.1, group=grp4)
trailAtrMult = input.float(2.0, title="Trailing Stop ATR Distance (Runner)", step=0.1, group=grp4)
grp5 = "Session & Time Filters"
useSession = input.bool(true, title="Only Trade Specific Sessions?", group=grp5)
sessionTime = input.session("0800-1600", title="Trading Hours (EST)", group=grp5)
// ==========================================
// 2. CALCULATIONS (LTF & HTF)
// ==========================================
fastEma = ta.ema(close, fastEmaLen)
slowEma = ta.ema(close, slowEmaLen)
trendEma = ta.ema(close, trendEmaLen)
rsiVal = ta.rsi(close, rsiLen)
atrVal = ta.atr(atrLen)
[diPlus, diMinus, adx] = ta.dmi(14, adxLen)
// Non-Repainting MTF Data
htfEma = request.security(syminfo.tickerid, htfRes, ta.ema(close, htfEmaLen)[1], lookahead=barmerge.lookahead_on)
inSession = not useSession or not na(time(timeframe.period, sessionTime, "America/New_York"))
// ==========================================
// 3. LOGIC & CONDITIONS
// ==========================================
bullishTrend = close > trendEma
bearishTrend = close < trendEma
trendStrong = not useAdxFilter or adx > adxThreshold
htfBullish = not useHtfFilter or close > htfEma
htfBearish = not useHtfFilter or close < htfEma
buySignal = ta.crossover(fastEma, slowEma) and bullishTrend and rsiVal > 50 and trendStrong and inSession and htfBullish
sellSignal = ta.crossunder(fastEma, slowEma) and bearishTrend and rsiVal < 50 and trendStrong and inSession and htfBearish
// ==========================================
// 4. EXECUTION & ATR TRAILING LOGIC
// ==========================================
var float entryPrice = na
var float slLevel = na
var float tp1Level = na
var bool tp1Hit = false
var float riskDist = na
// --- ENTRY EXECUTION ---
if buySignal and strategy.position_size == 0
entryPrice := close
riskDist := atrVal * slMultiplier
slLevel := entryPrice - riskDist
tp1Level := entryPrice + (riskDist * tp1Ratio)
tp1Hit := false
strategy.entry("Long", strategy.long)
strategy.exit("Exit L-TP1", from_entry="Long", qty_percent=50, stop=slLevel, limit=tp1Level)
strategy.exit("Exit L-Runner", from_entry="Long", stop=slLevel) // No limit, infinite upside
if sellSignal and strategy.position_size == 0
entryPrice := close
riskDist := atrVal * slMultiplier
slLevel := entryPrice + riskDist
tp1Level := entryPrice - (riskDist * tp1Ratio)
tp1Hit := false
strategy.entry("Short", strategy.short)
strategy.exit("Exit S-TP1", from_entry="Short", qty_percent=50, stop=slLevel, limit=tp1Level)
strategy.exit("Exit S-Runner", from_entry="Short", stop=slLevel) // No limit
// --- TRAILING STOP LOGIC ---
if strategy.position_size > 0
// Check if TP1 was just hit
if not tp1Hit and high >= tp1Level
tp1Hit := true
// Instantly move stop to break-even or better based on trail
slLevel := math.max(entryPrice, close - (atrVal * trailAtrMult))
strategy.exit("Exit L-Runner", from_entry="Long", stop=slLevel)
// Ratchet the trailing stop upward
if tp1Hit
newTrail = close - (atrVal * trailAtrMult)
if newTrail > slLevel
slLevel := newTrail
strategy.exit("Exit L-Runner", from_entry="Long", stop=slLevel)
if strategy.position_size < 0
if not tp1Hit and low <= tp1Level
tp1Hit := true
slLevel := math.min(entryPrice, close + (atrVal * trailAtrMult))
strategy.exit("Exit S-Runner", from_entry="Short", stop=slLevel)
if tp1Hit
newTrail = close + (atrVal * trailAtrMult)
if newTrail < slLevel
slLevel := newTrail
strategy.exit("Exit S-Runner", from_entry="Short", stop=slLevel)
// Reset levels
if strategy.position_size == 0
slLevel := na
tp1Level := na
entryPrice := na
tp1Hit := false
// ==========================================
// 5. PLOTTING
// ==========================================
plot(fastEma, color=color.new(color.blue, 0), title="Fast EMA", linewidth=1)
plot(slowEma, color=color.new(color.orange, 0), title="Slow EMA", linewidth=1)
plot(trendEma, color=color.new(color.white, 0), title="LTF 200 EMA Baseline", linewidth=2)
plot(useHtfFilter ? htfEma : na, color=color.new(color.yellow, 0), title="HTF 200 EMA", linewidth=3, style=plot.style_stepline)
// Dynamic Stop Loss Line (Turns purple when trailing)
plot(strategy.position_size != 0 ? slLevel : na, title="Stop Loss / Trail", color=tp1Hit ? color.new(#b026ff, 0) : color.new(color.red, 20), style=plot.style_stepline, linewidth=2)
// TP1 Line (Hides once TP1 is hit)
plot(strategy.position_size != 0 and not tp1Hit ? tp1Level : na, title="Take Profit 1 (50%)", color=color.new(color.teal, 0), style=plot.style_linebr, linewidth=2)
bgcolor(inSession and useSession ? color.new(color.blue, 95) : na, title="Session Window")
// ==========================================
// 6. PRO DASHBOARD
// ==========================================
var table dash = table.new(position.top_right, 2, 6, border_color=color.new(color.gray, 80), border_width=1, frame_color=color.new(color.gray, 80), frame_width=1)
string posStatus = "FLAT"
color statusBg = color.new(color.black, 0)
if strategy.position_size > 0
posStatus := tp1Hit ? "LONG (Trailing)" : "LONG (Full)"
statusBg := tp1Hit ? color.new(#b026ff, 30) : color.new(color.green, 30)
else if strategy.position_size < 0
posStatus := tp1Hit ? "SHORT (Trailing)" : "SHORT (Full)"
statusBg := tp1Hit ? color.new(#b026ff, 30) : color.new(color.red, 30)
string htfStatus = not useHtfFilter ? "OFF" : (close > htfEma ? "BULL" : "BEAR")
color htfColor = not useHtfFilter ? color.gray : (close > htfEma ? color.green : color.red)
if barstate.islast
table.cell(dash, 0, 0, "PRO SCALPER (ATR TRAIL)", text_color=color.white, bgcolor=color.new(#0800ff, 20), text_size=size.small)
table.cell(dash, 1, 0, "STATUS", text_color=color.white, bgcolor=color.new(#0800ff, 20), text_size=size.small)
table.cell(dash, 0, 1, "LTF Trend", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 1, bullishTrend ? "BULL" : "BEAR", text_color=bullishTrend ? color.green : color.red, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 0, 2, "HTF Trend (" + htfRes + ")", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 2, htfStatus, text_color=htfColor, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 0, 3, "ADX Filter (>20)", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 3, str.tostring(math.round(adx, 1)), text_color=trendStrong ? color.green : color.orange, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 0, 4, "Session Active", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 4, inSession ? "YES" : "NO", text_color=inSession ? color.green : color.red, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 0, 5, "Open Position", text_color=color.gray, bgcolor=color.new(color.black, 0), text_size=size.small)
table.cell(dash, 1, 5, posStatus, text_color=color.white, bgcolor=statusBg, text_size=size.small)Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: The Ultimate XAUUSD Scalping Indicator (Pine Script v5) - Trend + Momentum Confluence
How the Trailing Stop Behaves Visually:
The Initial Trade: Your Stop Loss starts as a flat red line, and your Target 1 is a flat teal line.
The Breakout: The exact moment price tags your 1R Target, the teal line vanishes. The Stop Loss line instantly shifts to break-even, and its color turns Purple.
The Ratchet Effect: Because I plotted the Trailing Stop using plot.style_stepline, you will visually see the purple line forming "steps" up the chart (for Longs) or down the chart (for Shorts) directly underneath the price action. It will never move backward.
With these inputs, the algorithm now mathematically guarantees you will never let a massive trend slip away without extracting the maximum possible value from the runner.
The Initial Trade: Your Stop Loss starts as a flat red line, and your Target 1 is a flat teal line.
The Breakout: The exact moment price tags your 1R Target, the teal line vanishes. The Stop Loss line instantly shifts to break-even, and its color turns Purple.
The Ratchet Effect: Because I plotted the Trailing Stop using plot.style_stepline, you will visually see the purple line forming "steps" up the chart (for Longs) or down the chart (for Shorts) directly underneath the price action. It will never move backward.
With these inputs, the algorithm now mathematically guarantees you will never let a massive trend slip away without extracting the maximum possible value from the runner.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
-
PropScalpDesk
- Posts: 229
- Joined: Sat Sep 19, 2026 7:50 pm
Re: The Ultimate XAUUSD Scalping Indicator (Pine Script v5) - Trend + Momentum Confluence
Hybrid runners sound attractive until trailing DD and gold spreads join the meeting. From Frankfurt I allow a runner only with a written protocol: first scale at planned R, runner stop to structure, hard time stop. “No TP on the second half” without those brakes is how a scalp becomes an accidental swing inside a funded daily.PTScalper wrote:By removing the fixed take profit on the second half of your position, you transform the strategy from a standard scalp into a hybrid that can catch the real trend move.
Desk rule: runners are optional and rare. Most of my expectancy still sits in the planned first clip. If the morning already paid, I often skip the hero half entirely.
Indicator confluence helps markup; it does not cancel session filters or news blackouts.
Trend+momentum confluence on gold is fine for markup. It is not a substitute for news blackouts or a soft daily. I would rather bank the first scale and stand aside than romanticise the unpaid second half.
How do you decide the runner is done — structure break, time, or a max adverse excursion from the scale point?