mql5/Experts/_FrameWork/Analysers/Liquidity/EqualLiquidity.mqh
younglubah-gmail a4b935d8d8
2026-09-30 09:06:59 +02:00

137 lines
5.6 KiB
MQL5

//+------------------------------------------------------------------+
//| EqualLiquidity.mqh |
//| Copyright 2026, Concrete Goonies |
//| https://concrete-goonies.web.app |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Concrete Goonies"
#property link "https://concrete-goonies.web.app"
#property version "1.00"
#include "AbstractLiquidity.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class EqualLiquidity : public AbstractLiquidity {
private:
bool HasRequiredInternalSwingsForEqh(datetime leftIndex, datetime rightIndex) {
return CountSwingHighsBetween(leftIndex, rightIndex) > configs.eqConfigs.minSwingCount;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool HasRequiredInternalSwingsForEql(datetime leftIndex, datetime rightIndex) {
return CountSwingLowsBetween(leftIndex, rightIndex) > configs.eqConfigs.minSwingCount;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool IsCleanEQH(datetime leftTime, datetime rightTime, double pointAPrice, double tolerance) {
if(leftTime >= rightTime)
return false;
// If any historical swing high between the two points exceeded the threshold, invalidate EQH
for(int i = 0; i < state.m_swingHighs.Size(); i++) {
TimePrice sh = state.m_swingHighs.At(i);
if(sh.x > leftTime && sh.x < rightTime) {
if(sh.y > pointAPrice + tolerance)
return false;
}
}
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool IsCleanEQL(datetime leftTime, datetime rightTime, double pointAPrice, double tolerance) {
if(leftTime >= rightTime)
return false;
// If any historical swing low between the two points fell below the threshold, invalidate EQL
for(int i = 0; i < state.m_swingLows.Size(); i++) {
TimePrice sl = state.m_swingLows.At(i);
if(sl.x > leftTime && sl.x < rightTime) {
if(sl.y < pointAPrice - tolerance)
return false;
}
}
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
public:
EqualLiquidity() {}
~EqualLiquidity() {}
virtual string GetAnalyserName() override {
return "EqualLiquidity";
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
virtual void OnSwing(TimePrice &swing, bool isHigh)override {
double tolerance = configs.eqConfigs.tolerance;
int maxTimeDiff = configs.eqConfigs.lookBack ;
if(isHigh) {
for(int i = 0; i < state.m_swingHighs.Size() - 1; i++) {
TimePrice oldSwing = state.m_swingHighs.At(i);
if(oldSwing.x == swing.x)
break;
int k = Bars(bar.symbol, bar.tf, oldSwing.x, swing.x);
if(k > maxTimeDiff)
continue;
if(!NearPrice(oldSwing.y, swing.y, tolerance))
continue;
if(!HasRequiredInternalSwingsForEqh(oldSwing.x, swing.x))
continue;
if(!IsCleanEQH(oldSwing.x, swing.x, oldSwing.y, tolerance))
continue;
string name = "EQH_" + IntegerToString((int)oldSwing.x) + "_" + IntegerToString((int)swing.x);
// CreateTrendL(name, oldSwing.x, oldSwing.y, swing.x, swing.y, clrRed);
EqualLiquidityEvent* e = new EqualLiquidityEvent(bar.symbol, bar.tf, BSL, oldSwing.x, oldSwing.y, swing.x, swing.y);
eventBus.Push(e);
}
} else {
for(int i = 0; i < state.m_swingLows.Size() - 1; i++) {
TimePrice oldSwing = state.m_swingLows.At(i);
if(oldSwing.x == swing.x)
break;
int k = Bars(bar.symbol, bar.tf, oldSwing.x, swing.x);
if(k > maxTimeDiff)
continue;
if(!NearPrice(oldSwing.y, swing.y, tolerance))
continue;
if(!HasRequiredInternalSwingsForEql(oldSwing.x, swing.x))
continue;
if(!IsCleanEQL(oldSwing.x, swing.x, oldSwing.y, tolerance))
continue;
string name = "EQL_" + IntegerToString((int)oldSwing.x) + "_" + IntegerToString((int)swing.x);
// CreateTrendL(name, oldSwing.x, oldSwing.y, swing.x, swing.y, clrDodgerBlue);
EqualLiquidityEvent* e = new EqualLiquidityEvent(bar.symbol, bar.tf, SSL, oldSwing.x, oldSwing.y, swing.x, swing.y);
eventBus.Push(e);
}
}
}
};
//+------------------------------------------------------------------+