last ...
This commit is contained in:
@@ -1650,6 +1650,254 @@ class XCMarketPatternDetector : public XCBase
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IsConsolidationPattern(
|
||||
XOHCL &bar,
|
||||
XBoxZone &zone,
|
||||
ENUM_X_DIRECTION &dir,
|
||||
int validationLength = 5,
|
||||
ENUM_X_PRICE breakPriceType = X_PRICE_CLOSE,
|
||||
ENUM_X_PRICE upperPriceType = X_PRICE_HIGH,
|
||||
ENUM_X_PRICE lowerPriceType = X_PRICE_LOW //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Descriptions:
|
||||
// ===============
|
||||
// Consolidation Zones Happens by Highest High and Lowest Low
|
||||
// of Specified Range which Breakes From one Side ...
|
||||
//
|
||||
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
zone.Clean();
|
||||
CleanDirection(dir);
|
||||
|
||||
//
|
||||
// Normalize ...
|
||||
validationLength = NormalizeInt(validationLength, 3);
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid() &&
|
||||
IsXValid(lowerPriceType) &&
|
||||
IsXValid(upperPriceType) &&
|
||||
IsXValid(breakPriceType);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Requirements ...
|
||||
XOHCL iBar;
|
||||
bool has = false;
|
||||
datetime to = NULL;
|
||||
datetime from = NULL;
|
||||
double iLow = EMPTY_VALUE;
|
||||
bool hasLowShadow = false;
|
||||
double lower = EMPTY_VALUE;
|
||||
double upper = EMPTY_VALUE;
|
||||
double iHigh = EMPTY_VALUE;
|
||||
bool hasHighShadow = false;
|
||||
double iPrice = EMPTY_VALUE;
|
||||
bool isLowerBreaked = false;
|
||||
bool isUpperBreaked = false;
|
||||
|
||||
//
|
||||
// Loop Through Bars ...
|
||||
int barIndex = bar.Index();
|
||||
int idx = barIndex;
|
||||
bool canLookup = IsValidIndex(idx);
|
||||
while (canLookup)
|
||||
{
|
||||
//
|
||||
// Initialize Indexed Bar ...
|
||||
idx++;
|
||||
iBar.Clean();
|
||||
result = bar.BarAt(idx, iBar);
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Update Time ...
|
||||
if (idx == barIndex + 1)
|
||||
{
|
||||
to = iBar.time;
|
||||
}
|
||||
|
||||
//
|
||||
// Extract Low and High Price ...
|
||||
iLow = iBar.GetPrice(lowerPriceType);
|
||||
iHigh = iBar.GetPrice(upperPriceType);
|
||||
result = NotEmptyZero(iLow) &&
|
||||
NotEmptyZero(iHigh);
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Bar Has Low/High Shadow ...
|
||||
hasLowShadow = iBar.GetLowShadow() > iBar.GetHighShadow();
|
||||
hasHighShadow = iBar.GetHighShadow() > iBar.GetLowShadow();
|
||||
|
||||
//
|
||||
// Update Range Lower and Upper based on Shadows ...
|
||||
|
||||
//
|
||||
// Lower ...
|
||||
if (hasLowShadow)
|
||||
{
|
||||
//
|
||||
// Check Can Update ...
|
||||
has =
|
||||
!NotEmptyZero(lower)
|
||||
? true
|
||||
: iLow < lower;
|
||||
if (has)
|
||||
{
|
||||
lower = iLow;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Upper ...
|
||||
if (hasHighShadow)
|
||||
{
|
||||
//
|
||||
// Check Can Update ...
|
||||
has =
|
||||
!NotEmptyZero(upper)
|
||||
? true
|
||||
: iHigh > upper;
|
||||
if (has)
|
||||
{
|
||||
upper = iHigh;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Price Breakes ...
|
||||
iPrice = iBar.GetPrice(breakPriceType);
|
||||
result = NotEmptyZero(iPrice);
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Upper/Lower breakes ...
|
||||
isLowerBreaked = iPrice < lower;
|
||||
isUpperBreaked = iPrice > upper;
|
||||
|
||||
//
|
||||
canLookup = (!isLowerBreaked && !isUpperBreaked);
|
||||
if (!canLookup)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
from = iBar.time;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Calculations ...
|
||||
result =
|
||||
//
|
||||
IsXValid(to) &&
|
||||
IsXValid(from) &&
|
||||
from < to &&
|
||||
//
|
||||
NotEmptyZero(lower) &&
|
||||
NotEmptyZero(upper) &&
|
||||
upper > lower
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Validate To Edge Breakes ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
iPrice = bar.GetPrice(breakPriceType);
|
||||
result = NotEmptyZero(iPrice);
|
||||
|
||||
//
|
||||
// Validate To Edge Breakes ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
isUpperBreaked = iPrice > upper;
|
||||
isLowerBreaked = iPrice < lower;
|
||||
|
||||
//
|
||||
// Validate To Break ...
|
||||
result = isUpperBreaked || isLowerBreaked;
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Direction ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
dir =
|
||||
isUpperBreaked
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Direction ...
|
||||
result = HasDirection(dir);
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Zone ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
zone.to = to;
|
||||
zone.dir = dir;
|
||||
zone.from = from;
|
||||
zone.at = bar.time;
|
||||
zone.upper = upper;
|
||||
zone.lower = lower;
|
||||
zone.symbol = bar.symbol;
|
||||
zone.period = bar.period;
|
||||
zone.type = ToXString(X_BAR_PATTERN_CONSOLIDATION);
|
||||
|
||||
//
|
||||
// Validate Zone ...
|
||||
result = zone.IsValid();
|
||||
|
||||
//
|
||||
// Validate Zone Length ...
|
||||
if (result)
|
||||
{
|
||||
result = zone.FromIndex() - zone.ToIndex() >= validationLength;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
zone.Clean();
|
||||
CleanDirection(dir);
|
||||
}
|
||||
iBar.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// FVG ...
|
||||
|
||||
|
||||
Reference in New Issue
Block a user