For standard MT4 environments. It handles arrays and time series inherently differently, utilizing built-in functions like iHighest, iLowest, and TimeHour/TimeMinute for leaner legacy execution.
Code: Select all
//+------------------------------------------------------------------+
//| Pro_Liquidity_Sweep.mq4 |
//| Institutional PA & AAE Tracker |
//+------------------------------------------------------------------+
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_label1 "Bullish Sweep"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 MediumSeaGreen
#property indicator_width1 2
#property indicator_label2 "Bearish Sweep"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 Crimson
#property indicator_width2 2
extern string InpSessionStart = "08:00";
extern string InpSessionEnd = "16:30";
extern int InpSwingLen = 15;
extern double InpRRTarget = 2.0;
extern double InpStopBuffer = 0.2;
extern int InpAtrPeriod = 14;
double BullBuffer[];
double BearBuffer[];
int OnInit()
{
SetIndexBuffer(0, BullBuffer);
SetIndexBuffer(1, BearBuffer);
SetIndexArrow(0, 233);
SetIndexArrow(1, 234);
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
Comment("");
}
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 < InpSwingLen * 2) return 0;
int limit = rates_total - prev_calculated;
if(limit > rates_total - InpSwingLen - 1) limit = rates_total - InpSwingLen - 1;
if(prev_calculated == 0)
{
ArrayInitialize(BullBuffer, EMPTY_VALUE);
ArrayInitialize(BearBuffer, EMPTY_VALUE);
}
int totalTrades = 0, wins = 0;
double sumAAE = 0.0;
for(int i = limit; i >= 1; i--)
{
// 1. Session Filter
string currentHour = IntegerToString(TimeHour(time[i]), 2, '0');
string currentMin = IntegerToString(TimeMinute(time[i]), 2, '0');
string currentTime = currentHour + ":" + currentMin;
bool inSession = (currentTime >= InpSessionStart && currentTime <= InpSessionEnd);
if(!inSession) continue;
// 2. HTF Alignment
double dailyEMA = iMA(NULL, PERIOD_D1, 20, 0, MODE_EMA, PRICE_CLOSE, iBarShift(NULL, PERIOD_D1, time[i]));
bool htfBullish = close[i] > dailyEMA;
bool htfBearish = close[i] < dailyEMA;
// 3. Find Liquidity Pools
int highestIdx = iHighest(NULL, 0, MODE_HIGH, InpSwingLen, i + 1);
int lowestIdx = iLowest(NULL, 0, MODE_LOW, InpSwingLen, i + 1);
double liqHigh = high[highestIdx];
double liqLow = low[lowestIdx];
double atr = iATR(NULL, 0, InpAtrPeriod, i);
// 4. Sweep Logic
bool bullSweep = htfBullish && (low[i] < liqLow) && (close[i] > liqLow) && (close[i] > open[i]);
bool bearSweep = htfBearish && (high[i] > liqHigh) && (close[i] < liqHigh) && (close[i] < open[i]);
if(bullSweep)
{
BullBuffer[i] = low[i] - (atr * 0.5);
double entryPx = close[i];
double slPx = low[i] - (atr * InpStopBuffer);
double tpPx = entryPx + ((entryPx - slPx) * InpRRTarget);
double maxDrawdown = 0.0;
for(int j = i - 1; j >= 0; j--)
{
double currentDD = (entryPx - low[j]) / atr;
if(currentDD > maxDrawdown) maxDrawdown = currentDD;
if(high[j] >= tpPx) { totalTrades++; wins++; sumAAE += maxDrawdown; break; }
if(low[j] <= slPx) { totalTrades++; sumAAE += maxDrawdown; break; }
}
}
else if(bearSweep)
{
BearBuffer[i] = high[i] + (atr * 0.5);
double entryPx = close[i];
double slPx = high[i] + (atr * InpStopBuffer);
double tpPx = entryPx - ((slPx - entryPx) * InpRRTarget);
double maxDrawdown = 0.0;
for(int j = i - 1; j >= 0; j--)
{
double currentDD = (high[j] - entryPx) / atr;
if(currentDD > maxDrawdown) maxDrawdown = currentDD;
if(low[j] <= tpPx) { totalTrades++; wins++; sumAAE += maxDrawdown; break; }
if(high[j] >= slPx) { totalTrades++; sumAAE += maxDrawdown; break; }
}
}
}
// 5. Dashboard Output
if(totalTrades > 0)
{
double winRate = ((double)wins / totalTrades) * 100.0;
double avgAAE = sumAAE / totalTrades;
string dash = "--- SYSTEM ANALYTICS ---\n";
dash += "Total Setups: " + IntegerToString(totalTrades) + "\n";
dash += "Win Rate (" + DoubleToString(InpRRTarget, 1) + "R): " + DoubleToString(winRate, 2) + "%\n";
dash += "Avg Adverse Excursion: " + DoubleToString(avgAAE, 2) + " ATR";
Comment(dash);
}
return rates_total;
}