mql5/Experts/_FrameWork/Analysers/Chapter3.mqh

204 lines
6.8 KiB
MQL5

2026-09-30 09:06:59 +02:00
//+------------------------------------------------------------------+
//| Chapter3.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 "Liquidity/EqualLiquidity.mqh"
#include "Liquidity/StructuralLiquidity.mqh"
#include "Liquidity/MomentumShiftLiquidity.mqh"
2026-10-26 06:27:09 +02:00
#include "Liquidity/TrendlineLiquidity.mqh"
#include "Liquidity/ImbalanceLiquidity.mqh"
//#include "Liquidity/TrendlineLiquidity.mqh"
// 1. Hyperparameters (Inputs)
input double InpMomMaxPercent = 60.0; // MS: Max Percent
input double InpMomMinPercent = 45.0; // MS: Min Percent
input int InpMomTolerancePoints = 50; // MS: Tolerance (Points)
input int InpMomMaxSwingCount = 10; // MS: Max Pullback Swings
2026-09-30 09:06:59 +02:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class Chapter3: public AbstractAnalyser {
private:
Indicator* ind;
TimeFrameDataSeries* bar;
CArrayList<AbstractLiquidity*>* liquidityScanners;
LiquidityConfigs configs;
CArrayList<LiqState*>* states;
LiqState* activeState;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
TimePrice MakeSwingHigh(int i) {
TimePrice tp;
tp.i = i;
tp.x = bar.Time(i);
tp.y = bar.High(i);
return tp;
}
//---
TimePrice MakeSwingLow(int i) {
TimePrice tp;
tp.i = i;
tp.x = bar.Time(i);
tp.y = bar.Low(i);
return tp;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int FindExist(string symbol, ENUM_TIMEFRAMES tf) {
for(int i = 0; i < states.Size(); i++) {
LiqState* data = states.At(i);
if(data.symbol == symbol && data.tf == tf)
return i;
}
return -1;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void DetectAndNotifySwings(int i) {
if(IsSwingHigh(i, ind)) {
TimePrice swing = MakeSwingHigh(i);
if(!activeState.HasSwingAt(swing.x, true)) {
ZigzagSwing s;
s.point = swing;
s.isHigh = true;
activeState.m_swings.Add(s);
activeState.m_swingHighs.Add(swing);
for(int j = 0; j < liquidityScanners.Size(); j++)
liquidityScanners.At(j).OnSwing(swing, true);
}
}
//+------------------------------------------------------------------+
if(IsSwingLow(i, ind)) {
TimePrice swing = MakeSwingLow(i);
if(!activeState.HasSwingAt(swing.x, false)) {
ZigzagSwing s;
s.point = swing;
s.isHigh = false;
activeState.m_swings.Add(s);
activeState.m_swingLows.Add(swing);
for(int j = 0; j < liquidityScanners.Size(); j++)
liquidityScanners.At(j).OnSwing(swing, false);
}
}
}
public:
Chapter3() {
liquidityScanners = new CArrayList<AbstractLiquidity*>();
// AbstractLiquidity* eqLiq = new EqualLiquidity();
// liquidityScanners.Add(eqLiq);
//AbstractLiquidity* structLiq = new StructuralLiquidity();
//liquidityScanners.Add(structLiq);
2026-10-26 06:27:09 +02:00
//AbstractLiquidity* momShiftLiq = new MomentumShiftLiquidity();
// liquidityScanners.Add(momShiftLiq);
//AbstractLiquidity* trendLiq = new TrendlineLiquidity();
// liquidityScanners.Add(trendLiq);
AbstractLiquidity* imbLiq = new ImbalanceLiquidity();
liquidityScanners.Add(imbLiq);
2026-09-30 09:06:59 +02:00
configs.eqConfigs.tolerance = 150000 * _Point;
configs.eqConfigs.minSwingCount = 0;
configs.eqConfigs.lookBack = 75;
configs.structConfigs.lookBack = 5;
configs.structConfigs.maxPercent = 60;
configs.structConfigs.minPercent = 45;
2026-10-26 06:27:09 +02:00
2026-09-30 09:06:59 +02:00
//configs.momShiftConfigs.lookBack = 5;
2026-10-26 06:27:09 +02:00
// 3. Configuration Initialization
configs.momShiftConfigs.maxPercent = InpMomMaxPercent;
configs.momShiftConfigs.minPercent = InpMomMinPercent;
configs.momShiftConfigs.tolerance = InpMomTolerancePoints * _Point; // Converted to price format
configs.momShiftConfigs.maxSwingCount = InpMomMaxSwingCount;
2026-09-30 09:06:59 +02:00
states = new CArrayList<LiqState*>();
}
~Chapter3() {
for(int i = 0; i < liquidityScanners.Size(); i++) {
AbstractLiquidity* liquidityScanner = liquidityScanners.At(i);
delete liquidityScanner;
}
for(int i = 0; i < states.Size(); i++) {
LiqState* state = states.At(i);
delete state;
}
delete liquidityScanners;
delete states;
}
virtual void Init(EventBus* bus) {
AbstractAnalyser::Init(bus);
for(int i = 0; i < liquidityScanners.Size(); i++) {
AbstractLiquidity* liquidityScanner = liquidityScanners.At(i);
liquidityScanner.Init(bus);
liquidityScanner.SetConfigs(configs);
}
}
void SetConfigs(LiquidityConfigs &c) {
configs = c;
for(int i = 0; i < liquidityScanners.Size(); i++) {
liquidityScanners.At(i).SetConfigs(configs);
}
}
virtual string GetAnalyserName() override {
return "Chapter3";
}
virtual void ProcessBar(TimeFrameDataSeries* series, int i) override {
ind = series.GetIndicator(0);
bar = series;
int stateIndex = FindExist(series.symbol, series.tf);
if(stateIndex < 0) {
LiqState* s = new LiqState();
s.symbol = series.symbol;
s.tf = series.tf;
states.Add(s);
activeState = s;
} else {
activeState = states.At(stateIndex);
}
for(int j = 0; j < liquidityScanners.Size(); j++) {
AbstractLiquidity* liquidityScanner = liquidityScanners.At(j);
liquidityScanner.ProcessBar(activeState, ind, series, i);
}
DetectAndNotifySwings(i);
}
};
//+------------------------------------------------------------------+