last ...
This commit is contained in:
@@ -1660,428 +1660,6 @@ class XCMarketPatternDetector : public XCBase
|
||||
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,
|
||||
XLeg &leg,
|
||||
int validationLength = 3,
|
||||
int loopback = 10 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
leg.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 zone;
|
||||
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();
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare XLeg ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
leg.dir = zone.dir;
|
||||
leg.time = zone.from;
|
||||
leg.upper = zone.upper;
|
||||
leg.lower = zone.lower;
|
||||
leg.symbol = zone.symbol;
|
||||
leg.period = zone.period;
|
||||
Copy(patterns, leg.patterns);
|
||||
Copy(supports, leg.supports);
|
||||
Copy(bullishBars, leg.bullishBars);
|
||||
Copy(bearishBars, leg.bearishBars);
|
||||
Copy(resistances, leg.resistances);
|
||||
Copy(bullishFVGs, leg.bullishFVGs);
|
||||
Copy(bearishFVGs, leg.bearishFVGs);
|
||||
leg.sequentialBullishBars = sequentialsBullishBarsCount;
|
||||
leg.sequentialBearishBars = sequentialsBearishBarsCount;
|
||||
|
||||
//
|
||||
result = leg.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
if (!result)
|
||||
{
|
||||
zone.Clean();
|
||||
}
|
||||
iBar.Clean();
|
||||
pBar.Clean();
|
||||
zone.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 ...
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user