Files
xMQL5/BKPS/14041018/Documents/BKP/x-saherelm.xfima.signaller.class copy 2.mq5
T
2026-01-08 11:39:42 +03:30

2249 lines
60 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class
// -------------------------------------------------
// Name: XCXFIMASignaller ...
// Description: XFIMA Signaller 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 Signaller Class"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.x-signaller.class.mq5"
#include "../../Helpers/x-saherelm.xfima.helper.mq5"
#include "../Classes/x-saherelm.xfima.x-poi.detector.class.mq5"
#include "../Classes/x-saherelm.xfima.x-poi.drawer.class.mq5"
//
// Implementation ...
//
// Base XFIMA base Signaller ...
class XCXFIMABaseSignaller : public XCBaseSignaller
{
//
// Public ...
public:
//
// Props ...
//
bool ignoreTargets; // Ignore Signal Targets ...
XFIMAInputs fimaInputs; // XFIMA Inputs ...
XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ...
XCXFIMAPOIDrawer *poiDrawer; // XFIMA POI Drawer ...
XCXFIMAPOIDetector *poiDetector; // XFIMA POI Detector ...
//
// Constructor ...
XCXFIMABaseSignaller(
string _name, // Name ...
string _symbol, // Symbol ...
ENUM_TIMEFRAMES _period, // Period ...
XFIMAInputs &_fimaInputs, // XFIMAInputs ...
bool _processAllTicks = false, // Process All Ticks ...
double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ...
double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ...
double _defaultSignalVolume = 0.01 // Default Signal Volume ...
) : XCBaseSignaller(_name,
_symbol,
_period,
_processAllTicks,
_defaultSignalR2R,
_defaultSignalRiskInPoint,
_defaultSignalVolume //
)
{
//
// Instantiating XFIMA Indicator Helper Class ...
if (_fimaInputs.IsValid())
{
//
fimaHelper = new XCXFIMAHelper();
bool isInited = fimaHelper.Init(
_symbol,
_period,
_fimaInputs //
);
if (isInited)
{
fimaInputs = _fimaInputs;
}
else
{
//
delete fimaHelper;
ZeroMemory(fimaHelper);
}
}
//
poiDrawer = new XCXFIMAPOIDrawer();
poiDetector = new XCXFIMAPOIDetector(fimaHelper);
}
//
// Deconstructor ...
~XCXFIMABaseSignaller()
{
Destroy();
}
//
// Overrides ...
//
// Actions ...
/**
* Destroy ...
*/
void Destroy()
{
//
BeforeDestroy();
//
fimaInputs.Clean();
//
delete fimaHelper;
ZeroMemory(fimaHelper);
//
delete poiDrawer;
ZeroMemory(poiDrawer);
//
delete poiDetector;
ZeroMemory(poiDetector);
}
//
// Virtuals ...
/**
* Before Destroy ...
*/
void virtual BeforeDestroy()
{
}
/**
* Processing Tick ...
*
* @param barIndex: int, Specified Bar Index ...
*/
virtual void ProcessTick(int barIndex = 0)
{
}
/**
* Processing New Bar ...
*
* @param barIndex: int, Specified Bar Index ...
*/
virtual void ProcessNewBar(int barIndex = 0)
{
}
/**
* Check Guards Based on MarketConditions ...
*
* @param guards: XGuard, reference collection to holds result ...
* @param positions: XPosition, reference collection to provides positions ...
* @param barIndex: int
*
* @return ( int )
*/
int virtual CheckForGuard(
XGuard &guards[],
XPosition &positions[],
int barIndex = 0 //
)
{
//
int result = 0;
//
SpecifiedClean(guards);
//
result = ArraySize(guards);
//
return result;
}
/**
* Check Additional Validations on Childs Instances ...
*
* @return ( bool virtual )
*/
bool virtual CheckAdditionslSignallerValidations()
{
//
bool result = false;
//
// Validate Fima Helper Requirements ...
result = fimaInputs.IsValid() &&
fimaHelper != NULL &&
poiDetector != NULL;
//
return result;
}
/**
* Normalizing Signal by Signaller Custom Props ...
*
* @param signal: XSignal ...
*/
void virtual NormalizeSignal(XSignal &signal)
{
}
//
// Protected ...
protected:
//
//
// Protected Actions ...
/**
* Check Specified Bar has Pattern or not ...
*
* @param bar: XOHCL, reference to Specified Bar ...
* @param name: string, reference to holds Detected Patterns Name ...
* @param dir: ENUM_X_DIRECTION, reference to holds Detected Patterns Direction ...
* @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ...
*
* @return ( bool )
*/
bool HasPattern(
XOHCL &bar,
string &patternName,
ENUM_X_DIRECTION &patternDir,
XFIMAMarketStructure &structure //
)
{
//
bool result = false;
//
// Prepare ...
patternName = NULL;
patternDir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Check Required Pattern Exists ...
bool hasPinnedBar = HasDirection(structure.pinnedDir);
bool hasEngulfedBar = HasDirection(structure.engulfedDir);
bool hasFlagPattern = HasDirection(structure.flagPatternDir);
bool hasStarPattern = HasDirection(structure.starPatternDir);
bool hasRisingPattern = HasDirection(structure.risingPatternDir);
bool hasPiercingPattern = HasDirection(structure.piercingPatternDir);
bool hasSignalKeyBar = HasDirection(structure.signalKeyBarPatternDir);
//
// Check Bar Pattern Exists ...
// and Select Pattern Direction and Price and Price Type ...
result = hasPinnedBar ||
hasEngulfedBar ||
hasFlagPattern ||
hasStarPattern ||
hasSignalKeyBar ||
hasRisingPattern ||
hasPiercingPattern;
//
if (result)
{
//
if (hasPinnedBar)
{
//
patternDir = structure.pinnedDir;
patternName = "XPinned_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasEngulfedBar)
{
//
patternDir = structure.engulfedDir;
patternName = "XEngulfed_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasFlagPattern)
{
//
patternDir = structure.flagPatternDir;
patternName = "XFlag_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasStarPattern)
{
//
patternDir = structure.starPatternDir;
patternName = "XStar_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasSignalKeyBar)
{
//
patternDir = structure.risingPatternDir;
patternName = "XRising_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasRisingPattern)
{
//
patternDir = structure.piercingPatternDir;
patternName = "XPiercing_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasPiercingPattern)
{
//
patternDir = structure.signalKeyBarPatternDir;
patternName = "XSignalKey_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
}
}
//
result =
result &&
IsXValid(patternName) &&
HasDirection(patternDir);
//
return result;
}
/**
* Validate a Pattern based on MA Band ...
*
* @param bar: XOHCL, reference to Pattern Bar ...
* @param patternName: string, detected pattern's name ...
* @param patternDir: ENUM_X_DIRECTION, detected pattern's direction ...
* @param fimaConditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
*
* @return ( bool )
*/
bool ValidatePatternBasedOnMABand(
XOHCL &bar,
string patternName,
ENUM_X_DIRECTION patternDir,
XFIMAConditions &fimaConditions //
)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
IsXValid(patternName) &&
HasDirection(patternDir);
if (!result)
{
return result;
}
//
// Define Requirements ...
bool isBullish = false;
bool isBearish = false;
double iPrice = EMPTY_VALUE;
double iPriceEdge = EMPTY_VALUE;
ENUM_X_PRICE iPriceType = X_PRICE_NONE;
ENUM_X_PRICE iPriceEdgeType = X_PRICE_NONE;
//
// Calculating Price and Price Types ...
//
isBullish = IsXBullish(patternDir);
isBearish = IsXBearish(patternDir);
//
iPriceType = isBullish
? X_PRICE_DOWN
: X_PRICE_UP;
//
iPriceEdgeType = isBullish
? X_PRICE_LOW
: X_PRICE_HIGH;
//
iPrice = bar.GetPrice(iPriceType);
iPriceEdge = bar.GetPrice(iPriceEdgeType);
//
// Validate ...
result =
NotEmptyZero(iPrice) &&
IsXValid(iPriceType) &&
NotEmptyZero(iPriceEdge) &&
IsXValid(iPriceEdgeType) &&
((isBullish && !isBearish) ||
(isBearish && !isBullish));
if (!result)
{
return result;
}
//
// Validate Pattern based on MA Band ...
//
// Retrieve MA Band for Validation ...
double iMABandUpper = fimaConditions.maBondUpperBuffer[0];
double iMABandLower = fimaConditions.maBondLowerBuffer[0];
//
// Validate by Edge Price ...
result =
NotEmptyZero(iMABandUpper) &&
NotEmptyZero(iMABandLower) &&
(isBullish
? iPriceEdge < iMABandLower
: iPriceEdge > iMABandUpper);
if (!result)
{
return result;
}
//
return result;
}
//
// Private ...
private:
//
};
//
// XFIMA Strategy 2 Signaller Class ...
class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
{
//
// Public ...
public:
//
// Props ...
CArrayObj drawnObjects;
// XFIMAPatternDetectorConfig analyserConfig;
//
// Constructor ...
XCXFIMAStrategy1Signaller(
string _symbol, // Symbol ...
ENUM_TIMEFRAMES _period, // Period ...
XFIMAInputs &_fimaInputs, // XFIMAInputs ...
bool _processAllTicks = false, // Process All Ticks ...
double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ...
double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ...
double _defaultSignalVolume = 0.01 // Default Signal Volume ...
) : XCXFIMABaseSignaller("XFIMA1",
_symbol,
_period,
_fimaInputs,
_processAllTicks,
_defaultSignalR2R,
_defaultSignalRiskInPoint,
_defaultSignalVolume //
)
{
//
// Configure Detector ...
//
analyserConfig.Default();
analyserConfig.validMACrossDiffMultiplier = 4;
//
analyserConfig.FullDetect();
//
// Ignore Signal Targets ...
ignoreTargets = true;
}
//
// Deconstructor ...
~XCXFIMAStrategy1Signaller()
{
//
Destroy();
//
analyserConfig.Clean();
}
//
// Overrides ...
/**
* Processing Tick ...
*
* @param barIndex: int, Specified Bar Index ...
*/
virtual void ProcessTick(int barIndex = 0)
{
}
/**
* Processing New Bar ...
*
* @param barIndex: int, Specified Bar Index ...
*/
virtual void ProcessNewBar(int barIndex = 0)
{
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
//
XOHCL iBar;
int count = 0;
XBoxZone iZone;
XSignal iSignal;
bool has = false;
XTarget iTargets[];
string iName = NULL;
bool isBullish = false;
bool isBearish = false;
XPatternAnalysis iBarAnalysis;
XFIMAConditions iFIMAConditions;
XFIMAMarketStructure iStructure;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
// Initialize Bar as CBar ...
has = iBar.Init(
symbol,
period,
barIndex //
);
if (!has)
{
//
iBar.Clean();
return;
}
//
// Retrieve Conditions ...
has = fimaHelper.GetConditions(
iFIMAConditions,
barIndex,
10 // Loopback ...
);
if (!has)
{
//
iBar.Clean();
iFIMAConditions.Clean();
//
return;
}
//
// Analyse Market ...
poiDetector.AnalyseMarket(
iBar,
iStructure,
analyserConfig //
);
//
// Bar Pattern Analysis Detection Test ...
has = poiDetector.AnalyseBarPatterns(
iBar,
iBarAnalysis
//
// Use Default Config ...
);
DrawBarPatternAnalysis(iBarAnalysis);
//
// Disable Signallers ...
has = false;
iDir = X_DIRECTION_NONE;
//
// Strategy 1 ...
// Works on Support or Resistances Areas ...
// has = Strategy1HasSignal(
// iBar,
// iZone,
// iTargets,
// iDir,
// iFIMAConditions,
// iStructure //
// );
//
// Strategy 2 ...
// Works on MA Crosses ...
if (!has)
{
//
// has = Strategy2HasSignal(
// iBar,
// iZone,
// iTargets,
// iDir,
// iFIMAConditions,
// iStructure //
// );
}
//
has = HasDirection(iDir);
if (has)
{
//
isBullish = IsXBullish(iDir);
isBearish = IsXBearish(iDir);
//
// TODO: Provided SL ...
double _point = GetPoints(iBar.symbol);
double slAddition = 5 * _point;
double slPrice =
isBullish
? iZone.lower - slAddition
: iZone.upper + slAddition;
//
// Prepare Founded Signal ...
//
// Handle Signal Targets ...
if (ignoreTargets)
{
XClean(iTargets);
}
//
has = PrepareSignal(
iSignal,
iDir,
iTargets,
0, // Use Default R2R ...
slPrice, // Provided Price for SL ...
0 // Specified Risk in Point ....
);
if (has)
{
//
// Notify On Signal Event ...
NotifySignalEventListeners(iSignal);
}
}
//
// Cleanup Resources ...
iBar.Clean();
iZone.Clean();
iSignal.Clean();
iStructure.Clean();
iBarAnalysis.Clean();
iFIMAConditions.Clean();
SpecifiedClean(iTargets);
}
/**
* Check Guards Based on MarketConditions ...
*
* @param guards: XGuard, reference collection to holds result ...
* @param positions: XPosition, reference collection to provides positions ...
* @param barIndex: int
*
* @return ( int )
*/
int virtual CheckForGuard(
XGuard &guards[],
XPosition &positions[],
int barIndex = 0 //
)
{
//
int result = 0;
//
SpecifiedClean(guards);
//
result = ArraySize(guards);
//
return result;
}
//
// Private ...
private:
//
// Props ...
//
// Implementing Strategies ...
/**
* Check Bar Has Signal Based on Strategy 1 ...
*
* @param bar: XOHCL, reference to Bar ...
* @param zone: XBoxZone, reference to holds affected zone ...
* @param targets: XTarget, reference to detected Signal's Targets collections ...
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
* @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
* @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ...
*
* @return ( bool )
*/
bool Strategy1HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir,
XFIMAConditions &conditions,
XFIMAMarketStructure &structure //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Check Pattern Exists ...
string patternName = NULL;
ENUM_X_DIRECTION patternDir = X_DIRECTION_NONE;
result = HasPattern(
bar,
patternName,
patternDir,
structure //
);
if (!result)
{
return result;
}
//
// Validate Pattern Based on MA Band ...
result = ValidatePatternBasedOnMABand(
bar,
patternName,
patternDir,
conditions //
);
if (!result)
{
return result;
}
//
// Here i Use Specified Supports and Resistances ...
XBoxZone tmpBox;
bool has = false;
XBoxZone supports[];
XBoxZone resistances[];
//
has = structure.pvAnalysis.IsValid() &&
structure.pvAnalysis.HasSupportBox(tmpBox);
if (has)
{
//
tmpBox.to = bar.time;
AddIfNotExists(
tmpBox,
supports //
);
}
//
has = structure.zigzagAnalysis.IsValid() &&
structure.zigzagAnalysis.HasSupportBox(tmpBox);
if (has)
{
//
tmpBox.to = bar.time;
AddIfNotExists(
tmpBox,
supports //
);
}
//
has = structure.pvAnalysis.IsValid() &&
structure.pvAnalysis.HasResistanceBox(tmpBox);
if (has)
{
//
tmpBox.to = bar.time;
AddIfNotExists(
tmpBox,
resistances //
);
}
//
has = structure.zigzagAnalysis.IsValid() &&
structure.zigzagAnalysis.HasResistanceBox(tmpBox);
if (has)
{
//
tmpBox.to = bar.time;
AddIfNotExists(
tmpBox,
resistances //
);
}
//
// Check Affected Zone ...
// Select a Support or Resistance ...
int insideZoneIDX = -1;
result =
(IsXBullish(patternDir)
? HasInside(
insideZoneIDX,
bar,
supports //
)
: IsXBearish(patternDir)
? HasInside(
insideZoneIDX,
bar,
resistances //
)
: false //
);
if (!result)
{
return result;
}
//
// Filling Affected Zone ...
// and Validate it ...
if (IsXBullish(patternDir))
{
zone = supports[insideZoneIDX];
}
else if (IsXBearish(patternDir))
{
zone = resistances[insideZoneIDX];
}
result = zone.IsValid();
if (!result)
{
return result;
}
//
// Validate affected Zone based on Pattern's Bar ...
result = IsXBullish(patternDir)
? bar.high > zone.upper
: IsXBearish(patternDir)
? bar.low < zone.lower
: false;
//
// Validate Zone ...
if (result)
{
//
//
}
//
// Draw Requirements ...
// if (result)
// {
// //
// // Support and Resistances ...
// CArrayObj *zoneObjs;
// poiDrawer.DrawBoxes(
// supports,
// zoneObjs //
// );
// poiDrawer.DrawBoxes(
// resistances,
// zoneObjs //
// );
// //
// // Zone ...
// XCBoxObject *iZoneObj;
// bool isDrawn = poiDrawer.DrawBox(
// zone,
// iZoneObj,
// true,
// zone.type //
// );
// if (isDrawn)
// {
// //
// XPOIStyle iStyle;
// iStyle.width = 2;
// iStyle.clr = clrYellow;
// poiDrawer.ApplyBoxStyle(
// iZoneObj,
// iStyle //
// );
// }
// //
// // Pattern ...
// XCBarArrowObject *iPObj;
// poiDrawer.DrawBarArrow(
// bar,
// iPObj,
// zone.IsBullish() ? X_PRICE_LOW : X_PRICE_HIGH,
// 159,
// clrYellow,
// 3, // With ...
// zone.IsBullish() ? ANCHOR_BOTTOM : ANCHOR_TOP,
// patternName //
// );
// // poiDrawer.DrawBoxes(
// // structure.fvgs,
// // zoneObjs,
// // false //
// // );
// Print("SALAM");
// }
if (result)
{
//
dir = patternDir;
//
// Handle Targets Detection ...
//
// Check Reversal FVGS ...
int idx = -1;
XTarget target;
XBoxZone targetZones[];
int numberOfTargets = 3;
double actingDistance = 20;
double iValue = EMPTY_VALUE;
bool ignoreFirstTarget = false;
ENUM_X_DIRECTION targetsDir = Opposit(dir);
int count = ExtractByDirection(
targetZones,
structure.fvgs,
targetsDir //
);
bool has = IsValidSize(count);
if (has)
{
//
// Calculate Value ...
double points = GetPoints(zone.symbol);
double zoneRange = zone.upper - zone.lower;
iValue = IsXBullish(dir)
? (zone.upper + (zoneRange * defaultSignalR2R))
: (zone.lower + (zoneRange * defaultSignalR2R));
double defaultTarget = iValue;
//
// Looping Back ...
for (int i = 0; i < numberOfTargets; i++)
{
//
// Detect Lowest Above Zone ...
if (IsXBullish(dir))
{
//
idx = GetLowestAbove(iValue, targetZones);
has = IsValidIndex(idx);
if (!has)
{
break;
}
//
iValue = targetZones[idx].lower;
}
//
// Detect Highest below Zone ...
else if (IsXBearish(dir))
{
//
idx = GetHighestBelow(iValue, targetZones);
has = IsValidIndex(idx);
if (!has)
{
break;
}
//
iValue = targetZones[idx].upper;
}
//
// Validate Target Value ...
has = NotEmptyZero(iValue) &&
iValue != defaultTarget;
if (has)
{
//
// Init Target ...
target.Clean();
target.doRF = true;
target.target = iValue;
target.actingDistance = actingDistance;
has = target.IsValid();
if (has)
{
//
// Add Target to Targets ...
AddRef(
target,
targets //
);
}
target.Clean();
}
}
//
// Remove Nearest ...
has = ignoreFirstTarget &&
HasChild(targets);
if (has)
{
//
ArrayRemove(
targets,
0,
1 //
);
}
}
//
// Cleanup Resources ...
target.Clean();
XClean(targetZones);
}
//
// Cleanup Resources ...
if (!result)
{
//
zone.Clean();
XClean(targets);
}
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 1 ...
*
* @param bar: XOHCL, reference to Bar ...
* @param zone: XBoxZone, reference to holds affected zone ...
* @param targets: XTarget, reference to detected Signal's Targets collections ...
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
* @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
* @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ...
*
* @return ( bool )
*/
bool Strategy2HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir,
XFIMAConditions &conditions,
XFIMAMarketStructure &structure //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Detect Specified MA Cross ...
result = HasDirection(structure.maCrossDir);
//
// Prepare zone ...
if (result)
{
//
zone.to = bar.time;
zone.from = GetBarTime(
bar.symbol,
bar.period,
bar.Index() + 2 //
);
zone.symbol = bar.symbol;
zone.period = bar.period;
zone.dir = structure.maCrossDir;
zone.lower = bar.FindLowest(2, MODE_LOW);
zone.upper = bar.FindHighest(2, MODE_HIGH);
zone.type = name + "_" + ToXString(structure.maCrossDir);
//
result = zone.IsValid();
}
//
// Check Result ...
if (result)
{
//
dir = structure.maCrossDir;
//
// Handle Targets Detection ...
}
//
// Cleanup Resources ...
if (!result)
{
//
zone.Clean();
XClean(targets);
}
//
return result;
}
//
// Drawer Functions ...
/**
* Draw Specified Pattern info ...
*
* @param _bar: XOHCL, reference to Pattern's Bar ...
* @param _pivot: XPivot, reference to Pattern's Pivot ...
* @param _zone: XBoxZone, reference to Pattern's Zone ...
* @param _pattern: ENUM_X_BAR_PATTERN, Specified Bar Pattern ...
* @param _patternDir: ENUM_X_DIRECTION, Specified Bar Pattern's Direction ...
*/
void DrawPattern(
XOHCL &_bar,
XPivot &_pivot,
XBoxZone &_zone,
ENUM_X_BAR_PATTERN _pattern,
ENUM_X_DIRECTION _patternDir,
int thresholdMultiplier = 0 //
)
{
//
// Normalize ...
thresholdMultiplier = NormalizeInt(thresholdMultiplier, 1);
//
// Validate ...
bool has =
poiDrawer != NULL &&
_bar.IsValid() &&
IsXValid(_pattern) &&
HasDirection(_patternDir);
if (!has)
{
return;
}
//
// Defien Draw Requirements ...
//
int width = 3;
bool ignoreBoxAt = true;
int arrowThreshold = 5 * thresholdMultiplier;
//
int bullishArrow = 159;
int bearishArrow = 159;
//
ENUM_X_PRICE arrowValePriceType = X_PRICE_LOW;
ENUM_X_PRICE arrowPeakPriceType = X_PRICE_HIGH;
//
color bullishColor = clrAqua;
color bearishColor = clrMagenta;
//
// Draw Bar ...
//
// Draw Pivot ...
if (_pivot.IsValid())
{
//
XCBarArrowObject *iObj;
has = poiDrawer.DrawBarArrow(
_bar,
iObj,
_pivot.IsPeak()
? arrowPeakPriceType
: arrowValePriceType,
IsXBullish(_patternDir)
? bullishArrow
: bearishArrow,
IsXBullish(_patternDir)
? bullishColor
: bearishColor,
width,
IsXBullish(_patternDir)
? ANCHOR_TOP
: ANCHOR_BOTTOM,
_pivot.prefix + "_Pivot_" + ToXString(TimeToSeconds(_pivot.time)),
true, // Ignore Bar Tag ...
arrowThreshold // Threshold ...
);
if (has)
{
drawnObjects.Add(iObj);
}
//
ZeroMemory(iObj);
}
//
// Draw Box ...
if (_zone.IsValid())
{
//
XCBoxObject *iObj;
has = poiDrawer.DrawBox(
_zone,
iObj,
ignoreBoxAt,
_zone.type + "_Zone_" + ToXString(TimeToSeconds(_zone.from)) //
);
if (has)
{
//
XPOIStyle iStyle;
poiDrawer.GetBoxStyle(
iStyle,
_zone.dir //
);
//
iStyle.clr =
IsXBullish(_patternDir)
? bullishColor
: bearishColor;
//
poiDrawer.ApplyBoxStyle(
iObj,
iStyle //
);
//
drawnObjects.Add(iObj);
//
iStyle.Clean();
}
//
ZeroMemory(iObj);
}
}
/**
* Draw Specified Bar Pattern Analysis ...
*
* @param barAnalysis: XPatternAnalysis, reference to Specified Bar Pattern Analysis ...
*/
void DrawBarPatternAnalysis(XPatternAnalysis &barAnalysis)
{
//
bool has = barAnalysis.IsValid();
if (!has)
{
return;
}
//
// Configure Draws ...
XPatternAnalysisDrawConfig config;
config.Clean();
//
Add(X_BAR_PATTERN_LOW, config.allowedDraws);
Add(X_BAR_PATTERN_HIGH, config.allowedDraws);
Add(X_BAR_PATTERN_STAR, config.allowedDraws);
Add(X_BAR_PATTERN_FLAG, config.allowedDraws);
Add(X_BAR_PATTERN_PINNED, config.allowedDraws);
Add(X_BAR_PATTERN_RISING, config.allowedDraws);
Add(X_BAR_PATTERN_MOMENTUM, config.allowedDraws);
Add(X_BAR_PATTERN_ENGULFED, config.allowedDraws);
Add(X_BAR_PATTERN_PIERCING, config.allowedDraws);
Add(X_BAR_PATTERN_SIGNALKEY, config.allowedDraws);
Add(X_BAR_PATTERN_TRUE_GAPED, config.allowedDraws);
//
Add(X_BAR_PATTERN_LOW, config.allowedDrawPivots);
Add(X_BAR_PATTERN_HIGH, config.allowedDrawPivots);
Add(X_BAR_PATTERN_PINNED, config.allowedDrawPivots);
Add(X_BAR_PATTERN_MOMENTUM, config.allowedDrawPivots);
Add(X_BAR_PATTERN_ENGULFED, config.allowedDrawPivots);
Add(X_BAR_PATTERN_TRUE_GAPED, config.allowedDrawPivots);
//
Add(X_BAR_PATTERN_STAR, config.allowedDrawZones);
Add(X_BAR_PATTERN_FLAG, config.allowedDrawZones);
Add(X_BAR_PATTERN_RISING, config.allowedDrawZones);
Add(X_BAR_PATTERN_PIERCING, config.allowedDrawZones);
Add(X_BAR_PATTERN_SIGNALKEY, config.allowedDrawZones);
//
Add(X_BAR_PATTERN_SUPPORT, config.allowedDraws);
Add(X_BAR_PATTERN_RESISTANCE, config.allowedDraws);
//
Add(X_BAR_PATTERN_SUPPORT, config.allowedDrawZones);
Add(X_BAR_PATTERN_RESISTANCE, config.allowedDrawZones);
//
config.Clean();
//
// Draw Bar Patterns Analysis ...
//
bool canDraw;
bool isBullish;
bool isBearish;
XOHCL patternBar;
bool canDrawZone;
bool canDrawPivot;
XPivot patternPivot;
XBoxZone patternBox;
ENUM_X_BAR_PATTERN pattern;
ENUM_X_DIRECTION patternDir;
//
int patternsPivotThresholdMultiplier = 0;
//
// Support and Resistance ...
//
// Support ...
isBearish = false;
isBullish = barAnalysis.IsSupport();
has = isBullish;
if (has)
{
//
pattern = X_BAR_PATTERN_SUPPORT;
patternDir = X_DIRECTION_BULLISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// Resistance ...
isBullish = false;
isBearish = barAnalysis.IsResistance();
has = isBearish;
if (has)
{
//
pattern = X_BAR_PATTERN_RESISTANCE;
patternDir = X_DIRECTION_BEARISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// PV: High and Low ...
//
// Low ...
isBearish = false;
isBullish = barAnalysis.IsLow();
has = isBullish;
if (has)
{
//
pattern = X_BAR_PATTERN_LOW;
patternDir = X_DIRECTION_BULLISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// High ...
isBullish = false;
isBearish = barAnalysis.IsHigh();
has = isBearish;
if (has)
{
//
pattern = X_BAR_PATTERN_HIGH;
patternDir = X_DIRECTION_BEARISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// OB ...
isBullish = barAnalysis.IsOB(X_DIRECTION_BULLISH);
isBearish = barAnalysis.IsOB(X_DIRECTION_BEARISH);
has = isBullish || isBearish;
if (has)
{
//
pattern = X_BAR_PATTERN_OB;
patternDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// FVG ...
isBullish = barAnalysis.IsFVG(X_DIRECTION_BULLISH);
isBearish = barAnalysis.IsFVG(X_DIRECTION_BEARISH);
has = isBullish || isBearish;
if (has)
{
//
pattern = X_BAR_PATTERN_FVG;
patternDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// Momentum ...
isBullish = barAnalysis.IsMomentum(X_DIRECTION_BULLISH);
isBearish = barAnalysis.IsMomentum(X_DIRECTION_BEARISH);
has = isBullish || isBearish;
if (has)
{
//
pattern = X_BAR_PATTERN_MOMENTUM;
patternDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// Engulfed ...
isBullish = barAnalysis.IsEngulfed(X_DIRECTION_BULLISH);
isBearish = barAnalysis.IsEngulfed(X_DIRECTION_BEARISH);
has = isBullish || isBearish;
if (has)
{
//
pattern = X_BAR_PATTERN_ENGULFED;
patternDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// Pinned ...
isBullish = barAnalysis.IsPinned(X_DIRECTION_BULLISH);
isBearish = barAnalysis.IsPinned(X_DIRECTION_BEARISH);
has = isBullish || isBearish;
if (has)
{
//
pattern = X_BAR_PATTERN_PINNED;
patternDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// TrueGaped ...
isBullish = barAnalysis.IsTrueGaped(X_DIRECTION_BULLISH);
isBearish = barAnalysis.IsTrueGaped(X_DIRECTION_BEARISH);
has = isBullish || isBearish;
if (has)
{
//
pattern = X_BAR_PATTERN_TRUE_GAPED;
patternDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// Star ...
isBullish = barAnalysis.IsStar(X_DIRECTION_BULLISH);
isBearish = barAnalysis.IsStar(X_DIRECTION_BEARISH);
has = isBullish || isBearish;
if (has)
{
//
pattern = X_BAR_PATTERN_STAR;
patternDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// Piercing ...
isBullish = barAnalysis.IsPiercing(X_DIRECTION_BULLISH);
isBearish = barAnalysis.IsPiercing(X_DIRECTION_BEARISH);
has = isBullish || isBearish;
if (has)
{
//
pattern = X_BAR_PATTERN_PIERCING;
patternDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// Rising ...
isBullish = barAnalysis.IsRising(X_DIRECTION_BULLISH);
isBearish = barAnalysis.IsRising(X_DIRECTION_BEARISH);
has = isBullish || isBearish;
if (has)
{
//
pattern = X_BAR_PATTERN_RISING;
patternDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// Flag ...
isBullish = barAnalysis.IsFlag(X_DIRECTION_BULLISH);
isBearish = barAnalysis.IsFlag(X_DIRECTION_BEARISH);
has = isBullish || isBearish;
if (has)
{
//
pattern = X_BAR_PATTERN_FLAG;
patternDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// SignalKey ...
isBullish = barAnalysis.IsSignalKey(X_DIRECTION_BULLISH);
isBearish = barAnalysis.IsSignalKey(X_DIRECTION_BEARISH);
has = isBullish || isBearish;
if (has)
{
//
pattern = X_BAR_PATTERN_SIGNALKEY;
patternDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
canDraw = config.CanDraw(pattern);
if (canDraw)
{
//
has = barAnalysis.GetPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir //
);
if (has)
{
//
canDrawZone = config.CanDrawZone(pattern);
if (!canDrawZone)
{
patternBox.Clean();
}
//
canDrawPivot = config.CanDrawPivot(pattern);
if (!canDrawPivot)
{
patternPivot.Clean();
}
else
{
patternsPivotThresholdMultiplier++;
}
//
DrawPattern(
patternBar,
patternPivot,
patternBox,
pattern,
patternDir,
patternsPivotThresholdMultiplier //
);
}
}
}
//
// Cleanup Resources ...
patternBar.Clean();
patternBox.Clean();
patternPivot.Clean();
}
//
};
//