Order Flow Imbalance Scalping
Order Flow Imbalance Scalping
Watch closely for moments when volume suddenly spikes alongside a strong, decisive candle that closes near its high (for bullish setups) or its low (for bearish setups). This combination often signals genuinely aggressive order flow entering the market — real participants committing capital with conviction, not just random noise.
The entry technique here relies on patience after spotting the imbalance. Rather than chasing the initial spike candle itself, which is often already extended, wait for price to retest the breakout level — essentially, wait for the market to come back and confirm the level holds as new support or resistance before committing.
Your stop-loss placement should sit just beyond the imbalance zone itself, on the assumption that if price pushes back through that zone with conviction, the original signal has failed and you should be out. This approach tends to work best in genuinely liquid major pairs during high-volume trading sessions — thin, illiquid conditions produce false imbalance signals far more often, since a single large order can create a misleading spike without real follow-through behind it.
As with any strategy, backtest this specifically on your chosen pairs and sessions before committing real capital, since imbalance behavior can differ meaningfully between, say, EUR/USD during London hours versus a more exotic pair during the Asian session.
The entry technique here relies on patience after spotting the imbalance. Rather than chasing the initial spike candle itself, which is often already extended, wait for price to retest the breakout level — essentially, wait for the market to come back and confirm the level holds as new support or resistance before committing.
Your stop-loss placement should sit just beyond the imbalance zone itself, on the assumption that if price pushes back through that zone with conviction, the original signal has failed and you should be out. This approach tends to work best in genuinely liquid major pairs during high-volume trading sessions — thin, illiquid conditions produce false imbalance signals far more often, since a single large order can create a misleading spike without real follow-through behind it.
As with any strategy, backtest this specifically on your chosen pairs and sessions before committing real capital, since imbalance behavior can differ meaningfully between, say, EUR/USD during London hours versus a more exotic pair during the Asian session.
It’s Fairman 
Re: Order Flow Imbalance Scalping
Hello Fairman.Fairman wrote: Fri Aug 21, 2026 9:57 pm Watch closely for moments when volume suddenly spikes alongside a strong, decisive candle that closes near its high (for bullish setups) or its low (for bearish setups). This combination often signals genuinely aggressive order flow entering the market — real participants committing capital with conviction, not just random noise.
The entry technique here relies on patience after spotting the imbalance. Rather than chasing the initial spike candle itself, which is often already extended, wait for price to retest the breakout level — essentially, wait for the market to come back and confirm the level holds as new support or resistance before committing.
Your stop-loss placement should sit just beyond the imbalance zone itself, on the assumption that if price pushes back through that zone with conviction, the original signal has failed and you should be out. This approach tends to work best in genuinely liquid major pairs during high-volume trading sessions — thin, illiquid conditions produce false imbalance signals far more often, since a single large order can create a misleading spike without real follow-through behind it.
As with any strategy, backtest this specifically on your chosen pairs and sessions before committing real capital, since imbalance behavior can differ meaningfully between, say, EUR/USD during London hours versus a more exotic pair during the Asian session.
I completely agree—this is a masterclass in patient, professional price action trading! What makes this approach so robust is that it shifts the focus away from FOMO-chasing and places it entirely on structural conviction and risk management.
Here is why this strategy stands out:
Noise Filtration: Combining a volume spike with a decisive closing candle ensures you're looking at genuine institutional footprints rather than random retail flickering.
The Retest Discipline: Waiting for price to return to the breakout level changes the game. Instead of chasing an extended move, you're buying or selling at a validated discount with a tight structural reference point.
Clear Invalidation: Tying the stop-loss directly to the imbalance zone removes emotional guesswork. If the market punches back through that zone, your thesis is simply proven wrong, and you exit cleanly.
Focusing on major pairs during high-volume windows (like the London and New York overlaps) is spot on, as thin liquidity can easily create fake-outs that trap impulsive traders.
Are you planning to test this strategy primarily on lower intraday timeframes (like the 5-minute chart), or are you looking at higher timeframe imbalances?
Re: Order Flow Imbalance Scalping
For me personally I think higher timeframe imbalances are betterFTtrader wrote: Wed Sep 02, 2026 8:54 pmHello Fairman.Fairman wrote: Fri Aug 21, 2026 9:57 pm Watch closely for moments when volume suddenly spikes alongside a strong, decisive candle that closes near its high (for bullish setups) or its low (for bearish setups). This combination often signals genuinely aggressive order flow entering the market — real participants committing capital with conviction, not just random noise.
The entry technique here relies on patience after spotting the imbalance. Rather than chasing the initial spike candle itself, which is often already extended, wait for price to retest the breakout level — essentially, wait for the market to come back and confirm the level holds as new support or resistance before committing.
Your stop-loss placement should sit just beyond the imbalance zone itself, on the assumption that if price pushes back through that zone with conviction, the original signal has failed and you should be out. This approach tends to work best in genuinely liquid major pairs during high-volume trading sessions — thin, illiquid conditions produce false imbalance signals far more often, since a single large order can create a misleading spike without real follow-through behind it.
As with any strategy, backtest this specifically on your chosen pairs and sessions before committing real capital, since imbalance behavior can differ meaningfully between, say, EUR/USD during London hours versus a more exotic pair during the Asian session.
I completely agree—this is a masterclass in patient, professional price action trading! What makes this approach so robust is that it shifts the focus away from FOMO-chasing and places it entirely on structural conviction and risk management.
Here is why this strategy stands out:
Noise Filtration: Combining a volume spike with a decisive closing candle ensures you're looking at genuine institutional footprints rather than random retail flickering.
The Retest Discipline: Waiting for price to return to the breakout level changes the game. Instead of chasing an extended move, you're buying or selling at a validated discount with a tight structural reference point.
Clear Invalidation: Tying the stop-loss directly to the imbalance zone removes emotional guesswork. If the market punches back through that zone, your thesis is simply proven wrong, and you exit cleanly.
Focusing on major pairs during high-volume windows (like the London and New York overlaps) is spot on, as thin liquidity can easily create fake-outs that trap impulsive traders.
Are you planning to test this strategy primarily on lower intraday timeframes (like the 5-minute chart), or are you looking at higher timeframe imbalances?
It’s Fairman 
Re: Order Flow Imbalance Scalping
Fairman wrote: Thu Sep 03, 2026 7:29 amFor me personally I think higher timeframe imbalances are better and also more reliableFTtrader wrote: Wed Sep 02, 2026 8:54 pmHello Fairman.Fairman wrote: Fri Aug 21, 2026 9:57 pm Watch closely for moments when volume suddenly spikes alongside a strong, decisive candle that closes near its high (for bullish setups) or its low (for bearish setups). This combination often signals genuinely aggressive order flow entering the market — real participants committing capital with conviction, not just random noise.
The entry technique here relies on patience after spotting the imbalance. Rather than chasing the initial spike candle itself, which is often already extended, wait for price to retest the breakout level — essentially, wait for the market to come back and confirm the level holds as new support or resistance before committing.
Your stop-loss placement should sit just beyond the imbalance zone itself, on the assumption that if price pushes back through that zone with conviction, the original signal has failed and you should be out. This approach tends to work best in genuinely liquid major pairs during high-volume trading sessions — thin, illiquid conditions produce false imbalance signals far more often, since a single large order can create a misleading spike without real follow-through behind it.
As with any strategy, backtest this specifically on your chosen pairs and sessions before committing real capital, since imbalance behavior can differ meaningfully between, say, EUR/USD during London hours versus a more exotic pair during the Asian session.
I completely agree—this is a masterclass in patient, professional price action trading! What makes this approach so robust is that it shifts the focus away from FOMO-chasing and places it entirely on structural conviction and risk management.
Here is why this strategy stands out:
Noise Filtration: Combining a volume spike with a decisive closing candle ensures you're looking at genuine institutional footprints rather than random retail flickering.
The Retest Discipline: Waiting for price to return to the breakout level changes the game. Instead of chasing an extended move, you're buying or selling at a validated discount with a tight structural reference point.
Clear Invalidation: Tying the stop-loss directly to the imbalance zone removes emotional guesswork. If the market punches back through that zone, your thesis is simply proven wrong, and you exit cleanly.
Focusing on major pairs during high-volume windows (like the London and New York overlaps) is spot on, as thin liquidity can easily create fake-outs that trap impulsive traders.
Are you planning to test this strategy primarily on lower intraday timeframes (like the 5-minute chart), or are you looking at higher timeframe imbalances?
It’s Fairman 
Re: Order Flow Imbalance Scalping
Order-flow imbalance is useful when it is treated as a confirmation layer, not as a standalone “see more buy prints → go long” reflex. On FX you often do not get a true exchange order book the way equity tape traders do, so I translate the idea into what I can actually observe: aggressive vs passive behavior at a level, failed auctions, and speed of reclaim after a sweep.
What I watch on M1/M5 (especially XAUUSD / EURUSD):
- Did price sweep a prior high/low and then reclaim with consecutive closes back inside the range? That is imbalance resolving, not just a thick bid label.
- Is the move continuing with expanding range and little pullback, or is it stalling into a known HTF level? Imbalance that dies into H1 supply is not a free continuation.
- Session context: London open and London–NY overlap produce cleaner imbalance reads than thin Asia noise for the pairs I trade.
My entry filter is still MTF first. H1 bias + M15 structure permission, then M5/M1 for the imbalance trigger. If H1 is clearly short and M1 shows a buy imbalance into resistance, I usually stand aside or take a half-size fade only when the reclaim fails — I do not fight HTF for a pretty DOM fantasy.
Risk notes that matter more than the buzzword:
- Slippage and spread widen exactly when imbalance is loud. Size off stop distance, not off how “obvious” the tape feels.
- Cap correlated risk if you stack gold + USDJPY on the same USD impulse.
- Invalidation is a candle close back through the sweep extreme or a time stop if the auction never continues.
Journal tag I use: ofi_confirm (Y/N) plus whether HTF agreed. Over a month you will see whether imbalance adds expectancy or just adds urgency. Urgency without permission is how scalpers overtrade the open. Keep the tool; lose the mystique.
When the book is synthetic or delayed, downgrade OFI to a secondary tell and lean harder on sweep-reclaim structure you can see on the chart alone.
What I watch on M1/M5 (especially XAUUSD / EURUSD):
- Did price sweep a prior high/low and then reclaim with consecutive closes back inside the range? That is imbalance resolving, not just a thick bid label.
- Is the move continuing with expanding range and little pullback, or is it stalling into a known HTF level? Imbalance that dies into H1 supply is not a free continuation.
- Session context: London open and London–NY overlap produce cleaner imbalance reads than thin Asia noise for the pairs I trade.
My entry filter is still MTF first. H1 bias + M15 structure permission, then M5/M1 for the imbalance trigger. If H1 is clearly short and M1 shows a buy imbalance into resistance, I usually stand aside or take a half-size fade only when the reclaim fails — I do not fight HTF for a pretty DOM fantasy.
Risk notes that matter more than the buzzword:
- Slippage and spread widen exactly when imbalance is loud. Size off stop distance, not off how “obvious” the tape feels.
- Cap correlated risk if you stack gold + USDJPY on the same USD impulse.
- Invalidation is a candle close back through the sweep extreme or a time stop if the auction never continues.
Journal tag I use: ofi_confirm (Y/N) plus whether HTF agreed. Over a month you will see whether imbalance adds expectancy or just adds urgency. Urgency without permission is how scalpers overtrade the open. Keep the tool; lose the mystique.
When the book is synthetic or delayed, downgrade OFI to a secondary tell and lean harder on sweep-reclaim structure you can see on the chart alone.
- Attachments
-
- 37-ofi-confirm-sketch.png (89.4 KiB) Viewed 17 times
It’s Fairman 
Re: Order Flow Imbalance Scalping
Hi Fairman, hi traders,Fairman wrote: Sat Sep 05, 2026 4:49 pm Order-flow imbalance is useful when it is treated as a confirmation layer, not as a standalone “see more buy prints → go long” reflex. On FX you often do not get a true exchange order book the way equity tape traders do, so I translate the idea into what I can actually observe: aggressive vs passive behavior at a level, failed auctions, and speed of reclaim after a sweep.
What I watch on M1/M5 (especially XAUUSD / EURUSD):
- Did price sweep a prior high/low and then reclaim with consecutive closes back inside the range? That is imbalance resolving, not just a thick bid label.
- Is the move continuing with expanding range and little pullback, or is it stalling into a known HTF level? Imbalance that dies into H1 supply is not a free continuation.
- Session context: London open and London–NY overlap produce cleaner imbalance reads than thin Asia noise for the pairs I trade.
My entry filter is still MTF first. H1 bias + M15 structure permission, then M5/M1 for the imbalance trigger. If H1 is clearly short and M1 shows a buy imbalance into resistance, I usually stand aside or take a half-size fade only when the reclaim fails — I do not fight HTF for a pretty DOM fantasy.
Risk notes that matter more than the buzzword:
- Slippage and spread widen exactly when imbalance is loud. Size off stop distance, not off how “obvious” the tape feels.
- Cap correlated risk if you stack gold + USDJPY on the same USD impulse.
- Invalidation is a candle close back through the sweep extreme or a time stop if the auction never continues.
Journal tag I use: ofi_confirm (Y/N) plus whether HTF agreed. Over a month you will see whether imbalance adds expectancy or just adds urgency. Urgency without permission is how scalpers overtrade the open. Keep the tool; lose the mystique.
When the book is synthetic or delayed, downgrade OFI to a secondary tell and lean harder on sweep-reclaim structure you can see on the chart alone.
When you don't have a centralized Level 2, translating OFI into structural behavior—specifically the velocity of a sweep and the immediate failure to hold outside the range—is the most reliable proxy we have. A legitimate imbalance that favors continuation won't immediately puke back inside the breakout zone. If it reclaims with consecutive closes, the initial aggressive prints were just smart money absorbing late retail breakout liquidity.
Your MTF filtering is the exact right safeguard here. Taking a 1-minute order-flow signal straight into an hourly supply zone is financial suicide. Using the tick volume spikes on the sweep candle combined with the HTF bias filters out about 80% of the noise.
Great framework. Keep the pragmatic approach; the tape is a tool, not a crystal ball.
MT4 Implementation: Sweep & Reclaim OFI Proxy
Here is an MQL4 Custom Indicator built around your exact logic. It identifies prior swing highs/lows, detects a sweep, waits for the structural reclaim, and filters the entire setup through a Higher Timeframe (HTF) moving average to ensure you have "permission" before plotting the trigger.
Code: Select all
//+------------------------------------------------------------------+
//| OFI_Sweep_Reclaim.mq4 |
//| Translates OFI/Sweep logic into MT4 signals |
//+------------------------------------------------------------------+
#property copyright "Algorithmic Trading Logic"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 clrDodgerBlue
#property indicator_color2 clrCrimson
//--- Inputs
input ENUM_TIMEFRAMES HTF_Period = PERIOD_H1; // Higher Timeframe Permission
input int HTF_MA_Period = 50; // HTF Trend Filter Period
input int Swing_Lookback = 20; // Lookback for Prior High/Low
input bool Require_Vol_Spike = true; // Require Tick Vol Expansion on Sweep
//--- Buffers
double ExtBuyBuffer[];
double ExtSellBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, ExtBuyBuffer);
SetIndexStyle(0, DRAW_ARROW);
SetIndexArrow(0, 233); // Up arrow
SetIndexLabel(0, "Sweep & Reclaim Buy");
SetIndexBuffer(1, ExtSellBuffer);
SetIndexStyle(1, DRAW_ARROW);
SetIndexArrow(1, 234); // Down arrow
SetIndexLabel(1, "Sweep & Reclaim Sell");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if(rates_total < Swing_Lookback + 2) return(0);
int limit = rates_total - prev_calculated;
if(prev_calculated == 0) limit = rates_total - Swing_Lookback - 3;
for(int i = limit; i >= 0; i--)
{
// Reset buffers
ExtBuyBuffer[i] = EMPTY_VALUE;
ExtSellBuffer[i] = EMPTY_VALUE;
// 1. Fetch HTF Permission (Aligning M1/M5 trigger with H1 bias)
int htf_shift = iBarShift(Symbol(), HTF_Period, time[i], false);
double htf_MA = iMA(Symbol(), HTF_Period, HTF_MA_Period, 0, MODE_EMA, PRICE_CLOSE, htf_shift);
bool htf_bullish = close[i] > htf_MA;
bool htf_bearish = close[i] < htf_MA;
// 2. Identify Prior Structure (Ignoring the current setup bars i and i+1)
int highest_idx = iHighest(Symbol(), 0, MODE_HIGH, Swing_Lookback, i+2);
int lowest_idx = iLowest(Symbol(), 0, MODE_LOW, Swing_Lookback, i+2);
if(highest_idx == -1 || lowest_idx == -1) continue;
double prior_high = high[highest_idx];
double prior_low = low[lowest_idx];
// 3. OFI Proxy: Did tick volume expand on the sweep? (Aggressive behavior)
bool vol_spike = true;
if(Require_Vol_Spike)
{
double avg_vol = 0;
for(int v = 2; v < 7; v++) avg_vol += (double)tick_volume[i+v];
avg_vol /= 5.0;
vol_spike = (double)tick_volume[i+1] > avg_vol;
}
// 4. SELL SETUP: Swept prior high, reclaimed below, HTF is bearish
if(htf_bearish && vol_spike)
{
bool swept_high = high[i+1] > prior_high; // Sweep
bool reclaimed = close[i] < prior_high && // Reclaim back inside
close[i] < open[i]; // Bearish close confirmation
if(swept_high && reclaimed)
{
ExtSellBuffer[i] = high[i] + (10 * Point); // Plot arrow slightly above
}
}
// 5. BUY SETUP: Swept prior low, reclaimed above, HTF is bullish
if(htf_bullish && vol_spike)
{
bool swept_low = low[i+1] < prior_low; // Sweep
bool reclaimed = close[i] > prior_low && // Reclaim back inside
close[i] > open[i]; // Bullish close confirmation
if(swept_low && reclaimed)
{
ExtBuyBuffer[i] = low[i] - (10 * Point); // Plot arrow slightly below
}
}
}
return(rates_total);
}
//+------------------------------------------------------------------+Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Order Flow Imbalance Scalping
How the Logic Maps to Your Framework:
The MTF Filter (htf_shift & iBarShift): It syncs perfectly regardless of whether you drop the indicator on M1 or M5. It accurately pulls the H1 EMA state at that exact historical moment so you don't repaint or "fight HTF for a pretty DOM fantasy."
The Structure Sweep (Swing_Lookback): It dynamically calculates the prior range extreme starting two bars back (i+2), ensuring it measures the previous structure, not the current spike.
The Reclaim (swept_low / swept_high): The logic explicitly requires the i+1 candle to pierce the level, and the i candle to close securely back inside the range.
The Imbalance/OFI Proxy (Require_Vol_Spike): Since MT4 uses tick volume, the script checks if the sweep candle had a surge in tick activity compared to a rolling 5-period average, simulating the "loud imbalance" you watch for before the failed auction.
The MTF Filter (htf_shift & iBarShift): It syncs perfectly regardless of whether you drop the indicator on M1 or M5. It accurately pulls the H1 EMA state at that exact historical moment so you don't repaint or "fight HTF for a pretty DOM fantasy."
The Structure Sweep (Swing_Lookback): It dynamically calculates the prior range extreme starting two bars back (i+2), ensuring it measures the previous structure, not the current spike.
The Reclaim (swept_low / swept_high): The logic explicitly requires the i+1 candle to pierce the level, and the i candle to close securely back inside the range.
The Imbalance/OFI Proxy (Require_Vol_Spike): Since MT4 uses tick volume, the script checks if the sweep candle had a surge in tick activity compared to a rolling 5-period average, simulating the "loud imbalance" you watch for before the failed auction.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Order Flow Imbalance Scalping
Here are the dedicated scripts for both MetaTrader 4 (MQL4) and MetaTrader 5 (MQL5).
The core logic is identical in both versions, but the MT5 version utilizes MQL5's specific array structures (ArraySetAsSeries), technical indicator handles (iMA handle initialized in OnInit), and CopyBuffer/CopyHigh/CopyLow functions to safely bridge the multi-timeframe moving average data.
1. MT4 Implementation (MQL4)
The core logic is identical in both versions, but the MT5 version utilizes MQL5's specific array structures (ArraySetAsSeries), technical indicator handles (iMA handle initialized in OnInit), and CopyBuffer/CopyHigh/CopyLow functions to safely bridge the multi-timeframe moving average data.
1. MT4 Implementation (MQL4)
Code: Select all
//+------------------------------------------------------------------+
//| OFI_Sweep_Reclaim_MT4.mq4 |
//+------------------------------------------------------------------+
#property copyright "Sweep & Reclaim Indicator"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 clrDodgerBlue
#property indicator_color2 clrCrimson
//--- Inputs
input ENUM_TIMEFRAMES HTF_Period = PERIOD_H1;
input int HTF_MA_Period = 50;
input int Swing_Lookback = 20;
input bool Require_Vol_Spike = true;
//--- Buffers
double ExtBuyBuffer[];
double ExtSellBuffer[];
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, ExtBuyBuffer);
SetIndexStyle(0, DRAW_ARROW);
SetIndexArrow(0, 233);
SetIndexLabel(0, "Sweep & Reclaim Buy");
SetIndexBuffer(1, ExtSellBuffer);
SetIndexStyle(1, DRAW_ARROW);
SetIndexArrow(1, 234);
SetIndexLabel(1, "Sweep & Reclaim Sell");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if(rates_total < Swing_Lookback + 2) return(0);
int limit = rates_total - prev_calculated;
if(prev_calculated == 0) limit = rates_total - Swing_Lookback - 3;
for(int i = limit; i >= 0; i--)
{
ExtBuyBuffer[i] = EMPTY_VALUE;
ExtSellBuffer[i] = EMPTY_VALUE;
// 1. Fetch HTF Permission
int htf_shift = iBarShift(Symbol(), HTF_Period, time[i], false);
double htf_MA = iMA(Symbol(), HTF_Period, HTF_MA_Period, 0, MODE_EMA, PRICE_CLOSE, htf_shift);
bool htf_bullish = close[i] > htf_MA;
bool htf_bearish = close[i] < htf_MA;
// 2. Identify Prior Structure
int highest_idx = iHighest(Symbol(), 0, MODE_HIGH, Swing_Lookback, i+2);
int lowest_idx = iLowest(Symbol(), 0, MODE_LOW, Swing_Lookback, i+2);
if(highest_idx == -1 || lowest_idx == -1) continue;
double prior_high = high[highest_idx];
double prior_low = low[lowest_idx];
// 3. OFI Proxy: Volume spike check
bool vol_spike = true;
if(Require_Vol_Spike)
{
double avg_vol = 0;
for(int v = 2; v < 7; v++) avg_vol += (double)tick_volume[i+v];
avg_vol /= 5.0;
vol_spike = (double)tick_volume[i+1] > avg_vol;
}
// 4. SELL SETUP
if(htf_bearish && vol_spike)
{
bool swept_high = high[i+1] > prior_high;
bool reclaimed = close[i] < prior_high && close[i] < open[i];
if(swept_high && reclaimed)
{
ExtSellBuffer[i] = high[i] + (10 * Point);
}
}
// 5. BUY SETUP
if(htf_bullish && vol_spike)
{
bool swept_low = low[i+1] < prior_low;
bool reclaimed = close[i] > prior_low && close[i] > open[i];
if(swept_low && reclaimed)
{
ExtBuyBuffer[i] = low[i] - (10 * Point);
}
}
}
return(rates_total);
}
//+------------------------------------------------------------------+Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Order Flow Imbalance Scalping
2. MT5 Implementation (MQL5)
Code: Select all
//+------------------------------------------------------------------+
//| OFI_Sweep_Reclaim_MT5.mq5 |
//+------------------------------------------------------------------+
#property copyright "Sweep & Reclaim Indicator"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
#property indicator_label1 "Sweep & Reclaim Buy"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrDodgerBlue
#property indicator_label2 "Sweep & Reclaim Sell"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrCrimson
//--- Inputs
input ENUM_TIMEFRAMES HTF_Period = PERIOD_H1;
input int HTF_MA_Period = 50;
input int Swing_Lookback = 20;
input bool Require_Vol_Spike = true;
//--- Buffers and Handles
double ExtBuyBuffer[];
double ExtSellBuffer[];
int ma_handle;
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, ExtBuyBuffer, INDICATOR_DATA);
PlotIndexSetInteger(0, PLOT_ARROW, 233);
SetIndexBuffer(1, ExtSellBuffer, INDICATOR_DATA);
PlotIndexSetInteger(1, PLOT_ARROW, 234);
// Initialize MA Handle
ma_handle = iMA(_Symbol, HTF_Period, HTF_MA_Period, 0, MODE_EMA, PRICE_CLOSE);
if(ma_handle == INVALID_HANDLE)
{
Print("Failed to create MA handle");
return INIT_FAILED;
}
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if(rates_total < Swing_Lookback + 2) return(0);
// Set timeseries array alignment (MT4 style)
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(ExtBuyBuffer, true);
ArraySetAsSeries(ExtSellBuffer, true);
int limit = rates_total - prev_calculated;
if(prev_calculated == 0)
{
limit = rates_total - Swing_Lookback - 3;
ArrayInitialize(ExtBuyBuffer, 0.0);
ArrayInitialize(ExtSellBuffer, 0.0);
}
double ma_val[];
ArraySetAsSeries(ma_val, true);
for(int i = limit; i >= 0 && !IsStopped(); i--)
{
ExtBuyBuffer[i] = 0.0;
ExtSellBuffer[i] = 0.0;
if(i + Swing_Lookback + 2 >= rates_total) continue;
// 1. Fetch HTF Permission (Sync to current bar time)
if(CopyBuffer(ma_handle, 0, time[i], 1, ma_val) <= 0) continue;
double htf_MA = ma_val[0];
bool htf_bullish = close[i] > htf_MA;
bool htf_bearish = close[i] < htf_MA;
// 2. Identify Prior Structure
double high_array[];
double low_array[];
if(CopyHigh(_Symbol, _Period, i+2, Swing_Lookback, high_array) <= 0) continue;
if(CopyLow(_Symbol, _Period, i+2, Swing_Lookback, low_array) <= 0) continue;
double prior_high = high_array[ArrayMaximum(high_array)];
double prior_low = low_array[ArrayMinimum(low_array)];
// 3. OFI Proxy: Volume spike check
bool vol_spike = true;
if(Require_Vol_Spike)
{
double avg_vol = 0;
for(int v = 2; v < 7; v++) avg_vol += (double)tick_volume[i+v];
avg_vol /= 5.0;
vol_spike = (double)tick_volume[i+1] > avg_vol;
}
// 4. SELL SETUP
if(htf_bearish && vol_spike)
{
bool swept_high = high[i+1] > prior_high;
bool reclaimed = close[i] < prior_high && close[i] < open[i];
if(swept_high && reclaimed)
{
ExtSellBuffer[i] = high[i] + (10 * _Point);
}
}
// 5. BUY SETUP
if(htf_bullish && vol_spike)
{
bool swept_low = low[i+1] < prior_low;
bool reclaimed = close[i] > prior_low && close[i] > open[i];
if(swept_low && reclaimed)
{
ExtBuyBuffer[i] = low[i] - (10 * _Point);
}
}
}
return(rates_total);
}
//+------------------------------------------------------------------+Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Order Flow Imbalance Scalping
Here is the translation of your sweep and reclaim logic into a cTrader custom indicator (cAlgo API in C#).
cTrader's architecture indexes bars in reverse compared to MT4 (the oldest bar is 0, the current bar is Bars.Count - 1), so the loop lookbacks and indexing have been inverted to match. It also uses MarketData.GetBars() to cleanly handle the multi-timeframe moving average without the repainting issues that often plague MT4.
Ctrader version:
cTrader's architecture indexes bars in reverse compared to MT4 (the oldest bar is 0, the current bar is Bars.Count - 1), so the loop lookbacks and indexing have been inverted to match. It also uses MarketData.GetBars() to cleanly handle the multi-timeframe moving average without the repainting issues that often plague MT4.
Ctrader version:
Code: Select all
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class OFI_Sweep_Reclaim : Indicator
{
[Parameter("HTF Timeframe", DefaultValue = "Hour")]
public TimeFrame HTF_Period { get; set; }
[Parameter("HTF MA Period", DefaultValue = 50, MinValue = 1)]
public int HTF_MA_Period { get; set; }
[Parameter("Swing Lookback", DefaultValue = 20, MinValue = 5)]
public int Swing_Lookback { get; set; }
[Parameter("Require Vol Spike", DefaultValue = true)]
public bool Require_Vol_Spike { get; set; }
// Output buffers allow easy programmatic access if you wrap this into a cBot later
[Output("Buy Signal", LineColor = "DodgerBlue", PlotType = PlotType.Points, Thickness = 4)]
public IndicatorDataSeries BuyBuffer { get; set; }
[Output("Sell Signal", LineColor = "Crimson", PlotType = PlotType.Points, Thickness = 4)]
public IndicatorDataSeries SellBuffer { get; set; }
private Bars _htfBars;
private ExponentialMovingAverage _htfMa;
protected override void Initialize()
{
// Initialize higher timeframe data and indicator
_htfBars = MarketData.GetBars(HTF_Period);
_htfMa = Indicators.ExponentialMovingAverage(_htfBars.ClosePrices, HTF_MA_Period);
}
public override void Calculate(int index)
{
// Ensure enough data is loaded to perform lookbacks
if (index < Swing_Lookback + 6)
return;
// 1. Fetch HTF Permission (Synchronize current bar time with HTF bar index)
int htfIndex = _htfBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
if (htfIndex < 0) return;
double htfMAValue = _htfMa.Result[htfIndex];
bool htf_bullish = Bars.ClosePrices[index] > htfMAValue;
bool htf_bearish = Bars.ClosePrices[index] < htfMAValue;
// 2. Identify Prior Structure (Looking back from index - 2)
double prior_high = double.MinValue;
double prior_low = double.MaxValue;
for (int i = 2; i < 2 + Swing_Lookback; i++)
{
int targetIndex = index - i;
if (Bars.HighPrices[targetIndex] > prior_high)
prior_high = Bars.HighPrices[targetIndex];
if (Bars.LowPrices[targetIndex] < prior_low)
prior_low = Bars.LowPrices[targetIndex];
}
// 3. OFI Proxy: Did tick volume expand on the sweep?
// Comparing sweep candle (index - 1) against the prior 5 candles
bool vol_spike = true;
if (Require_Vol_Spike)
{
double avg_vol = 0;
for (int v = 2; v <= 6; v++)
{
avg_vol += Bars.TickVolumes[index - v];
}
avg_vol /= 5.0;
vol_spike = Bars.TickVolumes[index - 1] > avg_vol;
}
// 4. SELL SETUP: Swept prior high, reclaimed below, HTF is bearish
if (htf_bearish && vol_spike)
{
bool swept_high = Bars.HighPrices[index - 1] > prior_high;
bool reclaimed = Bars.ClosePrices[index] < prior_high &&
Bars.ClosePrices[index] < Bars.OpenPrices[index];
if (swept_high && reclaimed)
{
SellBuffer[index] = Bars.HighPrices[index] + (10 * Symbol.PipSize);
// Optional: Draw a distinct arrow on the chart
Chart.DrawIcon("Sell" + index, ChartIconType.DownArrow, index, SellBuffer[index], Color.Crimson);
}
}
// 5. BUY SETUP: Swept prior low, reclaimed above, HTF is bullish
if (htf_bullish && vol_spike)
{
bool swept_low = Bars.LowPrices[index - 1] < prior_low;
bool reclaimed = Bars.ClosePrices[index] > prior_low &&
Bars.ClosePrices[index] > Bars.OpenPrices[index];
if (swept_low && reclaimed)
{
BuyBuffer[index] = Bars.LowPrices[index] - (10 * Symbol.PipSize);
// Optional: Draw a distinct arrow on the chart
Chart.DrawIcon("Buy" + index, ChartIconType.UpArrow, index, BuyBuffer[index], Color.DodgerBlue);
}
}
}
}
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.