Code: Select all
//+------------------------------------------------------------------+
//| Liquidity_Sweeps_H4_D1.mq5 |
//| Mechanical MT5 Indicator |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_plots 0
input int InpSwingBars = 5; // Fractal Swing Length (Bars left & right)
input int InpHistory = 300; // Number of HTF bars to scan
input color InpColorD1 = clrCrimson; // D1 Liquidity Color
input color InpColorH4 = clrDarkOrange; // H4 Liquidity Color
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit() {
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
ObjectsDeleteAll(0, "LiqPool_");
}
//+------------------------------------------------------------------+
//| 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[]) {
// Only recalculate on a new bar to save CPU cycles
if(rates_total == prev_calculated) return rates_total;
// Clear old lines before mapping current structure
ObjectsDeleteAll(0, "LiqPool_");
MapLiquidity(PERIOD_D1, "D1", InpColorD1, STYLE_SOLID, 2);
MapLiquidity(PERIOD_H4, "H4", InpColorH4, STYLE_DASH, 1);
ChartRedraw(0);
return(rates_total);
}
//+------------------------------------------------------------------+
//| Core logic to find and draw HTF liquidity pools |
//+------------------------------------------------------------------+
void MapLiquidity(ENUM_TIMEFRAMES tf, string prefix, color clr, int style, int width) {
double h[], l[];
datetime t[];
ArraySetAsSeries(h, true);
ArraySetAsSeries(l, true);
ArraySetAsSeries(t, true);
if(CopyHigh(Symbol(), tf, 0, InpHistory, h) < InpHistory) return;
if(CopyLow(Symbol(), tf, 0, InpHistory, l) < InpHistory) return;
if(CopyTime(Symbol(), tf, 0, InpHistory, t) < InpHistory) return;
// Scan for strict structural extremes
for(int i = InpSwingBars; i < InpHistory - InpSwingBars; i++) {
bool isRes = true;
bool isSup = true;
for(int j = 1; j <= InpSwingBars; j++) {
if(h[i] <= h[i-j] || h[i] <= h[i+j]) isRes = false;
if(l[i] >= l[i-j] || l[i] >= l[i+j]) isSup = false;
}
if(isRes) DrawLine("LiqPool_" + prefix + "_Res_" + TimeToString(t[i]), t[i], h[i], clr, style, width);
if(isSup) DrawLine("LiqPool_" + prefix + "_Sup_" + TimeToString(t[i]), t[i], l[i], clr, style, width);
}
}
//+------------------------------------------------------------------+
//| Renders a horizontal trendline (ray) from the exact origin point |
//+------------------------------------------------------------------+
void DrawLine(string name, datetime time, double price, color clr, int style, int width) {
// OBJ_TREND with RAY_RIGHT acts as a horizontal line that doesn't clutter past price action
if(ObjectCreate(0, name, OBJ_TREND, 0, time, price, time + PeriodSeconds(PERIOD_CURRENT)*10, price)) {
ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, true);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, name, OBJPROP_STYLE, style);
ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
ObjectSetInteger(0, name, OBJPROP_BACK, true); // Keeps candlesticks on top
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false); // Prevents accidental deletion
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
}
}
//+------------------------------------------------------------------+