1489 lines
41 KiB
Plaintext
1489 lines
41 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 ...
|
|
XCXFIMAHelper *fimaHelper; // XFIMA Helper ...
|
|
|
|
//
|
|
XBoxZone obs[];
|
|
XBoxZone fvgs[];
|
|
XBoxZone supports[];
|
|
XBoxZone resistances[];
|
|
|
|
//
|
|
// Constructor ...
|
|
XCXFIMAPOIDetector(
|
|
XCXFIMAHelper *_fimaHelper //
|
|
) : XCMarketPatternDetector()
|
|
{
|
|
//
|
|
barAnalyser = new XCBarAnalyser();
|
|
fimaHelper = _fimaHelper;
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XCXFIMAPOIDetector()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
//
|
|
// Actions and Tools ...
|
|
|
|
//
|
|
// Pivot Analysors ...
|
|
|
|
/**
|
|
* Analyse Market based on Specified Kind of Pivots ...
|
|
*
|
|
* @param analysis: XPivotAnalysis, reference to hold result ...
|
|
* @param barIndex: int, Bar Index ...
|
|
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
|
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
|
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AnalysePVPivots(
|
|
XPivotAnalysis &analysis,
|
|
int barIndex = 0,
|
|
int requiredNumberOFPivots = 50,
|
|
int maxAllowedLoopbackLength = 1500,
|
|
int validationLength = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
analysis.Clean();
|
|
|
|
//
|
|
// Reading Pivots ...
|
|
XPivot pivots[];
|
|
int count = ExtractPVPivots(
|
|
pivots, // Result ...
|
|
barIndex, // Bar Index ...
|
|
requiredNumberOFPivots, // Required Number of Pivots ...
|
|
maxAllowedLoopbackLength, // Max Allowed Loopback ...
|
|
validationLength // Validation Length ...
|
|
);
|
|
result = IsValidSize(count);
|
|
if (!result)
|
|
{
|
|
//
|
|
SpecifiedClean(pivots);
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = fimaHelper.GetSymbol();
|
|
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
|
|
|
|
//
|
|
// Initialize Analysis ...
|
|
result = analysis.Init(
|
|
"XFIMA_XPV",
|
|
symbol,
|
|
period,
|
|
pivots //
|
|
);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
if (!result)
|
|
{
|
|
analysis.Clean();
|
|
}
|
|
SpecifiedClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Analyse Market based on Specified Kind of Pivots ...
|
|
*
|
|
* @param analysis: XPivotAnalysis, reference to hold result ...
|
|
* @param barIndex: int, Bar Index ...
|
|
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
|
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
|
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AnalyseMAPivots(
|
|
XPivotAnalysis &analysis,
|
|
int barIndex = 0,
|
|
int requiredNumberOFPivots = 50,
|
|
int maxAllowedLoopbackLength = 1500,
|
|
int validationLength = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
analysis.Clean();
|
|
|
|
//
|
|
// Reading Pivots ...
|
|
XPivot pivots[];
|
|
int count = ExtractMAPivots(
|
|
pivots, // Result ...
|
|
barIndex, // Bar Index ...
|
|
requiredNumberOFPivots, // Required Number of Pivots ...
|
|
maxAllowedLoopbackLength, // Max Allowed Loopback ...
|
|
validationLength // Validation Length ...
|
|
);
|
|
result = IsValidSize(count);
|
|
if (!result)
|
|
{
|
|
//
|
|
SpecifiedClean(pivots);
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = fimaHelper.GetSymbol();
|
|
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
|
|
|
|
//
|
|
// Initialize Analysis ...
|
|
result = analysis.Init(
|
|
"XFIMA_XMA",
|
|
symbol,
|
|
period,
|
|
pivots //
|
|
);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
if (!result)
|
|
{
|
|
analysis.Clean();
|
|
}
|
|
SpecifiedClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Analyse Market based on Specified Kind of Pivots ...
|
|
*
|
|
* @param analysis: XPivotAnalysis, reference to hold result ...
|
|
* @param barIndex: int, Bar Index ...
|
|
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
|
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AnalyseSARPivots(
|
|
XPivotAnalysis &analysis,
|
|
int barIndex = 0,
|
|
int requiredNumberOFPivots = 50,
|
|
int maxAllowedLoopbackLength = 1500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
analysis.Clean();
|
|
|
|
//
|
|
// Reading Pivots ...
|
|
XPivot pivots[];
|
|
int count = ExtractSARPivots(
|
|
pivots, // Result ...
|
|
barIndex, // Bar Index ...
|
|
requiredNumberOFPivots, // Required Number of Pivots ...
|
|
maxAllowedLoopbackLength // Max Allowed Loopback ...
|
|
);
|
|
result = IsValidSize(count);
|
|
if (!result)
|
|
{
|
|
//
|
|
SpecifiedClean(pivots);
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = fimaHelper.GetSymbol();
|
|
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
|
|
|
|
//
|
|
// Initialize Analysis ...
|
|
result = analysis.Init(
|
|
"XFIMA_XSAR",
|
|
symbol,
|
|
period,
|
|
pivots //
|
|
);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
if (!result)
|
|
{
|
|
analysis.Clean();
|
|
}
|
|
SpecifiedClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Analyse Market based on Specified Kind of Pivots ...
|
|
*
|
|
* @param analysis: XPivotAnalysis, reference to hold result ...
|
|
* @param barIndex: int, Bar Index ...
|
|
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
|
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AnalyseZigZagPivots(
|
|
XPivotAnalysis &analysis,
|
|
int barIndex = 0,
|
|
int requiredNumberOFPivots = 50,
|
|
int maxAllowedLoopbackLength = 1500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
analysis.Clean();
|
|
|
|
//
|
|
// Reading Pivots ...
|
|
XPivot pivots[];
|
|
int count = ExtractZigZagPivots(
|
|
pivots, // Result ...
|
|
barIndex, // Bar Index ...
|
|
requiredNumberOFPivots, // Required Number of Pivots ...
|
|
maxAllowedLoopbackLength // Max Allowed Loopback ...
|
|
);
|
|
result = IsValidSize(count);
|
|
if (!result)
|
|
{
|
|
//
|
|
SpecifiedClean(pivots);
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = fimaHelper.GetSymbol();
|
|
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
|
|
|
|
//
|
|
// Initialize Analysis ...
|
|
result = analysis.Init(
|
|
"XFIMA_XZG",
|
|
symbol,
|
|
period,
|
|
pivots //
|
|
);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
if (!result)
|
|
{
|
|
analysis.Clean();
|
|
}
|
|
SpecifiedClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Pivot Extractors ...
|
|
|
|
/**
|
|
* Extract Specified Kind of Pivots ...
|
|
*
|
|
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
|
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
|
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ExtractPVPivots(
|
|
XPivot &pivots[],
|
|
int barIndex = 0,
|
|
int requiredNumberOFPivots = 50,
|
|
int maxAllowedLoopbackLength = 1500,
|
|
int validationLength = 0 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
result = fimaHelper.ExtractPVPivots(
|
|
pivots,
|
|
barIndex,
|
|
requiredNumberOFPivots,
|
|
maxAllowedLoopbackLength,
|
|
validationLength //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extract Specified Kind of Pivots ...
|
|
*
|
|
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
|
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
|
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ExtractMAPivots(
|
|
XPivot &pivots[],
|
|
int barIndex = 0,
|
|
int requiredNumberOFPivots = 50,
|
|
int maxAllowedLoopbackLength = 1500,
|
|
int validationLength = 0 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
result = fimaHelper.ExtractMAPivots(
|
|
pivots,
|
|
barIndex,
|
|
requiredNumberOFPivots,
|
|
maxAllowedLoopbackLength,
|
|
validationLength //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extract Specified Kind of Pivots ...
|
|
*
|
|
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
|
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ExtractSARPivots(
|
|
XPivot &pivots[],
|
|
int barIndex = 0,
|
|
int requiredNumberOFPivots = 50,
|
|
int maxAllowedLoopbackLength = 1500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
result = fimaHelper.ExtractSARPivots(
|
|
pivots,
|
|
barIndex,
|
|
requiredNumberOFPivots,
|
|
maxAllowedLoopbackLength //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extract Specified Kind of Pivots ...
|
|
*
|
|
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
|
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ExtractZigZagPivots(
|
|
XPivot &pivots[],
|
|
int barIndex = 0,
|
|
int requiredNumberOFPivots = 50,
|
|
int maxAllowedLoopbackLength = 1500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
result = fimaHelper.ExtractZigZagPivots(
|
|
pivots,
|
|
barIndex,
|
|
requiredNumberOFPivots,
|
|
maxAllowedLoopbackLength //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Destroy ...
|
|
*/
|
|
void Destroy()
|
|
{
|
|
//
|
|
SpecifiedClean(obs);
|
|
SpecifiedClean(fvgs);
|
|
SpecifiedClean(supports);
|
|
SpecifiedClean(resistances);
|
|
|
|
//
|
|
delete barAnalyser;
|
|
ZeroMemory(barAnalyser);
|
|
}
|
|
|
|
//
|
|
// Testers ...
|
|
|
|
/**
|
|
* Analyse Market based on Specified Bar ...
|
|
*
|
|
* @param forBar: XOHCL, reference Specified Bar for Analyse Market ...
|
|
* @param structure: XFIMAMarketStructure, reference to holds result ...
|
|
* @param config: XFIMAPatternDetectorConfig, reference to Configure Detector ...
|
|
*/
|
|
void AnalyseMarket(
|
|
XOHCL &forBar,
|
|
XFIMAMarketStructure &structure,
|
|
XFIMAPatternDetectorConfig &config //
|
|
)
|
|
{
|
|
//
|
|
// Prepare ...
|
|
structure.Clean();
|
|
|
|
//
|
|
// Validate ...
|
|
if (!forBar.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Do Analysis ...
|
|
|
|
//
|
|
structure.bar = forBar;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
XBoxZone iBox;
|
|
bool has = false;
|
|
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Detecting POI Based on Config ...
|
|
|
|
//
|
|
// Checking Momentum Bar ...
|
|
if (config.detectMomentum)
|
|
{
|
|
//
|
|
bool isMomentum = IsMomentumBar(
|
|
forBar,
|
|
iDir,
|
|
config.momentumBarRangeLength,
|
|
config.momentumBarApprovedMultiplier //
|
|
);
|
|
bool isBullishMomentum = isMomentum &&
|
|
IsSpecifiedBullish(iDir);
|
|
bool isBearishMomentum = isMomentum &&
|
|
IsSpecifiedBearish(iDir);
|
|
if (isMomentum)
|
|
{
|
|
structure.momentumDir = iDir;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Checking Engulfed Bar ...
|
|
if (config.detectEngulfed)
|
|
{
|
|
//
|
|
bool isEngulfed = IsEngulfedBar(
|
|
forBar,
|
|
iDir //
|
|
);
|
|
bool isBullishEngulfed = isEngulfed &&
|
|
IsSpecifiedBullish(iDir);
|
|
bool isBearishEngulfed = isEngulfed &&
|
|
IsSpecifiedBearish(iDir);
|
|
if (isEngulfed)
|
|
{
|
|
structure.engulfedDir = iDir;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Checking TruGaped Bar ...
|
|
if (config.detectTrueGaped)
|
|
{
|
|
//
|
|
bool isTrueGaped = IsTrueGapedBar(
|
|
forBar,
|
|
iDir,
|
|
config.truwGapApprovedPointMultiplier //
|
|
);
|
|
bool isBullishTrueGaped = isTrueGaped &&
|
|
IsSpecifiedBullish(iDir);
|
|
bool isBearishTrueGaped = isTrueGaped &&
|
|
IsSpecifiedBearish(iDir);
|
|
if (isTrueGaped)
|
|
{
|
|
structure.trueGapedDir = iDir;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Checking Pinned Bar ...
|
|
if (config.detectPinned)
|
|
{
|
|
//
|
|
bool isPinned = IsPinnedBar(
|
|
forBar,
|
|
iDir,
|
|
config.pinnedBaarShadowApprovedMultiplier,
|
|
config.pinnedBarMinimumPinBarRangeMultiplier,
|
|
config.pinnedBarForceDirection //
|
|
);
|
|
bool isBullishPinned = isPinned &&
|
|
IsSpecifiedBullish(iDir);
|
|
bool isBearishPinned = isPinned &&
|
|
IsSpecifiedBearish(iDir);
|
|
if (isPinned)
|
|
{
|
|
structure.pinnedDir = iDir;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Checking Star Pattern ...
|
|
if (config.detectStarPattern)
|
|
{
|
|
//
|
|
bool isStarPattern = IsStarPattern(
|
|
forBar,
|
|
iDir //
|
|
);
|
|
bool isBullishStarPattern = isStarPattern &&
|
|
IsSpecifiedBullish(iDir);
|
|
bool isBearishStarPattern = isStarPattern &&
|
|
IsSpecifiedBearish(iDir);
|
|
if (isStarPattern)
|
|
{
|
|
structure.starPatternDir = iDir;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Checking Piercing Pattern ...
|
|
if (config.detectPiercingPattern)
|
|
{
|
|
//
|
|
bool isPiercingPattern = IsPiercingPattern(
|
|
forBar,
|
|
iDir //
|
|
);
|
|
bool isBullishPiercingPattern = isPiercingPattern &&
|
|
IsSpecifiedBullish(iDir);
|
|
bool isBearishPiercingPattern = isPiercingPattern &&
|
|
IsSpecifiedBearish(iDir);
|
|
if (isPiercingPattern)
|
|
{
|
|
structure.piercingPatternDir = iDir;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Checking Rising Pattern ...
|
|
if (config.detectRisingPattern)
|
|
{
|
|
//
|
|
bool isRisingPattern = IsRisingPattern(
|
|
forBar,
|
|
iDir //
|
|
);
|
|
bool isBullishRisingPattern = isRisingPattern &&
|
|
IsSpecifiedBullish(iDir);
|
|
bool isBearishRisingPattern = isRisingPattern &&
|
|
IsSpecifiedBearish(iDir);
|
|
if (isRisingPattern)
|
|
{
|
|
structure.risingPatternDir = iDir;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Checking Flag Pattern ...
|
|
if (config.detectFlagPattern)
|
|
{
|
|
//
|
|
XOHCL swingBar;
|
|
bool isFlagPattern = IsFlagPattern(
|
|
forBar,
|
|
iDir,
|
|
swingBar,
|
|
config.flagPatternMinimumPullbackBars //
|
|
);
|
|
bool isBullishFlagPattern = isFlagPattern &&
|
|
IsSpecifiedBullish(iDir);
|
|
bool isBearishFlagPattern = isFlagPattern &&
|
|
IsSpecifiedBearish(iDir);
|
|
if (isFlagPattern)
|
|
{
|
|
//
|
|
structure.flagSwing = swingBar;
|
|
structure.flagPatternDir = iDir;
|
|
}
|
|
swingBar.Clean();
|
|
}
|
|
|
|
//
|
|
// Detect SignalKey Bar Pattern ...
|
|
if (config.detectSignalKeyBarPattern)
|
|
{
|
|
//
|
|
bool isSignalKeyBar = IsSignalKeyBarPattern(
|
|
forBar,
|
|
iDir,
|
|
config.signalKeyBarShadowApprovedMultiplier,
|
|
config.signalKeyBarMinimumPinBarRangeMultiplier,
|
|
config.signalKeyBarForceDirection //
|
|
);
|
|
bool isBullishSignalKeyBar = isSignalKeyBar &&
|
|
IsSpecifiedBullish(iDir);
|
|
bool isBearishSignalKeyBar = isSignalKeyBar &&
|
|
IsSpecifiedBearish(iDir);
|
|
if (isSignalKeyBar)
|
|
{
|
|
structure.signalKeyBarPatternDir = iDir;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Swing Trend ...
|
|
if (config.detectSwingTrend)
|
|
{
|
|
//
|
|
XOHCL swings[];
|
|
bool hasSwingTrend = HasSwingTrend(
|
|
forBar,
|
|
iDir,
|
|
swings,
|
|
config.trendingNumberOfSwings,
|
|
config.trendingSwingShoulders //
|
|
);
|
|
bool hasBullishSwingTrend = hasSwingTrend &&
|
|
IsSpecifiedBullish(iDir);
|
|
bool hasBearishSwingTrend = hasSwingTrend &&
|
|
IsSpecifiedBearish(iDir);
|
|
if (hasSwingTrend)
|
|
{
|
|
//
|
|
Copy(
|
|
swings,
|
|
structure.trendSwings //
|
|
);
|
|
structure.trendDir = iDir;
|
|
}
|
|
SpecifiedClean(swings);
|
|
}
|
|
|
|
//
|
|
// Custom Indicator Pivots ...
|
|
|
|
//
|
|
// Detecting MA Crosses ...
|
|
if (config.detectMACrosses)
|
|
{
|
|
//
|
|
idx = forBar.Index();
|
|
has = fimaHelper.HasMACross(
|
|
structure.maCrossDir,
|
|
idx,
|
|
config.validMACrossDiffMultiplier //
|
|
);
|
|
|
|
//
|
|
fimaHelper.ExtractMAPivots(
|
|
structure.maCrosses,
|
|
idx,
|
|
config.zonesRequiredNumber,
|
|
config.validMACrossDiffMultiplier,
|
|
config.zonesMaxAllowedLoopbackLength //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Detecting HK Switches ...
|
|
if (config.detectHKSwitches)
|
|
{
|
|
//
|
|
idx = forBar.Index();
|
|
has = fimaHelper.HasHKSwitch(
|
|
structure.hkSwitchDir,
|
|
idx //
|
|
);
|
|
|
|
//
|
|
fimaHelper.ExtractHKPivots(
|
|
structure.hkSwitches,
|
|
idx,
|
|
config.zonesRequiredNumber,
|
|
config.zonesMaxAllowedLoopbackLength //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Detecting SAR Switches ...
|
|
if (config.detectSARSwitches)
|
|
{
|
|
//
|
|
idx = forBar.Index();
|
|
has = fimaHelper.HasSARSwitch(
|
|
structure.sarSwitchDir,
|
|
idx //
|
|
);
|
|
|
|
//
|
|
fimaHelper.ExtractSARPivots(
|
|
structure.sarSwitches,
|
|
idx,
|
|
config.zonesRequiredNumber,
|
|
config.zonesMaxAllowedLoopbackLength //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Custom Analysers ...
|
|
|
|
//
|
|
// Analyse Based on PV ...
|
|
if (config.analyseFIMAPVPivots)
|
|
{
|
|
//
|
|
XPivotAnalysis analysis;
|
|
has = AnalysePVPivots(
|
|
analysis, // Result ...
|
|
forBar.Index(), // Bar Index ...
|
|
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
|
|
config.maxAllowedLoopbackLengthForAnalysis, // Max Allowed Loopback ...
|
|
config.pvPivotsValidationLength // Validation Length ...
|
|
);
|
|
if (has)
|
|
{
|
|
structure.pvAnalysis = analysis;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Analyse Based on ZigZag ...
|
|
if (config.analyseFIMAZigZagPivots)
|
|
{
|
|
//
|
|
XPivotAnalysis analysis;
|
|
has = AnalyseZigZagPivots(
|
|
analysis, // Result ...
|
|
forBar.Index(), // Bar Index ...
|
|
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
|
|
config.maxAllowedLoopbackLengthForAnalysis // Max Allowed Loopback ...
|
|
);
|
|
if (has)
|
|
{
|
|
structure.zigzagAnalysis = analysis;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Zones and Patterns Recent Actions ...
|
|
if (config.zonesRequiredNumber > 0 &&
|
|
config.zonesMaxAllowedLoopbackLength > 0)
|
|
{
|
|
//
|
|
// Detect Recent Patterns ...
|
|
|
|
//
|
|
XOHCL iBar;
|
|
XOHCL tmpBar;
|
|
XPivot iPivot;
|
|
XBoxZone iBox;
|
|
bool has = false;
|
|
string iPrefix = NULL;
|
|
int start = forBar.Index();
|
|
ENUM_X_SORT_BY iSortBy = X_SORT_BY_DATE;
|
|
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
|
ENUM_X_DIRECTION iSortDir = X_DIRECTION_BULLISH;
|
|
int end = start + config.zonesMaxAllowedLoopbackLength;
|
|
|
|
//
|
|
// Loop through Items ...
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
//
|
|
iPivot.Clean();
|
|
|
|
//
|
|
// Initialize Indexed Bar ...
|
|
has = forBar.BarAt(i, iBar);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// OB ...
|
|
has = HasOB(
|
|
iBar,
|
|
iDir,
|
|
iBox,
|
|
5 //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBox,
|
|
obs //
|
|
);
|
|
}
|
|
|
|
//
|
|
// FVG ...
|
|
has = HasFVG(
|
|
iBar,
|
|
iDir,
|
|
iBox,
|
|
5 //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBox,
|
|
fvgs //
|
|
);
|
|
}
|
|
|
|
//
|
|
// SUPPORT ...
|
|
tmpBar.Clean();
|
|
has = HasSupport(
|
|
iBar,
|
|
tmpBar,
|
|
config.zonesValidationLength,
|
|
config.zonesMaxAllowedLoopbackLength //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToSupportBox(tmpBar, iBox, iBar.time);
|
|
if (has)
|
|
{
|
|
//
|
|
// Check Strength ...
|
|
if (config.zonesMinAlloweStrength > 0)
|
|
{
|
|
has = (iBox.upper - iBox.lower) > (config.zonesMinAlloweStrength * GetPoints(iBar.symbol));
|
|
}
|
|
|
|
//
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBox,
|
|
supports //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
iBox.Clean();
|
|
tmpBar.Clean();
|
|
|
|
//
|
|
// RESISATNCE ...
|
|
tmpBar.Clean();
|
|
has = HasResistance(
|
|
iBar,
|
|
tmpBar,
|
|
config.zonesValidationLength,
|
|
config.zonesMaxAllowedLoopbackLength //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToResistanceBox(tmpBar, iBox, iBar.time);
|
|
if (has)
|
|
{
|
|
//
|
|
// Check Strength ...
|
|
if (config.zonesMinAlloweStrength > 0)
|
|
{
|
|
has = (iBox.upper - iBox.lower) > (config.zonesMinAlloweStrength * GetPoints(iBar.symbol));
|
|
}
|
|
|
|
//
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBox,
|
|
resistances //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
iBox.Clean();
|
|
tmpBar.Clean();
|
|
|
|
//
|
|
// Bars Detecting ...
|
|
|
|
//
|
|
// Momentum Bars ...
|
|
if (config.detectMomentum)
|
|
{
|
|
//
|
|
iPrefix = "MomentumBar";
|
|
has = IsMomentumBar(
|
|
iBar,
|
|
iDir,
|
|
config.momentumBarRangeLength,
|
|
config.momentumBarApprovedMultiplier //
|
|
);
|
|
has = has &&
|
|
ToPivot(
|
|
iBar,
|
|
iPivot,
|
|
iDir,
|
|
iPrefix //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iPivot,
|
|
structure.momentumBars //
|
|
);
|
|
}
|
|
iPivot.Clean();
|
|
}
|
|
|
|
//
|
|
// Engulfed Bars ...
|
|
if (config.detectEngulfed)
|
|
{
|
|
//
|
|
iPrefix = "EngulfedBar";
|
|
has = IsEngulfedBar(
|
|
iBar,
|
|
iDir //
|
|
);
|
|
has = has &&
|
|
ToPivot(
|
|
iBar,
|
|
iPivot,
|
|
iDir,
|
|
iPrefix //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iPivot,
|
|
structure.engulfBars //
|
|
);
|
|
}
|
|
iPivot.Clean();
|
|
}
|
|
|
|
//
|
|
// TruGaped Bars ...
|
|
if (config.detectTrueGaped)
|
|
{
|
|
//
|
|
iPrefix = "TruGapedBar";
|
|
has = IsTrueGapedBar(
|
|
iBar,
|
|
iDir,
|
|
config.truwGapApprovedPointMultiplier //
|
|
);
|
|
has = has &&
|
|
ToPivot(
|
|
iBar,
|
|
iPivot,
|
|
iDir,
|
|
iPrefix //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iPivot,
|
|
structure.trueGapBars //
|
|
);
|
|
}
|
|
iPivot.Clean();
|
|
}
|
|
|
|
//
|
|
// Pin Bars ...
|
|
if (config.detectTrueGaped)
|
|
{
|
|
//
|
|
iPrefix = "PinBar";
|
|
has = IsPinnedBar(
|
|
iBar,
|
|
iDir,
|
|
config.pinnedBaarShadowApprovedMultiplier,
|
|
config.pinnedBarMinimumPinBarRangeMultiplier,
|
|
config.pinnedBarForceDirection //
|
|
);
|
|
has = has &&
|
|
ToPivot(
|
|
iBar,
|
|
iPivot,
|
|
iDir,
|
|
iPrefix //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iPivot,
|
|
structure.pinBars //
|
|
);
|
|
}
|
|
iPivot.Clean();
|
|
}
|
|
|
|
//
|
|
// Patterns Detecting ...
|
|
|
|
//
|
|
// Star Pattern ...
|
|
if (config.detectStarPattern)
|
|
{
|
|
//
|
|
iPrefix = "Star";
|
|
has = IsStarPattern(
|
|
iBar,
|
|
iDir //
|
|
);
|
|
has = has &&
|
|
ToBox(
|
|
iBar,
|
|
iBox,
|
|
iDir,
|
|
iPrefix //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBox,
|
|
structure.starPatterns //
|
|
);
|
|
}
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
// Piercing Pattern ...
|
|
if (config.detectPiercingPattern)
|
|
{
|
|
//
|
|
iPrefix = "Piercing";
|
|
has = IsPiercingPattern(
|
|
iBar,
|
|
iDir //
|
|
);
|
|
has = has &&
|
|
ToBox(
|
|
iBar,
|
|
iBox,
|
|
iDir,
|
|
iPrefix //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBox,
|
|
structure.piercingPatterns //
|
|
);
|
|
}
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
// Rising Pattern ...
|
|
if (config.detectRisingPattern)
|
|
{
|
|
//
|
|
iPrefix = "Rising";
|
|
has = IsRisingPattern(
|
|
iBar,
|
|
iDir //
|
|
);
|
|
has = has &&
|
|
ToBox(
|
|
iBar,
|
|
iBox,
|
|
iDir,
|
|
iPrefix //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBox,
|
|
structure.risingPatterns //
|
|
);
|
|
}
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
// Flag Pattern ...
|
|
if (config.detectFlagPattern)
|
|
{
|
|
//
|
|
iPrefix = "Flag";
|
|
XOHCL swingBar;
|
|
has = IsFlagPattern(
|
|
iBar,
|
|
iDir,
|
|
swingBar,
|
|
config.flagPatternMinimumPullbackBars //
|
|
);
|
|
has = has &&
|
|
ToBox(
|
|
iBar,
|
|
iBox,
|
|
iDir,
|
|
iPrefix //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBox,
|
|
structure.flagPatterns //
|
|
);
|
|
}
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
// SignalKey Bar Pattern ...
|
|
if (config.detectSignalKeyBarPattern)
|
|
{
|
|
//
|
|
iPrefix = "SignalKeyBar";
|
|
has = IsSignalKeyBarPattern(
|
|
iBar,
|
|
iDir,
|
|
config.signalKeyBarShadowApprovedMultiplier,
|
|
config.signalKeyBarMinimumPinBarRangeMultiplier,
|
|
config.signalKeyBarForceDirection //
|
|
);
|
|
has = has &&
|
|
ToBox(
|
|
iBar,
|
|
iBox,
|
|
iDir,
|
|
iPrefix //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBox,
|
|
structure.signalKeyBarPatterns //
|
|
);
|
|
}
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
iBox.Clean();
|
|
tmpBar.Clean();
|
|
iPivot.Clean();
|
|
}
|
|
|
|
//
|
|
// Zones Extractions ...
|
|
|
|
//
|
|
// XBARZONES ...
|
|
XBoxZone tmpZones[];
|
|
int tmpZonesCount = fimaHelper.ExtractBarZones(
|
|
tmpZones,
|
|
forBar.Index(),
|
|
config.zonesRequiredNumber,
|
|
config.zonesBreakValidationLength,
|
|
config.zonesBreakValidationLength > 0,
|
|
config.zonesBarShadowMultiplier,
|
|
config.zonesMinAlloweStrength,
|
|
config.zonesValidationLength,
|
|
config.zonesMaxAllowedLoopbackLength //
|
|
);
|
|
has = IsValidSize(tmpZonesCount);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < tmpZonesCount; i++)
|
|
{
|
|
//
|
|
if (tmpZones[i].IsBullish())
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
tmpZones[i],
|
|
supports //
|
|
);
|
|
}
|
|
else if (tmpZones[i].IsBearish())
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
tmpZones[i],
|
|
resistances //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// XHK ...
|
|
XClean(tmpZones);
|
|
tmpZonesCount = fimaHelper.ExtractHKZones(
|
|
tmpZones,
|
|
forBar.Index(),
|
|
config.zonesRequiredNumber,
|
|
config.zonesBreakValidationLength,
|
|
config.zonesBreakValidationLength > 0,
|
|
config.zonesBarShadowMultiplier,
|
|
config.zonesMinAlloweStrength,
|
|
config.zonesValidationLength,
|
|
config.zonesMaxAllowedLoopbackLength //
|
|
);
|
|
has = IsValidSize(tmpZonesCount);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < tmpZonesCount; i++)
|
|
{
|
|
//
|
|
if (tmpZones[i].IsBullish())
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
tmpZones[i],
|
|
supports //
|
|
);
|
|
}
|
|
else if (tmpZones[i].IsBearish())
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
tmpZones[i],
|
|
resistances //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iBar.Clean();
|
|
iBox.Clean();
|
|
tmpBar.Clean();
|
|
iPivot.Clean();
|
|
}
|
|
|
|
//
|
|
// Analysis Zones ...
|
|
|
|
//
|
|
// XPV ...
|
|
|
|
//
|
|
// Support ...
|
|
has = structure.pvAnalysis.IsValid() &&
|
|
structure.pvAnalysis.HasSupportBox(iBox);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBox,
|
|
supports //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
has = structure.pvAnalysis.IsValid() &&
|
|
structure.pvAnalysis.HasResistanceBox(iBox);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBox,
|
|
resistances //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XZG ...
|
|
|
|
//
|
|
// Support ...
|
|
has = structure.zigzagAnalysis.IsValid() &&
|
|
structure.zigzagAnalysis.HasSupportBox(iBox);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBox,
|
|
supports //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
has = structure.zigzagAnalysis.IsValid() &&
|
|
structure.zigzagAnalysis.HasResistanceBox(iBox);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBox,
|
|
resistances //
|
|
);
|
|
}
|
|
|
|
//
|
|
// ZONES Specified ...
|
|
|
|
//
|
|
// OBS ...
|
|
CheckZones(forBar, obs);
|
|
UpdateToTime(obs, forBar.time);
|
|
Copy(
|
|
obs,
|
|
structure.obs //
|
|
);
|
|
|
|
//
|
|
// FVGS ...
|
|
CheckZones(forBar, fvgs);
|
|
UpdateToTime(fvgs, forBar.time);
|
|
Copy(
|
|
fvgs,
|
|
structure.fvgs //
|
|
);
|
|
|
|
//
|
|
// SUPPORTS ...
|
|
CheckZones(forBar, supports);
|
|
UpdateToTime(supports, forBar.time);
|
|
Copy(
|
|
supports,
|
|
structure.supports //
|
|
);
|
|
|
|
//
|
|
// RESISTANCES ...
|
|
CheckZones(forBar, resistances);
|
|
UpdateToTime(resistances, forBar.time);
|
|
Copy(
|
|
resistances,
|
|
structure.resistances //
|
|
);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
|
|
//
|
|
};
|
|
|
|
// |