204 lines
6.8 KiB
MQL5
204 lines
6.8 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| 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"
| |
#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
| |
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
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);
| |
| |
//AbstractLiquidity* momShiftLiq = new MomentumShiftLiquidity();
| |
// liquidityScanners.Add(momShiftLiq);
| |
| |
//AbstractLiquidity* trendLiq = new TrendlineLiquidity();
| |
// liquidityScanners.Add(trendLiq);
| |
| |
AbstractLiquidity* imbLiq = new ImbalanceLiquidity();
| |
liquidityScanners.Add(imbLiq);
| |
| |
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;
| |
| |
//configs.momShiftConfigs.lookBack = 5;
| |
// 3. Configuration Initialization
| |
configs.momShiftConfigs.maxPercent = InpMomMaxPercent;
| |
configs.momShiftConfigs.minPercent = InpMomMinPercent;
| |
configs.momShiftConfigs.tolerance = InpMomTolerancePoints * _Point; // Converted to price format
| |
configs.momShiftConfigs.maxSwingCount = InpMomMaxSwingCount;
| |
| |
| |
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);
| |
}
| |
| |
};
| |
//+------------------------------------------------------------------+
|