This commit is contained in:
2025-10-25 16:45:25 +03:30
parent 2db26ee5f6
commit 7c0c48128e
6 changed files with 1416 additions and 17 deletions
@@ -1660,6 +1660,402 @@ class XCMarketPatternDetector : public XCBase
return result; return result;
} }
/**
* Leg Pattern Detection ...
*
* @param bar: XOHCL, reference to Specified Bar ...
* @param zone: XBoxZone, reference to Holds Detection Zone ...
* @param validationLength: int, leg minimum Validation Length ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( bool )
*/
bool IsLegPattern(
XOHCL &bar,
XBoxZone &zone,
int validationLength = 3,
int loopback = 10 //,
// Forces ...
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
//
// Normalize ...
loopback = NormalizeInt(loopback, 5);
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Prepare Patterns Analysis Config ...
XPatternAnalysisConfig iPatternsConfig;
iPatternsConfig.Default();
iPatternsConfig.CleanPatterns();
iPatternsConfig.AddPattern(X_BAR_PATTERN_LOW);
iPatternsConfig.AddPattern(X_BAR_PATTERN_HIGH);
iPatternsConfig.AddPattern(X_BAR_PATTERN_FLAG);
iPatternsConfig.AddPattern(X_BAR_PATTERN_STAR);
iPatternsConfig.AddPattern(X_BAR_PATTERN_RISING);
iPatternsConfig.AddPattern(X_BAR_PATTERN_PIERCING);
iPatternsConfig.AddPattern(X_BAR_PATTERN_ENGULFED);
iPatternsConfig.AddPattern(X_BAR_PATTERN_MOMENTUM);
iPatternsConfig.AddPattern(X_BAR_PATTERN_SIGNALKEY);
iPatternsConfig.AddPattern(X_BAR_PATTERN_TRUE_GAPED);
//
XOHCL iBar;
XOHCL pBar;
XOHCL iZBar;
XBoxZone iZone;
XBoxZone jZone;
bool has = false;
XBoxZone supports[];
XOHCL bullishBars[];
XOHCL bearishBars[];
XBoxZone bullishFVGs[];
XBoxZone bearishFVGs[];
bool isBullish = false;
bool isBearish = false;
XBoxZone resistances[];
double bullishPower = 0;
double bearishPower = 0;
int bullishBarsCount = 0;
int bearishBarsCount = 0;
int barIndex = bar.Index();
int start = barIndex + 1;
XPatternAnalysis iPattern;
int end = start + loopback;
XPatternAnalysis patterns[];
int bullishPatternsCount = 0;
int bearishPatternsCount = 0;
int sequentialsBullishBarsCount = 0;
int sequentialsBearishBarsCount = 0;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
for (int i = end; i >= start; i--)
{
//
// Initialize Indexed Bar ...
iBar.Clean();
pBar.Clean();
result = bar.BarAt(i, iBar);
result = result &&
iBar.GetPreviousBar(pBar);
if (!result)
{
break;
}
//
// Fill Bar Direction ...
isBullish = iBar.IsBullish();
isBearish = iBar.IsBearish();
//
// Directional ...
//
if (isBullish)
{
//
bullishBarsCount++;
//
bullishPower += iBar.GetBody();
bullishPower += iBar.GetLowShadow();
bullishPower -= iBar.GetHighShadow();
//
AddIfNotExists(iBar, bullishBars);
}
//
if (isBearish)
{
//
bearishBarsCount++;
//
bearishPower += iBar.GetBody();
bearishPower -= iBar.GetLowShadow();
bearishPower += iBar.GetHighShadow();
//
AddIfNotExists(iBar, bearishBars);
}
//
// Sequentail ....
//
// Bullish ...
if (isBullish)
{
//
if (pBar.IsBullish())
{
sequentialsBullishBarsCount++;
}
else if (pBar.IsBearish())
{
sequentialsBullishBarsCount = 0;
}
}
//
// Bearish ...
if (isBearish)
{
//
if (pBar.IsBearish())
{
sequentialsBearishBarsCount++;
}
else if (pBar.IsBullish())
{
sequentialsBearishBarsCount = 0;
}
}
//
// Detect Patterns ...
iPattern.Clean();
has = AnalyseBarPatterns(iBar, iPattern, iPatternsConfig);
if (has)
{
//
AddRef(iPattern, patterns);
//
bullishPatternsCount += iPattern.Count(X_DIRECTION_BULLISH);
bearishPatternsCount += iPattern.Count(X_DIRECTION_BEARISH);
}
//
// FVG Detection ...
CleanDirection(iDir);
has = HasFVG(iBar, iDir, iZone);
if (has)
{
//
if (iZone.IsBullish())
{
AddIfNotExists(iZone, bullishFVGs);
}
else
{
AddIfNotExists(iZone, bearishFVGs);
}
}
//
// Support / Resistance Detection ...
has = HasSupportResistance(
iBar,
iZone,
jZone,
5 //
);
if (has)
{
//
if (iZone.IsValid())
{
AddIfNotExists(iZone, supports);
}
//
if (jZone.IsValid())
{
AddIfNotExists(jZone, resistances);
}
}
}
//
// Summarizing ...
//
// Detect Direction ...
zone.Clean();
isBullish = false;
isBearish = false;
CleanDirection(iDir);
//
isBullish =
//
bullishPower > 0 &&
bullishBarsCount > 0 &&
bullishPatternsCount > 0 &&
sequentialsBullishBarsCount > 0 &&
//
bullishPower > bearishPower &&
bullishBarsCount > bearishBarsCount &&
bullishPatternsCount > bearishPatternsCount &&
sequentialsBullishBarsCount > sequentialsBearishBarsCount
//
;
//
isBearish =
//
bearishPower > 0 &&
bearishBarsCount > 0 &&
bearishPatternsCount > 0 &&
sequentialsBearishBarsCount > 0 &&
//
bearishPower > bullishPower &&
bearishBarsCount > bullishBarsCount &&
bearishPatternsCount > bullishPatternsCount &&
sequentialsBearishBarsCount > sequentialsBullishBarsCount
//
;
//
// Validate ...
result =
(isBullish && !isBearish) ||
(isBearish && !isBullish);
//
// PRICE Types ...
ENUM_X_PRICE lowerPriceType = X_PRICE_LOW;
ENUM_X_PRICE upperPriceType = X_PRICE_HIGH;
//
// Prepare Zone ...
if (result)
{
//
zone.at = bar.time;
zone.to = bar.time;
zone.period = bar.period;
zone.symbol = bar.symbol;
//
zone.type = ToXString(X_BAR_PATTERN_LEG);
zone.dir = isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
int idx = -1;
if (isBullish)
{
idx = GetOldest(bullishBars);
}
else
{
idx = GetOldest(bearishBars);
}
//
result = IsValidIndex(idx);
if (result)
{
//
iZBar.Clean();
if (isBullish)
{
iZBar = bullishBars[idx];
}
else
{
iZBar = bearishBars[idx];
}
//
zone.from = iZBar.time;
//
iZBar.Clean();
}
//
if (isBullish)
{
//
// Prepare Upper and Lower ...
//
// Upper ...
idx = GetHighestBarPrice(bullishBars, upperPriceType);
if (IsValidIndex(idx))
{
zone.upper = bullishBars[idx].GetPrice(upperPriceType);
}
//
// Lower ...
idx = GetLowestBarPrice(bullishBars, upperPriceType);
if (IsValidIndex(idx))
{
zone.lower = bullishBars[idx].GetPrice(lowerPriceType);
}
}
else
{
//
// Prepare Upper and Lower ...
//
// Upper ...
idx = GetHighestBarPrice(bearishBars, upperPriceType);
if (IsValidIndex(idx))
{
zone.upper = bearishBars[idx].GetPrice(upperPriceType);
}
//
// Lower ...
idx = GetLowestBarPrice(bearishBars, upperPriceType);
if (IsValidIndex(idx))
{
zone.lower = bearishBars[idx].GetPrice(lowerPriceType);
}
}
//
result = zone.IsValid();
}
//
// Cleanup ...
if (!result)
{
zone.Clean();
}
iBar.Clean();
pBar.Clean();
iZBar.Clean();
iZone.Clean();
jZone.Clean();
iPattern.Clean();
XClean(supports);
XClean(patterns);
XClean(bullishBars);
XClean(bearishBars);
XClean(bullishFVGs);
XClean(bearishFVGs);
XClean(resistances);
//
return result;
}
/** /**
* Detect Order Flow ... * Detect Order Flow ...
* *
@@ -2700,6 +3096,100 @@ class XCMarketPatternDetector : public XCBase
return result; return result;
} }
/**
* Check Specified Bar Has Support or Resistance and Extract them ...
*
* @param bar: XOHCL, reference to Specified Bar ...
* @param support: XBoxZone, reference to holds Detected Support ...
* @param resistance: XBoxZone, reference to holds Detected Resistance ...
* @param validationLength: int, Specified Validation Length ...
* @param loopback: int, Max Allowed Loopback Bars for Detection ...
*
* @return ( bool )
*/
bool HasSupportResistance(
XOHCL &bar,
XBoxZone &support,
XBoxZone &resistance,
int validationLength = 7,
int loopback = 100 //
)
{
//
bool result = false;
//
// Prepare ...
support.Clean();
resistance.Clean();
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
validationLength = NormalizeInt(validationLength, 3);
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
XOHCL iZBar;
//
// Support ...
iZBar.Clean();
bool hasSupport = HasSupport(
bar,
iZBar,
validationLength,
loopback //
);
if (hasSupport)
{
//
hasSupport = ToSupportBox(
iZBar,
support,
bar.time //
);
}
//
// Resistance ...
iZBar.Clean();
bool hasResistance = HasResistance(
bar,
iZBar,
validationLength,
loopback //
);
if (hasResistance)
{
//
hasResistance = ToResistanceBox(
iZBar,
resistance,
bar.time //
);
}
//
// Summarize Result ...
result = hasSupport ||
hasResistance;
//
// Cleanup ...
iZBar.Clean();
//
return result;
}
// //
// Analysers ... // Analysers ...
@@ -2581,6 +2581,15 @@ struct XPatternAnalysisConfig
// //
// Collection Manipulations ... // Collection Manipulations ...
/**
* Remove all Allowed Patterns and Directions ...
*/
void CleanPatterns() {
//
XClean(allowedDirs);
XClean(allowedPatterns);
}
/** /**
* Full Detect Patterns ... * Full Detect Patterns ...
* *
@@ -652,6 +652,53 @@ int GetHighestByBar(
return result; return result;
} }
/**
* Get Highest Bar Price Index of Specified Collection ...
*
* @param source: reference collection, Provides Data Source ...
*
* @return ( int )
*/
int GetHighestBarPrice(
XOHCL &source[],
ENUM_X_PRICE priceType //
)
{
//
int result = -1;
//
// Validate ...
bool has = HasChild(source) &&
IsXValid(priceType);
if (!has)
{
return result;
}
//
double price = EMPTY_VALUE;
double selected = EMPTY_VALUE;
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
price = source[i].GetPrice(priceType);
has = !NotEmptyZero(selected)
? true
: price > selected;
if (has)
{
//
result = i;
selected = price;
}
}
//
return result;
}
/** /**
* Get Highest Index of Specified Collection ... * Get Highest Index of Specified Collection ...
* *
@@ -903,6 +950,53 @@ int GetLowestByBar(
return result; return result;
} }
/**
* Get Lowest Bar Price Index of Specified Collection ...
*
* @param source: reference collection, Provides Data Source ...
*
* @return ( int )
*/
int GetLowestBarPrice(
XOHCL &source[],
ENUM_X_PRICE priceType //
)
{
//
int result = -1;
//
// Validate ...
bool has = HasChild(source) &&
IsXValid(priceType);
if (!has)
{
return result;
}
//
double price = EMPTY_VALUE;
double selected = EMPTY_VALUE;
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
price = source[i].GetPrice(priceType);
has = !NotEmptyZero(selected)
? true
: price < selected;
if (has)
{
//
result = i;
selected = price;
}
}
//
return result;
}
/** /**
* Get Lowest Index of Specified Collection ... * Get Lowest Index of Specified Collection ...
* *
+28 -17
View File
@@ -51,6 +51,7 @@ enum ENUM_X_BAR_PATTERN
X_BAR_PATTERN_RESISTANCE = 15, X_BAR_PATTERN_RESISTANCE = 15,
X_BAR_PATTERN_PULLBACK = 16, X_BAR_PATTERN_PULLBACK = 16,
X_BAR_PATTERN_CONSOLIDATION = 17, X_BAR_PATTERN_CONSOLIDATION = 17,
X_BAR_PATTERN_LEG = 18,
}; };
/** /**
@@ -87,87 +88,92 @@ string ToXString(ENUM_X_BAR_PATTERN value)
// //
case X_BAR_PATTERN_HIGH: case X_BAR_PATTERN_HIGH:
result = "XHIGH"; result = "XHIGHP";
break; break;
// //
case X_BAR_PATTERN_LOW: case X_BAR_PATTERN_LOW:
result = "XLOW"; result = "XLOWP";
break; break;
// //
case X_BAR_PATTERN_MOMENTUM: case X_BAR_PATTERN_MOMENTUM:
result = "XMOMENTUM"; result = "XMOMENTUMP";
break; break;
// //
case X_BAR_PATTERN_ENGULFED: case X_BAR_PATTERN_ENGULFED:
result = "XENGULFED"; result = "XENGULFEDP";
break; break;
// //
case X_BAR_PATTERN_TRUE_GAPED: case X_BAR_PATTERN_TRUE_GAPED:
result = "XGAPED"; result = "XGAPEDP";
break; break;
// //
case X_BAR_PATTERN_PINNED: case X_BAR_PATTERN_PINNED:
result = "XPINNED"; result = "XPINNEDP";
break; break;
// //
case X_BAR_PATTERN_STAR: case X_BAR_PATTERN_STAR:
result = "XSTAR"; result = "XSTARP";
break; break;
// //
case X_BAR_PATTERN_PIERCING: case X_BAR_PATTERN_PIERCING:
result = "XPIERCING"; result = "XPIERCINGP";
break; break;
// //
case X_BAR_PATTERN_RISING: case X_BAR_PATTERN_RISING:
result = "XRISING"; result = "XRISINGP";
break; break;
// //
case X_BAR_PATTERN_FLAG: case X_BAR_PATTERN_FLAG:
result = "XFLAG"; result = "XFLAGP";
break; break;
// //
case X_BAR_PATTERN_SIGNALKEY: case X_BAR_PATTERN_SIGNALKEY:
result = "XSIGNALKEY"; result = "XSIGNALKEYP";
break; break;
// //
case X_BAR_PATTERN_OB: case X_BAR_PATTERN_OB:
result = "XOB"; result = "XOBP";
break; break;
// //
case X_BAR_PATTERN_FVG: case X_BAR_PATTERN_FVG:
result = "XFVG"; result = "XFVGP";
break; break;
// //
case X_BAR_PATTERN_SUPPORT: case X_BAR_PATTERN_SUPPORT:
result = "XSUPPORT"; result = "XSUPPORTP";
break; break;
// //
case X_BAR_PATTERN_RESISTANCE: case X_BAR_PATTERN_RESISTANCE:
result = "XRESISTANCE"; result = "XRESISTANCEP";
break; break;
// //
case X_BAR_PATTERN_PULLBACK: case X_BAR_PATTERN_PULLBACK:
result = "XPULLBACK"; result = "XPULLBACKP";
break; break;
// //
case X_BAR_PATTERN_CONSOLIDATION: case X_BAR_PATTERN_CONSOLIDATION:
result = "XCONSOLIDATION"; result = "XCONSOLIDATIONP";
break;
//
case X_BAR_PATTERN_LEG:
result = "XLEGP";
break; break;
} }
@@ -267,6 +273,10 @@ ENUM_X_BAR_PATTERN ToBarPattern(string value)
{ {
result = X_BAR_PATTERN_CONSOLIDATION; result = X_BAR_PATTERN_CONSOLIDATION;
} }
else if (value == ToXString(X_BAR_PATTERN_LEG))
{
result = X_BAR_PATTERN_LEG;
}
// //
return result; return result;
@@ -302,6 +312,7 @@ int GetAllBarPatters(ENUM_X_BAR_PATTERN &dest[])
Add(X_BAR_PATTERN_RESISTANCE, dest); Add(X_BAR_PATTERN_RESISTANCE, dest);
Add(X_BAR_PATTERN_PULLBACK, dest); Add(X_BAR_PATTERN_PULLBACK, dest);
Add(X_BAR_PATTERN_CONSOLIDATION, dest); Add(X_BAR_PATTERN_CONSOLIDATION, dest);
Add(X_BAR_PATTERN_LEG, dest);
// //
return ArraySize(dest); return ArraySize(dest);
@@ -2712,6 +2712,791 @@ class XCXFIMAHelperParser : XCBase
return result; return result;
} }
//
// Boundary Tools ...
// =============================
// Boundary Includes:
// MA Band ...
// PB Band ...
// HK Band ...
// ATR Band ...
/**
* Reading Boundary Values ...
*
* @param maBandUpper: double, reference to holds MA Band Upper value ...
* @param maBandLower: double, reference to holds MA Band Lower value ...
* @param pbBandUpper: double, reference to holds PB Band Upper value ...
* @param pbBandLower: double, reference to holds PB Band Lower value ...
* @param hkBandUpper: double, reference to holds HK Band Upper value ...
* @param hkBandLower: double, reference to holds HK Band Lower value ...
* @param atrBandUpper: double, reference to holds ATR Band Upper value ...
* @param atrBandLower: double, reference to holds ATR Band Lower value ...
* @param barIndex: int, Specified Bar Index ...
*/
void GetBoundaryValues(
double &maBandUpper,
double &maBandLower,
double &pbBandUpper,
double &pbBandLower,
double &hkBandUpper,
double &hkBandLower,
double &atrBandUpper,
double &atrBandLower,
int barIndex = 0 //
)
{
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Prepare ...
maBandUpper = EMPTY_VALUE;
maBandLower = EMPTY_VALUE;
pbBandUpper = EMPTY_VALUE;
pbBandLower = EMPTY_VALUE;
hkBandUpper = EMPTY_VALUE;
hkBandLower = EMPTY_VALUE;
atrBandUpper = EMPTY_VALUE;
atrBandLower = EMPTY_VALUE;
//
// Validate ...
bool has = IsValid();
if (!has)
{
return;
}
//
maBandUpper = helper.GetMABandUpper(barIndex);
maBandLower = helper.GetMABandLower(barIndex);
pbBandUpper = helper.GetPBBandUpper(barIndex);
pbBandLower = helper.GetPBBandLower(barIndex);
hkBandUpper = helper.GetHKBandUpper(barIndex);
hkBandLower = helper.GetHKBandLower(barIndex);
atrBandUpper = helper.GetATRBandUpper(barIndex);
atrBandLower = helper.GetATRBandLower(barIndex);
}
/**
* Read Boundary Values and Fill as an Array ...
*
* @param values: double, collection reference to fill results ...
* @param barIndex: int, Specified Bar Index ...
*/
void GetBoundaryValuesArray(
double &values[],
int barIndex = 0 //
)
{
//
// Prepare ...
XClean(values);
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
bool has = IsValid();
if (!has)
{
return;
}
//
// Reading Boundary Values ...
//
double maBandUpper = EMPTY_VALUE;
double maBandLower = EMPTY_VALUE;
double pbBandUpper = EMPTY_VALUE;
double pbBandLower = EMPTY_VALUE;
double hkBandUpper = EMPTY_VALUE;
double hkBandLower = EMPTY_VALUE;
double atrBandUpper = EMPTY_VALUE;
double atrBandLower = EMPTY_VALUE;
//
GetBoundaryValues(
maBandUpper,
maBandLower,
pbBandUpper,
pbBandLower,
hkBandUpper,
hkBandLower,
atrBandUpper,
atrBandLower,
barIndex //
);
//
// Validate ...
has =
NotEmptyZero(maBandUpper) &&
NotEmptyZero(maBandLower) &&
NotEmptyZero(pbBandUpper) &&
NotEmptyZero(pbBandLower) &&
NotEmptyZero(hkBandUpper) &&
NotEmptyZero(hkBandLower) &&
NotEmptyZero(atrBandUpper) &&
NotEmptyZero(atrBandLower);
if (!has)
{
return;
}
//
Add(maBandUpper, values);
Add(maBandLower, values);
Add(pbBandUpper, values);
Add(pbBandLower, values);
Add(hkBandUpper, values);
Add(hkBandLower, values);
Add(atrBandUpper, values);
Add(atrBandLower, values);
}
/**
* Read Boundary Min Value ...
*
* @param barIndex: int, Specified Bar Index ...
*
* @return ( double )
*/
double GetBoundaryMin(int barIndex = 0)
{
//
double result = EMPTY_VALUE;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
bool has = IsValid();
if (!has)
{
return result;
}
//
double values[];
GetBoundaryValuesArray(values, barIndex);
result = GetMax(values);
//
return result;
}
/**
* Read Boundary Max Value ...
*
* @param barIndex: int, Specified BAr Index ...
*
* @return ( double )
*/
double GetBoundaryMax(int barIndex = 0)
{
//
double result = EMPTY_VALUE;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
bool has = IsValid();
if (!has)
{
return result;
}
//
double values[];
GetBoundaryValuesArray(values, barIndex);
result = GetMin(values);
//
return result;
}
//
// Bars and Boundary ...
/**
* Check Bar's Price is Over Boundary Max or not ...
*
* @param barIndex: int, Specified Bar Index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
*
* @return ( bool )
*/
bool IsBarOverBoundaryMax(
int barIndex = 0,
ENUM_X_PRICE priceType = X_PRICE_HIGH //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
XOHCL bar;
double price = EMPTY_VALUE;
double value = GetBoundaryMax(barIndex);
result = bar.Init(symbol, period, barIndex);
if (result)
{
price = bar.GetPrice(priceType);
}
result = bar.IsValid() &&
NotEmptyZero(price) &&
NotEmptyZero(value) &&
price > value;
//
// Cleanup ...
bar.Clean();
//
return result;
}
/**
* Check Bar's Price is Over Boundary Min or not ...
*
* @param barIndex: int, Specified Bar Index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
*
* @return ( bool )
*/
bool IsBarOverBoundaryMin(
int barIndex = 0,
ENUM_X_PRICE priceType = X_PRICE_LOW //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
XOHCL bar;
double price = EMPTY_VALUE;
double value = GetBoundaryMin(barIndex);
result = bar.Init(symbol, period, barIndex);
if (result)
{
price = bar.GetPrice(priceType);
}
result = bar.IsValid() &&
NotEmptyZero(price) &&
NotEmptyZero(value) &&
price > value;
//
// Cleanup ...
bar.Clean();
//
return result;
}
/**
* Check Bar's Price is Under Boundary Max or not ...
*
* @param barIndex: int, Specified Bar Index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
*
* @return ( bool )
*/
bool IsBarUnderBoundaryMax(
int barIndex = 0,
ENUM_X_PRICE priceType = X_PRICE_HIGH //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
XOHCL bar;
double price = EMPTY_VALUE;
double value = GetBoundaryMax(barIndex);
result = bar.Init(symbol, period, barIndex);
if (result)
{
price = bar.GetPrice(priceType);
}
result = bar.IsValid() &&
NotEmptyZero(price) &&
NotEmptyZero(value) &&
price < value;
//
// Cleanup ...
bar.Clean();
//
return result;
}
/**
* Check Bar's Price is Under Boundary Min or not ...
*
* @param barIndex: int, Specified Bar Index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
*
* @return ( bool )
*/
bool IsBarUnderBoundaryMin(
int barIndex = 0,
ENUM_X_PRICE priceType = X_PRICE_LOW //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
XOHCL bar;
double price = EMPTY_VALUE;
double value = GetBoundaryMin(barIndex);
result = bar.Init(symbol, period, barIndex);
if (result)
{
price = bar.GetPrice(priceType);
}
result = bar.IsValid() &&
NotEmptyZero(price) &&
NotEmptyZero(value) &&
price < value;
//
// Cleanup ...
bar.Clean();
//
return result;
}
/**
* Check Bar's Price is Crossed Over Boundary Max or not ...
*
* @param barIndex: int, Specified Bar Index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
*
* @return ( bool )
*/
bool IsBarCrossedOverBoundaryMax(
int barIndex = 0,
ENUM_X_PRICE priceType = X_PRICE_HIGH //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
bool isC = IsBarOverBoundaryMax(barIndex, priceType);
bool isP = IsBarOverBoundaryMax(barIndex + 1, priceType);
//
result = isC && !isP;
//
return result;
}
/**
* Check Bar's Price is Crossed Over Boundary Min or not ...
*
* @param barIndex: int, Specified Bar Index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
*
* @return ( bool )
*/
bool IsBarCrossedOverBoundaryMin(
int barIndex = 0,
ENUM_X_PRICE priceType = X_PRICE_LOW //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
bool isC = IsBarOverBoundaryMin(barIndex, priceType);
bool isP = IsBarOverBoundaryMin(barIndex + 1, priceType);
//
result = isC && !isP;
//
return result;
}
/**
* Check Bar's Price is Crossed Under Boundary Max or not ...
*
* @param barIndex: int, Specified Bar Index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
*
* @return ( bool )
*/
bool IsBarCrossedUnderBoundaryMax(
int barIndex = 0,
ENUM_X_PRICE priceType = X_PRICE_HIGH //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
bool isC = IsBarUnderBoundaryMax(barIndex, priceType);
bool isP = IsBarUnderBoundaryMax(barIndex + 1, priceType);
//
result = isC && !isP;
//
return result;
}
/**
* Check Bar's Price is Crossed Under Boundary Min or not ...
*
* @param barIndex: int, Specified Bar Index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
*
* @return ( bool )
*/
bool IsBarCrossedUnderBoundaryMin(
int barIndex = 0,
ENUM_X_PRICE priceType = X_PRICE_LOW //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
bool isC = IsBarUnderBoundaryMin(barIndex, priceType);
bool isP = IsBarUnderBoundaryMin(barIndex + 1, priceType);
//
result = isC && !isP;
//
return result;
}
/**
* Count Over Boundary Max Bar's Prices ...
*
* @param barIndex: int, Specified Bar Index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( int )
*/
int CountBarsOverBoundaryMax(
int barIndex = 0,
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int loopback = 500 //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
bool has = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
int idx = barIndex;
while (idx < barIndex + loopback)
{
//
idx++;
has = IsBarOverBoundaryMax(idx);
if (!has)
{
break;
}
result++;
}
//
return result;
}
/**
* Count Over Boundary Min Bar's Prices ...
*
* @param barIndex: int, Specified Bar Index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( int )
*/
int CountBarsOverBoundaryMin(
int barIndex = 0,
ENUM_X_PRICE priceType = X_PRICE_LOW,
int loopback = 500 //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
bool has = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
int idx = barIndex;
while (idx < barIndex + loopback)
{
//
idx++;
has = IsBarOverBoundaryMin(idx);
if (!has)
{
break;
}
result++;
}
//
return result;
}
/**
* Count Under Boundary Max Bar's Prices ...
*
* @param barIndex: int, Specified Bar Index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( int )
*/
int CountBarsUnderBoundaryMax(
int barIndex = 0,
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int loopback = 500 //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
bool has = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
int idx = barIndex;
while (idx < barIndex + loopback)
{
//
idx++;
has = IsBarUnderBoundaryMax(idx);
if (!has)
{
break;
}
result++;
}
//
return result;
}
/**
* Count Under Boundary Min Bar's Prices ...
*
* @param barIndex: int, Specified Bar Index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( int )
*/
int CountBarsUnderBoundaryMin(
int barIndex = 0,
ENUM_X_PRICE priceType = X_PRICE_LOW,
int loopback = 500 //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
bool has = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
int idx = barIndex;
while (idx < barIndex + loopback)
{
//
idx++;
has = IsBarUnderBoundaryMin(idx);
if (!has)
{
break;
}
result++;
}
//
return result;
}
// //
// Protected ... // Protected ...
protected: protected:
@@ -1941,6 +1941,16 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
Print("OrderFlow ..."); Print("OrderFlow ...");
} }
//
XBoxZone legZone;
result = poiDetector.IsLegPattern(pBar, legZone);
if (result)
{
//
poiDrawer.DrawZone(legZone, structureDrawConfig.drawConfig);
Print("Leg Pattern Detected ...");
}
// //
isBullish = isBullish =
// //