Files
MQL5Data/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5
T
2025-09-21 10:35:47 +03:30

456 lines
10 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class
// -------------------------------------------------
// Name: XCXFIMAPoiDetector ...
// Description: XFIMA POI Detector Class ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XFIMA POI Detector Class"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.base.class.mq5"
#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5"
#include "../../Classes/x-saherelm.x-market.pattern.class.mq5"
#include "../Libraries/x-saherelm.xfima.lib.mq5"
//
// Implementation ...
class XCXFIMAPOIDetector : public XCMarketPatternDetector
{
//
// Public ...
public:
//
// Props ...
XCBarAnalyser *barAnalyser; // Bar Analyser ...
//
// Constructor ...
XCXFIMAPOIDetector()
{
//
barAnalyser = new XCBarAnalyser();
}
//
// Deconstructor ...
~XCXFIMAPOIDetector()
{
Destroy();
}
//
// Actions and Tools ...
/**
* Get Specified Number of Recent ZigZag Points ...
*
* @param bar: XOHCL, Specified Bar for Start ...
* @param fimaHelper: XCXFIMAHelper, instance of XFIMA Helper ...
* @param zigzagPoints: XZigZagPoint, Array of Founded Points ...
* @param numberOfRequiredPivots: int, Specified Number of required ZigZag Points ...
*
* @return ( int )
*/
int GetZigZagPivot(
XOHCL &bar,
XCXFIMAHelper *&fimaHelper,
XZigZagPivot &zigzagPivots[],
int numberOfRequiredPivots = 5 //
)
{
//
int result = 0;
//
// Normalize ...
SpecifiedClean(zigzagPivots);
numberOfRequiredPivots = NormalizeInt(numberOfRequiredPivots, 3);
//
// Validate ...
result = bar.IsValid() &&
bar.symbol == fimaHelper.GetSymbol() &&
bar.period == fimaHelper.GetPeriod();
if (!result)
{
return result;
}
//
// Update Fima Helper ...
int index = bar.Index();
fimaHelper.Update(index);
//
// Start Reading ZigZag Values ...
double iZG = 0;
double iPZG = 0;
int iZGIdx = -1;
int iPZGIdx = -1;
bool has = false;
int start = index;
XZigZagPivot iZGPoint;
datetime iZGTime = NULL;
datetime iPZGTime = NULL;
int lastZGDetected = start;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
ENUM_X_ZIGZAG_POINT_TYPE iType = X_ZIGZAG_PIVOT_TYPE_NONE;
while (ArraySize(zigzagPivots) < numberOfRequiredPivots)
{
//
// Reading Last two ZigZag Value ...
//
// Detect Last ZG Value ...
has = GetZigZagValue(lastZGDetected, iZG, iZGIdx, iZGTime, fimaHelper);
if (!has)
{
//
iZG = 0;
iPZG = 0;
iZGIdx = -1;
iPZGIdx = -1;
iZGTime = NULL;
iPZGTime = NULL;
iZGPoint.Clean();
iDir = X_DIRECTION_NONE;
iType = X_ZIGZAG_PIVOT_TYPE_NONE;
//
start++;
lastZGDetected++;
//
continue;
}
//
// Detect Previous ZG Value ...
has = GetZigZagValue(lastZGDetected + 1, iPZG, iPZGIdx, iPZGTime, fimaHelper);
if (!has)
{
//
iZG = 0;
iPZG = 0;
iZGIdx = -1;
iPZGIdx = -1;
iZGTime = NULL;
iPZGTime = NULL;
iZGPoint.Clean();
iDir = X_DIRECTION_NONE;
iType = X_ZIGZAG_PIVOT_TYPE_NONE;
//
start++;
lastZGDetected++;
//
continue;
}
//
// Check Direction ...
iDir =
(iZG > iPZG)
? X_DIRECTION_BULLISH
: (iZG < iPZG)
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
// Check Point Type ...
iType =
IsSpecifiedBullish(iDir)
? X_ZIGZAG_PIVOT_TYPE_PEAK
: IsSpecifiedBearish(iDir)
? X_ZIGZAG_PIVOT_TYPE_VALE
: X_ZIGZAG_PIVOT_TYPE_NONE;
has =
IsXValid(iType) &&
HasDirection(iDir);
if (!has)
{
//
iZG = 0;
iPZG = 0;
iZGIdx = -1;
iPZGIdx = -1;
iZGTime = NULL;
iPZGTime = NULL;
iZGPoint.Clean();
iDir = X_DIRECTION_NONE;
iType = X_ZIGZAG_PIVOT_TYPE_NONE;
//
start++;
lastZGDetected++;
//
continue;
}
//
// Initialize ZigZag Point ...
has = iZGPoint.Init(
iZG,
iZGTime,
bar.symbol,
iDir,
bar.period,
iType //
);
if (has)
{
//
iZGPoint.AddIfNotExists(zigzagPivots);
lastZGDetected = iZGIdx + 1;
}
//
// Reset Resources ...
iZG = 0;
iPZG = 0;
iZGIdx = -1;
iPZGIdx = -1;
iZGTime = NULL;
iPZGTime = NULL;
iZGPoint.Clean();
iDir = X_DIRECTION_NONE;
iType = X_ZIGZAG_PIVOT_TYPE_NONE;
//
start++;
}
//
result = ArraySize(zigzagPivots);
//
return result;
}
//
bool AnalyseMarketUsingZigZag(
XOHCL &bar,
ENUM_TIMEFRAMES forPeriod,
XCXFIMAHelper *&fimaHelper,
XZigZagAnalysis &analysis,
int numberOfRequiredPivots = 20 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Normalize ...
numberOfRequiredPivots = NormalizeInt(numberOfRequiredPivots, 5);
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = bar.period;
}
//
// Reading XZigZag Points ...
XOHCL iPeriodBar;
result = iPeriodBar.Init(
bar.symbol,
forPeriod,
bar.Index() //
);
if (!result)
{
//
iPeriodBar.Clean();
return result;
}
//
// Reading Required Pivots ...
XZigZagPivot pivots[];
int pivotsCount = GetZigZagPivot(
iPeriodBar,
fimaHelper,
pivots,
numberOfRequiredPivots //
);
result = IsValidSize(pivotsCount);
if (!result)
{
//
analysis.Clean();
iPeriodBar.Clean();
SpecifiedClean(pivots);
}
//
// Initialize Analysis Model ...
result = analysis.Analyse(
bar,
pivots //
);
if (!result)
{
//
analysis.Clean();
iPeriodBar.Clean();
SpecifiedClean(pivots);
}
//
return result;
}
//
// Tools ...
/**
* Destroy ...
*/
void Destroy()
{
//
delete barAnalyser;
ZeroMemory(barAnalyser);
}
//
// Protected ...
protected:
//
// Props ...
//
// Tools / Actions ...
/**
* Read Specified Value of ZigZag ...
*
* @param fromBarIndex: int, Specified Start Bar Index ...
* @param value: double, reference to Hold ZigZag Value ...
* @param index: int, reference to Hold ZigZag Value's Bar Index ...
* @param time: datetime, reference to Hold ZigZag Value's Time ...
* @param maxAllowedLoopback: int, Maximum Allowe Loopback to Detect Specified Point ...
*
* @return ( bool )
*/
bool GetZigZagValue(
int fromBarIndex,
double &value,
int &index,
datetime &time,
XCXFIMAHelper *&fimaHelper,
int maxAllowedLoopback = 100 //
)
{
//
bool result = false;
//
// Normalize ...
fromBarIndex = NormalizeInt(fromBarIndex, 0);
maxAllowedLoopback = NormalizeInt(maxAllowedLoopback, 10, 100);
//
// Prepare ...
value = 0;
index = -1;
time = NULL;
//
// Validate ...
result = fimaHelper != NULL;
if (!result)
{
return result;
}
//
int start = fromBarIndex;
int end = start + maxAllowedLoopback;
while (start < end)
{
//
fimaHelper.Update(start);
//
value = fimaHelper.GetZigZag(start);
result = value > 0 && value != EMPTY_VALUE;
if (result)
{
//
time = GetBarTime(
fimaHelper.GetSymbol(),
fimaHelper.GetPeriod(),
start //
);
//
index = start;
//
break;
}
//
value = 0;
index = -1;
time = NULL;
//
start++;
}
//
result =
value > 0 &&
IsValidIndex(index) &&
value != EMPTY_VALUE &&
IsSpecifiedValid(time);
if (!result)
{
//
value = 0;
index = -1;
time = NULL;
}
//
return result;
}
//
// Private ...
private:
//
//
};
//