Files
MQL5Data/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5
T
2025-09-26 13:20:34 +03:30

1300 lines
36 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;
bool has = false;
int maxAllowedCollecting = 50;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
// Detecting POI Based on Config ...
//
// Order Block ...
if (config.detectOB)
{
//
bool isOB = HasOB(
forBar,
iDir,
structure.ob,
config.obLoopback //
);
bool isBullishOB = isOB &&
IsSpecifiedBullish(iDir);
bool isBearishOB = isOB &&
IsSpecifiedBearish(iDir);
if (!isOB)
{
structure.ob.Clean();
}
//
// Detect Touches ...
if (isOB)
{
//
AddIfNotExists(
structure.ob,
obs,
maxAllowedCollecting //
);
//
XOHCL pBar;
bool has = forBar.GetPreviousBar(pBar);
if (has)
{
//
structure.isOBTouched =
isBullishOB
? pBar.low < structure.ob.upper
: pBar.high > structure.ob.lower;
}
//
pBar.Clean();
}
}
//
// Fair Value Gap ...
if (config.detectFVG)
{
//
bool isFVG = HasFVG(
forBar,
iDir,
structure.fvg,
config.fvgLoopback //
);
bool isBullishFVG = isFVG &&
IsSpecifiedBullish(iDir);
bool isBearishFVG = isFVG &&
IsSpecifiedBearish(iDir);
if (!isFVG)
{
structure.fvg.Clean();
}
//
// Detect Touches ...
if (isFVG)
{
//
AddIfNotExists(
structure.fvg,
fvgs,
maxAllowedCollecting //
);
//
XOHCL pBar;
bool has = forBar.GetPreviousBar(pBar);
if (has)
{
//
structure.isFVGTouched =
isBullishFVG
? pBar.low < structure.fvg.upper
: pBar.high > structure.fvg.lower;
}
//
pBar.Clean();
}
}
//
// 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 = IsStartPattern(
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);
}
//
// Detect Supports ...
if (config.detectSupport)
{
//
XOHCL support;
bool hasSupport = HasSupport(
forBar,
support,
config.supportAndResistanceValidationLength,
config.supportAndResistanceMaxAllowedLoopback //
);
if (hasSupport)
{
//
XBoxZone supportBox;
has = ToSupportBox(support, supportBox);
//
// Validate Zone Strength if Provided ...
if (config.minAllowdSupportAndResistanceStrength > 0)
{
//
has = has &&
ValidateStrength(
supportBox,
config.minAllowdSupportAndResistanceStrength //
);
}
//
if (has)
{
//
AddIfNotExists(
supportBox,
supports,
maxAllowedCollecting //
);
//
structure.support = supportBox;
}
//
// Check for Support Touches ...
XOHCL pBar;
has = has &&
forBar.GetPreviousBar(pBar);
if (has)
{
structure.isSupportTouched = pBar.low < supportBox.upper;
}
//
pBar.Clean();
supportBox.Clean();
}
support.Clean();
}
//
// Detect Resistance ...
if (config.detectResistance)
{
//
XOHCL resistance;
bool hasResistance = HasResistance(
forBar,
resistance,
config.supportAndResistanceValidationLength,
config.supportAndResistanceMaxAllowedLoopback //
);
if (hasResistance)
{
//
XBoxZone resistanceBox;
has = ToResistanceBox(resistance, resistanceBox);
//
// Validate Zone Strength if Provided ...
if (config.minAllowdSupportAndResistanceStrength > 0)
{
//
has = has &&
ValidateStrength(
resistanceBox,
config.minAllowdSupportAndResistanceStrength //
);
}
//
if (has)
{
//
AddIfNotExists(
resistanceBox,
resistances,
maxAllowedCollecting //
);
//
structure.resistance = resistanceBox;
}
//
// Check for Resistance Touches ...
XOHCL pBar;
has = has &&
forBar.GetPreviousBar(pBar);
if (has)
{
structure.isResistanceTouched = pBar.high > resistanceBox.upper;
}
//
pBar.Clean();
resistanceBox.Clean();
}
resistance.Clean();
}
//
// 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 MA ...
if (config.analyseFIMAMAPivots)
{
//
XPivotAnalysis analysis;
has = AnalyseMAPivots(
analysis, // Result ...
forBar.Index(), // Bar Index ...
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
config.maxAllowedLoopbackLengthForAnalysis, // Max Allowed Loopback ...
config.pvPivotsValidationLength // Validation Length ...
);
if (has)
{
structure.maAnalysis = analysis;
}
}
//
// Analyse Based on SAR ...
if (config.analyseFIMASARPivots)
{
//
XPivotAnalysis analysis;
has = AnalyseSARPivots(
analysis, // Result ...
forBar.Index(), // Bar Index ...
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
config.maxAllowedLoopbackLengthForAnalysis // Max Allowed Loopback ...
);
if (has)
{
structure.sarAnalysis = 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;
}
}
//
// COMPLEX Actions ...
//
// Lockup For Previous Zone ...
has = structure.isSupportTouched ||
structure.isResistanceTouched;
if (has)
{
//
if (structure.isSupportTouched)
{
//
idx = GetYoungestBefore(
structure.support.from,
supports //
);
has = IsValidIndex(idx);
if (has)
{
structure.prevZone = supports[idx];
}
}
else if (structure.isResistanceTouched)
{
//
idx = GetYoungestBefore(
structure.resistance.from,
resistances //
);
has = IsValidIndex(idx);
if (has)
{
structure.prevZone = resistances[idx];
}
}
}
//
// Detect Recently Tested Zones ...
if ((config.detectSupport ||
config.detectResistance) &&
config.recentlyTestedZonesMaxLookup > 0)
{
//
XOHCL iBar;
int idx = -1;
bool has = false;
//
int start = forBar.Index() + 1;
int end = start + config.recentlyTestedZonesMaxLookup;
for (int i = start; i < end; i++) {
//
// Initialize Indexed Bar ...
has = forBar.BarAt(i, iBar);
if (!has) {
continue;
}
//
// Selecting Support and Resistances ...
//
// Supports ...
idx = GetYoungestBefore(iBar.time, supports);
has = IsValidIndex(idx);
if (has) {
//
// Check Testing ...
has = IsTested(iBar, supports[idx]);
if (has) {
//
AddIfNotExists(
supports[idx],
structure.recentlyTestedZones //
);
}
}
//
// Resistances ...
idx = GetYoungestBefore(iBar.time, resistances);
has = IsValidIndex(idx);
if (has) {
//
// Check Testing ...
has = IsTested(iBar, resistances[idx]);
if (has) {
//
AddIfNotExists(
resistances[idx],
structure.recentlyTestedZones //
);
}
}
}
}
//
// Checkup for FakeBreaked Zones ...
if (config.detectSupport ||
config.detectResistance)
{
//
// Retrieve Previous Bar ...
int idx = -1;
XOHCL pForBar;
XOHCL breakerBar;
XBoxZone pSupport;
XOHCL pBreakerBar;
XBoxZone pResistance;
//
// Selecting Previously Touched Support / Resistance ...
has = forBar.GetPreviousBar(pForBar);
if (has)
{
//
// Detecting Nearest Above Lows Support ...
idx = GetYoungestAbove(
pForBar.low,
supports //
);
has = IsValidIndex(idx) &&
IsBreaked(
forBar,
supports[idx] //
);
if (has)
{
pSupport = supports[idx];
}
//
// Detecting Nearest Below Highs Resistance ...
idx = GetYoungestBelow(
pForBar.high,
resistances //
);
has = IsValidIndex(idx) &&
IsBreaked(
forBar,
resistances[idx] //
);
if (has)
{
pResistance = resistances[idx];
}
}
//
// Check at least a zone Exists ...
// Selecting pTestedZone ...
has = pSupport.IsValid() ||
pResistance.IsValid();
if (has)
{
//
// Support ...
has = pSupport.IsValid();
if (has)
{
//
structure.isPTest = true;
structure.pTestedZone = pSupport;
}
//
// Resistance ...
has = pResistance.IsValid();
if (has)
{
//
structure.isPTest = true;
structure.pTestedZone = pResistance;
}
}
//
// Check pTestedZone Existance ...
has = structure.isPTest &&
structure.pTestedZone.IsValid();
if (has)
{
//
// Get Breaker Bars ...
XOHCL breakerBars[];
int breakerBarsCount = GetBreakerBars(
structure.pTestedZone,
breakerBars //
);
has = IsValidSize(breakerBarsCount);
if (has)
{
//
idx = GetYoungestBar(breakerBars);
has = IsValidIndex(idx);
if (has)
{
breakerBar = breakerBars[idx];
}
}
//
SpecifiedClean(breakerBars);
}
//
// Check Zone Breaker Bar Exists ...
// Validate Zone Fake Breake Langth ...
has = breakerBar.IsValid();
if (has)
{
//
// Validate Breake Length ...
has = (breakerBar.Index() - pForBar.Index()) <= config.supportAndResistanceBreakeValidationLength;
}
//
// Cleanup Resources ...
//
if (!has)
{
//
structure.isPTest = false;
structure.pTestedZone.Clean();
}
pForBar.Clean();
pSupport.Clean();
breakerBar.Clean();
pBreakerBar.Clean();
pResistance.Clean();
}
}
//
// Protected ...
protected:
//
// Props ...
//
// Tools / Actions ...
//
// Private ...
private:
//
//
};
//