Forex scalping trading strategy for Gold (XAU/USD)
Forex scalping trading strategy for Gold (XAU/USD)
Hi traders, scalpers,
i prepared for you another interesting trading strategy.
The highest-expectancy forex scalping approach combines Higher-Timeframe (H4/D1) Structural Liquidity Zones with M15/M5 Price-Action Displacement on a Raw ECN execution feed. Pure indicator-crossover systems on 1-minute charts break down once spread expansion, slippage, and round-turn commissions are factored in; fading false breakouts (liquidity sweeps) or trading confirmed micro-structure pullbacks in the direction of institutional order flow keeps stops tight (5 to 12 pips) while preserving asymmetric reward-to-risk ratios (1:1.5 to 1:4).
i prepared for you another interesting trading strategy.
The highest-expectancy forex scalping approach combines Higher-Timeframe (H4/D1) Structural Liquidity Zones with M15/M5 Price-Action Displacement on a Raw ECN execution feed. Pure indicator-crossover systems on 1-minute charts break down once spread expansion, slippage, and round-turn commissions are factored in; fading false breakouts (liquidity sweeps) or trading confirmed micro-structure pullbacks in the direction of institutional order flow keeps stops tight (5 to 12 pips) while preserving asymmetric reward-to-risk ratios (1:1.5 to 1:4).
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Forex scalping trading strategy for Gold (XAU/USD)
1. Strategy Architecture: Multi-Timeframe Liquidity & Micro-Structure
Step-by-Step Execution Protocol
Follow this sequence before placing any order during an active session:
1.Map Pre-Session H4/D1 Liquidity Pools:
Complete 15 minutes before London or New York open.
Mark the Previous Day High (PDH), Previous Day Low (PDL), Asian Session High/Low, and major H4 Support and Resistance zones. These levels act as liquidity magnets where clustered retail stop-losses and breakout orders rest.
Step-by-Step Execution Protocol
Follow this sequence before placing any order during an active session:
1.Map Pre-Session H4/D1 Liquidity Pools:
Complete 15 minutes before London or New York open.
Mark the Previous Day High (PDH), Previous Day Low (PDL), Asian Session High/Low, and major H4 Support and Resistance zones. These levels act as liquidity magnets where clustered retail stop-losses and breakout orders rest.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Forex scalping trading strategy for Gold (XAU/USD)
2.Wait for the Liquidity Sweep or Trend Impulse:
Filter out mid-range noise on M15.
Allow price to reach your pre-marked H4 or session level. Look for one of two institutional footprints on the M15 chart:Reversal Sweep (False Breakout): Price pierces the key support/resistance level by a few pips to sweep stops, then prints an impulsive engulfing candle that closes decisively back inside the level.Trend Pullback: In a strong directional trend where EMA 20 is separated from EMA 50, wait for price to pull back into the EMA 20 and horizontal micro-support/resistance zone.
Filter out mid-range noise on M15.
Allow price to reach your pre-marked H4 or session level. Look for one of two institutional footprints on the M15 chart:Reversal Sweep (False Breakout): Price pierces the key support/resistance level by a few pips to sweep stops, then prints an impulsive engulfing candle that closes decisively back inside the level.Trend Pullback: In a strong directional trend where EMA 20 is separated from EMA 50, wait for price to pull back into the EMA 20 and horizontal micro-support/resistance zone.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Forex scalping trading strategy for Gold (XAU/USD)
3.Confirm Micro Break of Structure (BoS) & Enter:
Execute on M5/M15 candle close or 50% retest.
Drop to the M5 or M15 chart and verify that price breaks the minor swing high (for longs) or swing low (for shorts) that initiated the sweep or pullback.Entry: Enter on the confirmation candle close or place a limit order at the 50% retracement of the displacement candle.Hard Stop-Loss: Place a server-side stop-loss 1x M5 ATR (typically 6 to 12 pips on FX majors, or $0.80 to $1.50 on XAU/USD) beyond the extreme tip of the liquidity sweep wick. If price violates that wick, exit immediately without widening the stop.
Execute on M5/M15 candle close or 50% retest.
Drop to the M5 or M15 chart and verify that price breaks the minor swing high (for longs) or swing low (for shorts) that initiated the sweep or pullback.Entry: Enter on the confirmation candle close or place a limit order at the 50% retracement of the displacement candle.Hard Stop-Loss: Place a server-side stop-loss 1x M5 ATR (typically 6 to 12 pips on FX majors, or $0.80 to $1.50 on XAU/USD) beyond the extreme tip of the liquidity sweep wick. If price violates that wick, exit immediately without widening the stop.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Forex scalping trading strategy for Gold (XAU/USD)
4.Manage Trade & Scale Out Asymmetrically:
Protect capital first, let runners capture H4 range.
At +1.2R to +1.5R: Close 50% of the position (or move your hard stop to breakeven plus commission) to eliminate downside risk on the trade.At +2R: Trail the remaining stop-loss behind each new M15 higher low (for longs) or lower high (for shorts).Final Target (+2.5R to +4R) or Time Stop: Target the opposing intraday liquidity pool or session high/low. If price stalls and fails to move in your favor within 3 to 4 M15 candles, close the trade manually via a time stop.
Protect capital first, let runners capture H4 range.
At +1.2R to +1.5R: Close 50% of the position (or move your hard stop to breakeven plus commission) to eliminate downside risk on the trade.At +2R: Trail the remaining stop-loss behind each new M15 higher low (for longs) or lower high (for shorts).Final Target (+2.5R to +4R) or Time Stop: Target the opposing intraday liquidity pool or session high/low. If price stalls and fails to move in your favor within 3 to 4 M15 candles, close the trade manually via a time stop.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Forex scalping trading strategy for Gold (XAU/USD)
Position Sizing, Spread Friction & Profit-Locked Scaling
In high-frequency scalping, transaction costs represent a major percentage of gross edge. On a $10,000 account, position sizing must explicitly account for both the structural stop distance and the round-turn ECN commission:
$$\text{Position Size (Lots)} = \frac{\text{Account Equity} \times \text{Risk \%}}{\left(\text{Stop-Loss in Pips} + \text{Effective Spread/Commission in Pips}\right) \times \text{Pip Value}}$$
Worked Calculation ($10,000 Account on EUR/USD)
Baseline Risk per Trade: 0.50% of account equity = $50.00 maximum loss.Trade Parameters:
8.0-pip structural stop-loss + 0.1-pip raw spread + 0.7-pip equivalent commission ($7.00 round-turn per standard lot) = 8.8 pips total risk distance.Exact
Lot Size: $$\text{Position Size} = \frac{\$50.00}{8.8 \text{ pips} \times \$10.00/\text{pip}} = 0.568 \approx \mathbf{0.57 \text{ Standard Lots}}$$
Reward Profile: At a 1.5R initial target (13.2 pips net, or ~14 pips gross), the trade nets $75.00 after commissions; at a 3R runner target (26.4 pips net), it nets $150.00.
In high-frequency scalping, transaction costs represent a major percentage of gross edge. On a $10,000 account, position sizing must explicitly account for both the structural stop distance and the round-turn ECN commission:
$$\text{Position Size (Lots)} = \frac{\text{Account Equity} \times \text{Risk \%}}{\left(\text{Stop-Loss in Pips} + \text{Effective Spread/Commission in Pips}\right) \times \text{Pip Value}}$$
Worked Calculation ($10,000 Account on EUR/USD)
Baseline Risk per Trade: 0.50% of account equity = $50.00 maximum loss.Trade Parameters:
8.0-pip structural stop-loss + 0.1-pip raw spread + 0.7-pip equivalent commission ($7.00 round-turn per standard lot) = 8.8 pips total risk distance.Exact
Lot Size: $$\text{Position Size} = \frac{\$50.00}{8.8 \text{ pips} \times \$10.00/\text{pip}} = 0.568 \approx \mathbf{0.57 \text{ Standard Lots}}$$
Reward Profile: At a 1.5R initial target (13.2 pips net, or ~14 pips gross), the trade nets $75.00 after commissions; at a 3R runner target (26.4 pips net), it nets $150.00.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Forex scalping trading strategy for Gold (XAU/USD)
Exponential "Profit-Lock" Risk Protocol
Rather than risking a high static percentage on every trade, separate Core Capital from Accumulated Session Profit:
Phase 1 (Baseline Defense): Risk strictly 0.25% to 0.50% ($25 to $50 on a $10,000 account) until your account builds a realized profit cushion of +2.0% ($200). Enforce a hard daily drawdown cap of 1.5% ($150) or 3 consecutive losses—if hit, shut down the terminal for the session.
Phase 2 (Asymmetric Scaling from Gains): Once you are up +2.0% ($200) on the week, permanently lock 50% ($100) into your protected equity floor and use up to 50% of the unlocked profit buffer ($100) to scale position size on your next A+ London/NY overlap setup. Your core deposit remains insulated while winning streaks compound geometrically.
Rather than risking a high static percentage on every trade, separate Core Capital from Accumulated Session Profit:
Phase 1 (Baseline Defense): Risk strictly 0.25% to 0.50% ($25 to $50 on a $10,000 account) until your account builds a realized profit cushion of +2.0% ($200). Enforce a hard daily drawdown cap of 1.5% ($150) or 3 consecutive losses—if hit, shut down the terminal for the session.
Phase 2 (Asymmetric Scaling from Gains): Once you are up +2.0% ($200) on the week, permanently lock 50% ($100) into your protected equity floor and use up to 50% of the unlocked profit buffer ($100) to scale position size on your next A+ London/NY overlap setup. Your core deposit remains insulated while winning streaks compound geometrically.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Forex scalping trading strategy for Gold (XAU/USD)
Action Plan to Deploy This Strategy
Configure a Raw ECN Execution Workspace: Allocate your baseline trading capital (e.g., $10,000 or a dedicated sub-account) on an ECN account with raw spreads (0.0 to 0.2 pips on EUR/USD) and set a live spread-filter alert so you never execute when spreads widen past 0.5 pips on majors or $0.25 on XAU/USD before your next London session.
Enforce Fixed Fractional & Daily Drawdown Limits: Lock your default order-ticket risk at 0.25% to 0.50% ($25 to $50 per trade) with a hard daily loss limit of 1.5% ($150), and commit to executing 50 consecutive sample trades exclusively during the London Open and London–NY Overlap over the next 30 trading days.
Audit Expectancy & Activate Profit-Locked Scaling: After completing your 50-trade sample block, verify a minimum Profit Factor of 1.4+ and net expectancy greater than 0.3R per trade in your trade journal before activating the 50% profit-lock scaling rule for live lot expansion.
Configure a Raw ECN Execution Workspace: Allocate your baseline trading capital (e.g., $10,000 or a dedicated sub-account) on an ECN account with raw spreads (0.0 to 0.2 pips on EUR/USD) and set a live spread-filter alert so you never execute when spreads widen past 0.5 pips on majors or $0.25 on XAU/USD before your next London session.
Enforce Fixed Fractional & Daily Drawdown Limits: Lock your default order-ticket risk at 0.25% to 0.50% ($25 to $50 per trade) with a hard daily loss limit of 1.5% ($150), and commit to executing 50 consecutive sample trades exclusively during the London Open and London–NY Overlap over the next 30 trading days.
Audit Expectancy & Activate Profit-Locked Scaling: After completing your 50-trade sample block, verify a minimum Profit Factor of 1.4+ and net expectancy greater than 0.3R per trade in your trade journal before activating the 50% profit-lock scaling rule for live lot expansion.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Forex scalping trading strategy for Gold (XAU/USD)
This complete, production-ready MQL5 Expert Advisor (XAUUSD_LiquidityScalper.mq5) automates the multi-timeframe liquidity sweep and micro-structure pullback strategy specifically calibrated for XAU/USD (Gold) on a Raw ECN execution feed.
Key Architectural Highlights for XAU/USD
Broker-Agnostic USD Price Math: Gold is quoted with either 2 decimals (0.01) or 3 decimals (0.001) depending on the broker. All spread filters, stop-loss bounds, and sweep tolerances in this EA are defined in exact USD price delta (e.g., $0.25 max spread, $1.20 to $3.50 stop-loss bounds) and converted dynamically to broker ticks.
ECN Commission-Adjusted Sizing: Lot size is calculated using SYMBOL_TRADE_TICK_VALUE, SYMBOL_TRADE_TICK_SIZE, and your exact round-turn ECN commission per lot (default $7.00), ensuring a $50 risk target includes commission drag.
Exponential Profit-Lock Scaling Engine: Tracks your baseline equity floor. Once profit reaches your trigger threshold (default +2.0%), the EA locks 50% of the gain into a protected floor and optionally scales position risk using a fraction of the unlocked profit cushion—while enforcing a hard daily drawdown circuit breaker (1.5% or 3 consecutive losses).
State-Tracked Partial Close & M15 Structural Trail: Automatically banks 50% of the position at +1.5R, moves the hard server-side stop-loss to Breakeven + Commission, trails the runner behind M15 structural swing highs/lows past +2.0R, and enforces a time stop on stalled trades.
Key Architectural Highlights for XAU/USD
Broker-Agnostic USD Price Math: Gold is quoted with either 2 decimals (0.01) or 3 decimals (0.001) depending on the broker. All spread filters, stop-loss bounds, and sweep tolerances in this EA are defined in exact USD price delta (e.g., $0.25 max spread, $1.20 to $3.50 stop-loss bounds) and converted dynamically to broker ticks.
ECN Commission-Adjusted Sizing: Lot size is calculated using SYMBOL_TRADE_TICK_VALUE, SYMBOL_TRADE_TICK_SIZE, and your exact round-turn ECN commission per lot (default $7.00), ensuring a $50 risk target includes commission drag.
Exponential Profit-Lock Scaling Engine: Tracks your baseline equity floor. Once profit reaches your trigger threshold (default +2.0%), the EA locks 50% of the gain into a protected floor and optionally scales position risk using a fraction of the unlocked profit cushion—while enforcing a hard daily drawdown circuit breaker (1.5% or 3 consecutive losses).
State-Tracked Partial Close & M15 Structural Trail: Automatically banks 50% of the position at +1.5R, moves the hard server-side stop-loss to Breakeven + Commission, trails the runner behind M15 structural swing highs/lows past +2.0R, and enforces a time stop on stalled trades.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Forex scalping trading strategy for Gold (XAU/USD)
Complete MQL5 Source Code (XAUUSD_LiquidityScalper.mq5)
Save the code below in MetaEditor 5 under MQL5/Experts/XAUUSD_LiquidityScalper.mq5 and compile (F7):
Save the code below in MetaEditor 5 under MQL5/Experts/XAUUSD_LiquidityScalper.mq5 and compile (F7):
Code: Select all
//+------------------------------------------------------------------+
//| XAUUSD_LiquidityScalper.mq5 |
//| Multi-Timeframe Liquidity Sweep & Pullback Scalping EA |
//| Calibrated for XAU/USD Raw ECN |
//+------------------------------------------------------------------+
#property copyright "XAUUSD Liquidity Scalper"
#property version "1.00"
#property strict
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>
//+------------------------------------------------------------------+
//| Input Parameters |
//+------------------------------------------------------------------+
input group "=== 1. Strategy & Setup Filters ==="
input bool InpEnableSweepSetup = true; // Enable Liquidity Sweep (False Breakout)
input bool InpEnablePullbackSetup = true; // Enable M15 EMA 20/50 Trend Pullback
input ENUM_TIMEFRAMES InpTriggerTF = PERIOD_M5; // Entry Trigger Timeframe (M5 or M15)
input int InpEmaFast = 20; // M15 Fast EMA Period
input int InpEmaSlow = 50; // M15 Slow EMA Period
input int InpAtrPeriod = 14; // M5 ATR Period for Stop Sizing
input int InpH4SwingLookback = 10; // H4 Bars Lookback for Structural High/Low
input double InpMaxSweepOvershootUSD = 2.50; // Max Liquidity Sweep Piercing ($ USD)
input double InpTouchToleranceUSD = 0.35; // Level / EMA Touch Tolerance ($ USD)
input group "=== 2. XAU/USD Stop-Loss & Target Calibration ==="
input double InpAtrStopMultiplier = 1.0; // ATR Multiplier Beyond Sweep/Pullback Wick
input double InpMinStopUSD = 1.20; // Minimum Structural Stop Distance ($ USD)
input double InpMaxStopUSD = 3.50; // Maximum Structural Stop Distance ($ USD)
input double InpPartialCloseRR = 1.5; // Partial Close & BE Trigger (R-Multiple)
input double InpPartialCloseRatio = 0.50; // Partial Close Volume Ratio (0.50 = 50%)
input double InpTrailStartRR = 2.0; // Start M15 Structural Trail (R-Multiple)
input double InpFinalTargetRR = 3.5; // Hard Take-Profit Target (R-Multiple)
input int InpTimeStopMinutes = 45; // Time Stop if Profit < 0.5R (Minutes, 0=Off)
input group "=== 3. Risk, ECN Commission & Profit-Lock Scaling ==="
input double InpBaseRiskPct = 0.50; // Baseline Risk Per Trade (% of Equity)
input double InpCommissionPerLotRT = 7.00; // Round-Turn ECN Commission Per 1.0 Lot ($)
input bool InpUseProfitLockScaling = true; // Enable Exponential Profit-Lock Scaling
input double InpProfitLockTriggerPct = 2.00; // Profit Gain % to Trigger 50% Equity Lock
input double InpUnlockedBufferRiskPct = 25.0; // % of Unlocked Profit Buffer Added to Risk
input double InpMaxScaledRiskPct = 1.25; // Hard Cap on Scaled Risk Per Trade (%)
input double InpMaxDailyDrawdownPct = 1.50; // Daily Loss Circuit Breaker (% of Day Start)
input int InpMaxDailyConsecLosses = 3; // Max Consecutive Losses Per Day
input group "=== 4. Raw ECN Spread & Session Windows (UTC/Server) ==="
input double InpMaxSpreadUSD = 0.25; // Max Allowed Live Spread ($ USD, e.g. $0.25)
input int InpAsianStartHour = 0; // Asian Session Start Hour (Server Time)
input int InpAsianEndHour = 7; // Asian Session End Hour (Server Time)
input bool InpTradeLondonSession = true; // Trade London Open Window
input int InpLondonStartHour = 7; // London Window Start Hour
input int InpLondonEndHour = 10; // London Window End Hour
input bool InpTradeNYOverlap = true; // Trade London-NY Overlap Window
input int InpNYStartHour = 12; // NY Overlap Start Hour
input int InpNYEndHour = 16; // NY Overlap End Hour
input ulong InpMagicNumber = 20260888; // EA Magic Number
input int InpSlippagePoints = 15; // Max Deviation in Points
//+------------------------------------------------------------------+
//| Global Objects & State Variables |
//+------------------------------------------------------------------+
CTrade g_trade;
CPositionInfo g_posInfo;
CSymbolInfo g_symInfo;
int g_hEmaFastM15 = INVALID_HANDLE;
int g_hEmaSlowM15 = INVALID_HANDLE;
int g_hAtrM5 = INVALID_HANDLE;
datetime g_lastTriggerBarTime = 0;
int g_currentDayOfYear = -1;
// Risk & Profit-Lock State
double g_dayStartEquity = 0.0;
double g_baseReferenceEq = 0.0;
double g_lockedEquityFloor = 0.0;
int g_dailyConsecLosses = 0;
bool g_dailyHalted = false;
// Liquidity Pool Cache
double g_pdh = 0.0;
double g_pdl = 0.0;
double g_asianHigh = 0.0;
double g_asianLow = 0.0;
double g_h4SwingHigh = 0.0;
double g_h4SwingLow = 0.0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(!g_symInfo.Name(_Symbol))
return(INIT_FAILED);
g_symInfo.RefreshRates();
g_trade.SetExpertMagicNumber(InpMagicNumber);
g_trade.SetDeviationInPoints(InpSlippagePoints);
g_trade.SetTypeFillingBySymbol(_Symbol);
g_trade.SetAsyncMode(false);
g_hEmaFastM15 = iMA(_Symbol, PERIOD_M15, InpEmaFast, 0, MODE_EMA, PRICE_CLOSE);
g_hEmaSlowM15 = iMA(_Symbol, PERIOD_M15, InpEmaSlow, 0, MODE_EMA, PRICE_CLOSE);
g_hAtrM5 = iATR(_Symbol, PERIOD_M5, InpAtrPeriod);
if(g_hEmaFastM15 == INVALID_HANDLE || g_hEmaSlowM15 == INVALID_HANDLE || g_hAtrM5 == INVALID_HANDLE)
{
Print("Error creating indicator handles: ", GetLastError());
return(INIT_FAILED);
}
double eq = AccountInfoDouble(ACCOUNT_EQUITY);
g_dayStartEquity = eq;
g_baseReferenceEq = eq;
g_lockedEquityFloor = eq * (1.0 - InpMaxDailyDrawdownPct / 100.0);
MqlDateTime dt;
TimeCurrent(dt);
g_currentDayOfYear = dt.day_of_year;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if(g_hEmaFastM15 != INVALID_HANDLE) IndicatorRelease(g_hEmaFastM15);
if(g_hEmaSlowM15 != INVALID_HANDLE) IndicatorRelease(g_hEmaSlowM15);
if(g_hAtrM5 != INVALID_HANDLE) IndicatorRelease(g_hAtrM5);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
if(!g_symInfo.RefreshRates())
return;
// 1. Daily Reset & Circuit Breaker Audit
CheckDailyResetAndDrawdown();
// 2. Manage Any Open Position (Partial Close, BE, Structural Trail, Time Stop)
if(HasOpenPosition())
{
ManageOpenPositions();
return; // One active position at a time on XAU/USD
}
if(g_dailyHalted)
return;
// 3. Evaluate Entry Signals Strictly on New Trigger Bar Close
datetime currentBarTime = iTime(_Symbol, InpTriggerTF, 0);
if(currentBarTime == g_lastTriggerBarTime)
return;
// Check Session Filter
if(!IsWithinActiveSession())
return;
// Check Live Spread Filter ($ USD)
double liveSpreadUSD = g_symInfo.Ask() - g_symInfo.Bid();
if(liveSpreadUSD > InpMaxSpreadUSD)
return;
g_lastTriggerBarTime = currentBarTime;
// 4. Refresh H4/D1 & Asian Session Liquidity Pools
UpdateLiquidityPools();
// 5. Fetch Indicator Values
double emaFast[2], emaSlow[2], atrM5[2];
if(CopyBuffer(g_hEmaFastM15, 0, 1, 2, emaFast) < 2) return;
if(CopyBuffer(g_hEmaSlowM15, 0, 1, 2, emaSlow) < 2) return;
if(CopyBuffer(g_hAtrM5, 0, 1, 1, atrM5) < 1) return;
double currentAtr = atrM5[0];
double slPrice = 0.0;
// 6. Check Setup 1: Liquidity Sweep (False Breakout of Key Level)
if(InpEnableSweepSetup)
{
if(CheckBullishSweep(currentAtr, slPrice))
{
ExecuteTrade(ORDER_TYPE_BUY, slPrice, "XAU_Sweep_Buy");
return;
}
if(CheckBearishSweep(currentAtr, slPrice))
{
ExecuteTrade(ORDER_TYPE_SELL, slPrice, "XAU_Sweep_Sell");
return;
}
}
// 7. Check Setup 2: M15 EMA 20/50 Trend Pullback + Micro BoS
if(InpEnablePullbackSetup)
{
// Note: CopyBuffer index 1 is bar [1] (most recently closed M15 bar)
double m15Fast = emaFast[1];
double m15Slow = emaSlow[1];
if(CheckBullishPullback(m15Fast, m15Slow, currentAtr, slPrice))
{
ExecuteTrade(ORDER_TYPE_BUY, slPrice, "XAU_Pullback_Buy");
return;
}
if(CheckBearishPullback(m15Fast, m15Slow, currentAtr, slPrice))
{
ExecuteTrade(ORDER_TYPE_SELL, slPrice, "XAU_Pullback_Sell");
return;
}
}
}
//+------------------------------------------------------------------+
//| Track Closed Deals for Consecutive Losses & Profit-Lock Scaling |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
if(trans.type != TRADE_TRANSACTION_DEAL_ADD)
return;
if(!HistoryDealSelect(trans.deal))
return;
ulong magic = (ulong)HistoryDealGetInteger(trans.deal, DEAL_MAGIC);
string sym = HistoryDealGetString(trans.deal, DEAL_SYMBOL);
long entry = HistoryDealGetInteger(trans.deal, DEAL_ENTRY);
if(magic != InpMagicNumber || sym != _Symbol || entry != DEAL_ENTRY_OUT)
return;
double netProfit = HistoryDealGetDouble(trans.deal, DEAL_PROFIT)
+ HistoryDealGetDouble(trans.deal, DEAL_COMMISSION)
+ HistoryDealGetDouble(trans.deal, DEAL_SWAP);
// Ignore partial closes when counting full-trade consecutive losses
if(netProfit < -1.0)
g_dailyConsecLosses++;
else if(netProfit > 1.0)
g_dailyConsecLosses = 0;
// Update Profit-Lock Exponential Floor if threshold reached
double eq = AccountInfoDouble(ACCOUNT_EQUITY);
double gainPct = ((eq - g_baseReferenceEq) / g_baseReferenceEq) * 100.0;
if(InpUseProfitLockScaling && gainPct >= InpProfitLockTriggerPct)
{
double gainedUSD = eq - g_baseReferenceEq;
g_lockedEquityFloor = g_baseReferenceEq + (gainedUSD * 0.50);
g_baseReferenceEq = eq;
PrintFormat("Profit-Lock Triggered! New Locked Equity Floor: $%.2f | New Reference: $%.2f",
g_lockedEquityFloor, g_baseReferenceEq);
}
}
//+------------------------------------------------------------------+
//| Daily Reset & Circuit Breaker Audit |
//+------------------------------------------------------------------+
void CheckDailyResetAndDrawdown()
{
MqlDateTime dt;
TimeCurrent(dt);
double eq = AccountInfoDouble(ACCOUNT_EQUITY);
if(dt.day_of_year != g_currentDayOfYear)
{
g_currentDayOfYear = dt.day_of_year;
g_dayStartEquity = eq;
g_dailyConsecLosses = 0;
g_dailyHalted = false;
}
if(g_dailyHalted)
return;
double dailyDDPct = ((g_dayStartEquity - eq) / g_dayStartEquity) * 100.0;
if(dailyDDPct >= InpMaxDailyDrawdownPct)
{
g_dailyHalted = true;
PrintFormat("Circuit Breaker: Max Daily Drawdown (%.2f%%) reached. Trading halted for today.", dailyDDPct);
}
else if(g_dailyConsecLosses >= InpMaxDailyConsecLosses)
{
g_dailyHalted = true;
PrintFormat("Circuit Breaker: %d Consecutive Losses reached. Trading halted for today.", g_dailyConsecLosses);
}
}
//+------------------------------------------------------------------+
//| Update PDH/PDL, Asian Session High/Low, and H4 Structural Swings |
//+------------------------------------------------------------------+
void UpdateLiquidityPools()
{
// 1. Previous Day High & Low (D1 Bar 1)
g_pdh = iHigh(_Symbol, PERIOD_D1, 1);
g_pdl = iLow(_Symbol, PERIOD_D1, 1);
// 2. H4 Structural Swing High & Low (Last N closed H4 bars)
int h4HighIdx = iHighest(_Symbol, PERIOD_H4, MODE_HIGH, InpH4SwingLookback, 1);
int h4LowIdx = iLowest(_Symbol, PERIOD_H4, MODE_LOW, InpH4SwingLookback, 1);
if(h4HighIdx != -1) g_h4SwingHigh = iHigh(_Symbol, PERIOD_H4, h4HighIdx);
if(h4LowIdx != -1) g_h4SwingLow = iLow(_Symbol, PERIOD_H4, h4LowIdx);
// 3. Asian Session High & Low (Calculated from M15 bars today)
MqlDateTime dt;
TimeCurrent(dt);
dt.hour = InpAsianStartHour;
dt.min = 0;
dt.sec = 0;
datetime asianStart = StructToTime(dt);
dt.hour = InpAsianEndHour;
datetime asianEnd = StructToTime(dt);
g_asianHigh = 0.0;
g_asianLow = DBL_MAX;
for(int i = 1; i < 100; i++)
{
datetime barTime = iTime(_Symbol, PERIOD_M15, i);
if(barTime < asianStart)
break;
if(barTime >= asianStart && barTime < asianEnd)
{
double h = iHigh(_Symbol, PERIOD_M15, i);
double l = iLow(_Symbol, PERIOD_M15, i);
if(h > g_asianHigh) g_asianHigh = h;
if(l < g_asianLow) g_asianLow = l;
}
}
if(g_asianLow == DBL_MAX) g_asianLow = 0.0;
}
//+------------------------------------------------------------------+
//| Check Bullish Liquidity Sweep (False Breakout of Support) |
//+------------------------------------------------------------------+
bool CheckBullishSweep(double atr, double &outSlPrice)
{
double open1 = iOpen(_Symbol, InpTriggerTF, 1);
double close1 = iClose(_Symbol, InpTriggerTF, 1);
double high1 = iHigh(_Symbol, InpTriggerTF, 1);
double low1 = iLow(_Symbol, InpTriggerTF, 1);
double low2 = iLow(_Symbol, InpTriggerTF, 2);
double high2 = iHigh(_Symbol, InpTriggerTF, 2);
// Require bullish displacement body on bar [1] and micro break above high[2] or strong engulfing
double range1 = high1 - low1;
double body1 = close1 - open1;
if(range1 <= 0.0 || body1 <= 0.45 * range1)
return(false);
double sweepLow = MathMin(low1, low2);
double levels[3] = { g_pdl, g_asianLow, g_h4SwingLow };
for(int i = 0; i < 3; i++)
{
double lvl = levels[i];
if(lvl <= 0.0) continue;
// Price pierced below support level by up to InpMaxSweepOvershootUSD and closed back above it
double overshoot = lvl - sweepLow;
if(overshoot > 0.0 && overshoot <= InpMaxSweepOvershootUSD && close1 > lvl && (close1 > high2 || body1 > 0.60 * range1))
{
outSlPrice = sweepLow - (atr * InpAtrStopMultiplier);
return(true);
}
}
return(false);
}
//+------------------------------------------------------------------+
//| Check Bearish Liquidity Sweep (False Breakout of Resistance) |
//+------------------------------------------------------------------+
bool CheckBearishSweep(double atr, double &outSlPrice)
{
double open1 = iOpen(_Symbol, InpTriggerTF, 1);
double close1 = iClose(_Symbol, InpTriggerTF, 1);
double high1 = iHigh(_Symbol, InpTriggerTF, 1);
double low1 = iLow(_Symbol, InpTriggerTF, 1);
double high2 = iHigh(_Symbol, InpTriggerTF, 2);
double low2 = iLow(_Symbol, InpTriggerTF, 2);
double range1 = high1 - low1;
double body1 = open1 - close1;
if(range1 <= 0.0 || body1 <= 0.45 * range1)
return(false);
double sweepHigh = MathMax(high1, high2);
double levels[3] = { g_pdh, g_asianHigh, g_h4SwingHigh };
for(int i = 0; i < 3; i++)
{
double lvl = levels[i];
if(lvl <= 0.0) continue;
// Price pierced above resistance level and closed decisively back below it
double overshoot = sweepHigh - lvl;
if(overshoot > 0.0 && overshoot <= InpMaxSweepOvershootUSD && close1 < lvl && (close1 < low2 || body1 > 0.60 * range1))
{
outSlPrice = sweepHigh + (atr * InpAtrStopMultiplier);
return(true);
}
}
return(false);
}
//+------------------------------------------------------------------+
//| Check Bullish Trend Pullback into M15 EMA 20/50 Zone |
//+------------------------------------------------------------------+
bool CheckBullishPullback(double emaFast, double emaSlow, double atr, double &outSlPrice)
{
if(emaFast <= emaSlow)
return(false);
double open1 = iOpen(_Symbol, InpTriggerTF, 1);
double close1 = iClose(_Symbol, InpTriggerTF, 1);
double high1 = iHigh(_Symbol, InpTriggerTF, 1);
double low1 = iLow(_Symbol, InpTriggerTF, 1);
double high2 = iHigh(_Symbol, InpTriggerTF, 2);
double low2 = iLow(_Symbol, InpTriggerTF, 2);
double pullbackLow = MathMin(low1, low2);
// Pullback touched or dipped into EMA 20 zone while holding above EMA 50, then broke above bar [2] high
bool touchedValueZone = (pullbackLow <= emaFast + InpTouchToleranceUSD) && (pullbackLow >= emaSlow - InpTouchToleranceUSD);
bool bullishBoS = (close1 > open1) && (close1 > emaFast) && (close1 > high2);
if(touchedValueZone && bullishBoS)
{
outSlPrice = pullbackLow - (atr * InpAtrStopMultiplier);
return(true);
}
return(false);
}
//+------------------------------------------------------------------+
//| Check Bearish Trend Pullback into M15 EMA 20/50 Zone |
//+------------------------------------------------------------------+
bool CheckBearishPullback(double emaFast, double emaSlow, double atr, double &outSlPrice)
{
if(emaFast >= emaSlow)
return(false);
double open1 = iOpen(_Symbol, InpTriggerTF, 1);
double close1 = iClose(_Symbol, InpTriggerTF, 1);
double high1 = iHigh(_Symbol, InpTriggerTF, 1);
double low1 = iLow(_Symbol, InpTriggerTF, 1);
double high2 = iHigh(_Symbol, InpTriggerTF, 2);
double low2 = iLow(_Symbol, InpTriggerTF, 2);
double pullbackHigh = MathMax(high1, high2);
bool touchedValueZone = (pullbackHigh >= emaFast - InpTouchToleranceUSD) && (pullbackHigh <= emaSlow + InpTouchToleranceUSD);
bool bearishBoS = (close1 < open1) && (close1 < emaFast) && (close1 < low2);
if(touchedValueZone && bearishBoS)
{
outSlPrice = pullbackHigh + (atr * InpAtrStopMultiplier);
return(true);
}
return(false);
}
//+------------------------------------------------------------------+
//| Execute Order with Commission-Adjusted & Profit-Lock Lot Sizing |
//+------------------------------------------------------------------+
void ExecuteTrade(ENUM_ORDER_TYPE orderType, double rawSlPrice, string comment)
{
g_symInfo.RefreshRates();
double entryPrice = (orderType == ORDER_TYPE_BUY) ? g_symInfo.Ask() : g_symInfo.Bid();
double slDistUSD = MathAbs(entryPrice - rawSlPrice);
// Clamp Stop-Loss distance to XAU/USD structural bounds ($1.20 to $3.50)
if(slDistUSD < InpMinStopUSD)
slDistUSD = InpMinStopUSD;
else if(slDistUSD > InpMaxStopUSD)
return; // Skip trade if structural stop is too wide for a scalp
double slPrice = (orderType == ORDER_TYPE_BUY)
? NormalizeDouble(entryPrice - slDistUSD, _Digits)
: NormalizeDouble(entryPrice + slDistUSD, _Digits);
double tpDistUSD = slDistUSD * InpFinalTargetRR;
double tpPrice = (orderType == ORDER_TYPE_BUY)
? NormalizeDouble(entryPrice + tpDistUSD, _Digits)
: NormalizeDouble(entryPrice - tpDistUSD, _Digits);
double lots = CalculatePositionLots(slDistUSD);
if(lots <= 0.0)
return;
if(orderType == ORDER_TYPE_BUY)
g_trade.Buy(lots, _Symbol, entryPrice, slPrice, tpPrice, comment);
else
g_trade.Sell(lots, _Symbol, entryPrice, slPrice, tpPrice, comment);
}
//+------------------------------------------------------------------+
//| Calculate Exact Lots Factoring ECN Commission & Profit-Lock |
//+------------------------------------------------------------------+
double CalculatePositionLots(double slDistUSD)
{
double eq = AccountInfoDouble(ACCOUNT_EQUITY);
double riskUSD = eq * (InpBaseRiskPct / 100.0);
// Apply Exponential Profit-Lock Scaling if active and above locked floor
if(InpUseProfitLockScaling && eq > g_lockedEquityFloor)
{
double unlockedProfit = MathMax(0.0, eq - g_baseReferenceEq);
if(unlockedProfit > 0.0)
{
double bonusRiskUSD = unlockedProfit * (InpUnlockedBufferRiskPct / 100.0);
double maxRiskUSD = eq * (InpMaxScaledRiskPct / 100.0);
riskUSD = MathMin(riskUSD + bonusRiskUSD, maxRiskUSD);
}
}
double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
if(tickSize <= 0.0 || tickValue <= 0.0)
return(0.0);
// Price loss per 1.0 standard lot + Round-Turn ECN Commission per 1.0 lot
double priceLossPerLot = (slDistUSD / tickSize) * tickValue;
double totalLossPerLot = priceLossPerLot + InpCommissionPerLotRT;
if(totalLossPerLot <= 0.0)
return(0.0);
double rawLots = riskUSD / totalLossPerLot;
double stepLots = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
double minLots = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLots = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double lots = MathFloor(rawLots / stepLots) * stepLots;
if(lots < minLots) return(0.0);
if(lots > maxLots) lots = maxLots;
// Verify Free Margin
double marginRequired = 0.0;
if(!OrderCalcMargin(ORDER_TYPE_BUY, _Symbol, lots, g_symInfo.Ask(), marginRequired) ||
marginRequired > AccountInfoDouble(ACCOUNT_MARGIN_FREE))
{
Print("Insufficient free margin for calculated lot size: ", lots);
return(0.0);
}
return(NormalizeDouble(lots, 2));
}
//+------------------------------------------------------------------+
//| Manage Open Positions: Partial Close, BE+Comm, Trail & Time Stop |
//+------------------------------------------------------------------+
void ManageOpenPositions()
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(!g_posInfo.SelectByIndex(i)) continue;
if(g_posInfo.Symbol() != _Symbol || g_posInfo.Magic() != InpMagicNumber) continue;
ulong ticket = g_posInfo.Ticket();
double openPrice = g_posInfo.PriceOpen();
double currentSL = g_posInfo.StopLoss();
double currentTP = g_posInfo.TakeProfit();
double volume = g_posInfo.Volume();
ENUM_POSITION_TYPE posType = g_posInfo.PositionType();
double currentPrice = (posType == POSITION_TYPE_BUY) ? g_symInfo.Bid() : g_symInfo.Ask();
double profitDist = (posType == POSITION_TYPE_BUY) ? (currentPrice - openPrice) : (openPrice - currentPrice);
// Recover initial 1R distance from TakeProfit distance
double initialRiskDist = (currentTP > 0.0) ? (MathAbs(currentTP - openPrice) / InpFinalTargetRR) : InpMinStopUSD;
if(initialRiskDist <= 0.0) initialRiskDist = InpMinStopUSD;
double currentR = profitDist / initialRiskDist;
// 1. Time Stop Check: Close if open > InpTimeStopMinutes and profit < 0.5R
if(InpTimeStopMinutes > 0)
{
int elapsedSec = (int)(TimeCurrent() - g_posInfo.Time());
if(elapsedSec >= InpTimeStopMinutes * 60 && currentR < 0.5)
{
g_trade.PositionClose(ticket);
PrintFormat("Time Stop executed on Ticket #%I64u after %d mins (R = %.2f)", ticket, InpTimeStopMinutes, currentR);
continue;
}
}
// 2. Partial Close at +1.5R & Move Stop-Loss to Breakeven + Commission Buffer
string gvKey = "XAU_PARTIAL_" + IntegerToString(ticket);
if(currentR >= InpPartialCloseRR && !GlobalVariableCheck(gvKey))
{
double stepLots = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
double minLots = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double closeLots = MathFloor((volume * InpPartialCloseRatio) / stepLots) * stepLots;
if(closeLots >= minLots && (volume - closeLots) >= minLots)
g_trade.PositionClosePartial(ticket, NormalizeDouble(closeLots, 2));
// Move SL to Breakeven + $0.15 Commission/Spread Offset
double commOffsetUSD = 0.15;
double newSL = (posType == POSITION_TYPE_BUY)
? NormalizeDouble(openPrice + commOffsetUSD, _Digits)
: NormalizeDouble(openPrice - commOffsetUSD, _Digits);
if((posType == POSITION_TYPE_BUY && newSL > currentSL) ||
(posType == POSITION_TYPE_SELL && (currentSL == 0.0 || newSL < currentSL)))
{
g_trade.PositionModify(ticket, newSL, currentTP);
}
GlobalVariableSet(gvKey, 1.0);
}
// 3. M15 Structural Trailing Stop once trade reaches +2.0R
if(currentR >= InpTrailStartRR)
{
double trailBuffer = 0.20; // $0.20 buffer beyond last closed M15 candle
if(posType == POSITION_TYPE_BUY)
{
double m15Low = iLow(_Symbol, PERIOD_M15, 1) - trailBuffer;
double newSL = NormalizeDouble(m15Low, _Digits);
if(newSL > currentSL && newSL < currentPrice)
g_trade.PositionModify(ticket, newSL, currentTP);
}
else
{
double m15High = iHigh(_Symbol, PERIOD_M15, 1) + trailBuffer;
double newSL = NormalizeDouble(m15High, _Digits);
if((currentSL == 0.0 || newSL < currentSL) && newSL > currentPrice)
g_trade.PositionModify(ticket, newSL, currentTP);
}
}
}
}
//+------------------------------------------------------------------+
//| Helper: Check if EA Has an Active Open Position on Symbol |
//+------------------------------------------------------------------+
bool HasOpenPosition()
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(g_posInfo.SelectByIndex(i))
if(g_posInfo.Symbol() == _Symbol && g_posInfo.Magic() == InpMagicNumber)
return(true);
}
return(false);
}
//+------------------------------------------------------------------+
//| Helper: Verify Active London or NY Overlap Window |
//+------------------------------------------------------------------+
bool IsWithinActiveSession()
{
MqlDateTime dt;
TimeCurrent(dt);
bool inLondon = InpTradeLondonSession && (dt.hour >= InpLondonStartHour && dt.hour < InpLondonEndHour);
bool inNY = InpTradeNYOverlap && (dt.hour >= InpNYStartHour && dt.hour < InpNYEndHour);
return(inLondon || inNY);
}
//+------------------------------------------------------------------+Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.