Files
MQL5Data/Documents/BKP/x-saherelm.xfima.signaller.class.mq5
T
2025-09-29 16:22:30 +03:30

3804 lines
105 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 ...
//
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[]
* @param barIndex: int
*
* @return ( int )
*/
int virtual CheckForGuard(
XGuard &guards[],
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:
//
//
// Private ...
private:
//
};
//
// XFIMA Strategy 1 Signaller Class ...
class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
{
//
// Public ...
public:
//
// Props ...
int fvgLookupLenght; // Maximum Lenght for Looking up FVG before Crosses
//
// 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 //
)
{
//
fvgLookupLenght = 5;
}
//
// 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);
//
// Update Helper ...
fimaHelper.Update(barIndex);
//
XOHCL bar;
XSignal signal;
bool has = false;
int cIdx = barIndex + 1;
int pIdx = cIdx + 1;
ENUM_X_DIRECTION signalDir = X_DIRECTION_NONE;
//
// Initialize Bar as CBar ...
has = bar.Init(
symbol,
period,
cIdx //
);
if (!has)
{
//
bar.Clean();
return;
}
//
// Retrieve Conditions ...
XFIMAConditions fimaConditions;
has = fimaHelper.GetConditions(
fimaConditions,
barIndex,
10 // Loopback ...
);
if (!has)
{
//
bar.Clean();
fimaConditions.Clean();
//
return;
}
//
// Analyse Conditions for Finding Signal ...
//
// TODO: Remove this ...
//
bool isFastCrossedOverSlow =
fimaConditions.maFastBuffer[cIdx] > fimaConditions.maSlowBuffer[cIdx] &&
fimaConditions.maFastBuffer[pIdx] < fimaConditions.maSlowBuffer[pIdx];
//
bool isFastCrossedUnderSlow =
fimaConditions.maFastBuffer[cIdx] < fimaConditions.maSlowBuffer[cIdx] &&
fimaConditions.maFastBuffer[pIdx] > fimaConditions.maSlowBuffer[pIdx];
//
has =
isFastCrossedOverSlow ||
isFastCrossedUnderSlow;
if (has)
{
//
// Do Conditions Validating ...
// TODO: Igmore All Validations for Testing Purposes ...
//
// Validate MA Positions ...
double iFastMa = fimaConditions.maFastBuffer[cIdx];
double iSlowMa = fimaConditions.maSlowBuffer[cIdx];
double iFiboUpper = fimaConditions.fiboUpperBuffer[cIdx];
double iFiboLower = fimaConditions.fiboLowerBuffer[cIdx];
//
// Checking Has FVG ...
XBoxZone fvg;
ENUM_X_DIRECTION fvgDir;
bool hasFVG = patternDetector.HasFVG(
bar,
fvgDir,
fvg,
fvgLookupLenght //
);
//
// Checking Crossed On Shadow ...
//
bool isCrossedOverHappensOnShadow =
isFastCrossedOverSlow &&
iFastMa <= bar.GetDown() &&
iFastMa >= bar.low;
//
bool isCrossedUnderHappensOnShadow =
isFastCrossedUnderSlow &&
iFastMa <= bar.high &&
iFastMa >= bar.GetUp();
//
// Bullish Validation ...
bool isBullish =
//
// Has Cross ...
isFastCrossedOverSlow
//
// &&
// //
// // Cross Places Based on Fibo ...
// MathMax(iFastMa, iSlowMa) < iFiboLower
// //
// &&
// //
// (
// //
// // Checking FVG ...
// (hasFVG &&
// fvg.IsBullish())
// //
// ||
// //
// // Checking Crossed Place ...
// isCrossedOverHappensOnShadow
// //
// )
// //
;
//
// Bearish Validation ...
bool isBearish =
//
// Has Cross ...
isFastCrossedUnderSlow
//
// &&
// //
// // Cross Places Based on Fibo ...
// MathMin(iFastMa, iSlowMa) > iFiboUpper
// //
// &&
// //
// (
// //
// // Checking FVG ...
// (hasFVG &&
// fvg.IsBearish())
// //
// ||
// //
// // Checking Crossed Place ...
// isCrossedUnderHappensOnShadow
// //
// )
// //
;
//
has =
(isBullish && !isBearish) ||
(isBearish && !isBullish);
if (has)
{
//
signalDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
}
//
// Check Signal Founded ...
has = HasDirection(signalDir);
if (has)
{
//
// Prepare Founded Signal ...
XTarget targets[];
has = PrepareSignal(
signal,
signalDir,
targets //
);
if (has)
{
//
// Notify On Signal Event ...
NotifySignalEventListeners(signal);
}
}
//
// Cleanup Resources ...
bar.Clean();
signal.Clean();
fimaConditions.Clean();
}
/**
* Check Guards Based on MarketConditions ...
*
* @param guards: XGuard[]
* @param barIndex: int
*
* @return ( int )
*/
int virtual CheckForGuard(
XGuard &guards[],
int barIndex = 0 //
)
{
//
int result = 0;
//
SpecifiedClean(guards);
//
result = ArraySize(guards);
//
return result;
}
//
// Private ...
private:
//
// Props ...
//
// Lookup FVG ...
bool LookupFVG(
XOHCL &bar,
ENUM_X_DIRECTION &dir,
XBoxZone &fvgBox //
)
{
//
bool result = false;
//
return result;
}
//
};
//
// XFIMA Strategy 2 Signaller Class ...
class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller
{
//
// Public ...
public:
//
// Props ...
XFIMAPatternDetectorConfig analyserConfig;
//
// Constructor ...
XCXFIMAStrategy2Signaller(
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("XFIMA2",
_symbol,
_period,
_fimaInputs,
_processAllTicks,
_defaultSignalR2R,
_defaultSignalRiskInPoint,
_defaultSignalVolume //
)
{
//
// Configure Detector ...
analyserConfig.Default();
analyserConfig.FullDetect();
}
//
// Deconstructor ...
~XCXFIMAStrategy2Signaller()
{
//
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 ...
*/
void ProcessNewBarNKP(int barIndex = 0)
{
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
//
// Update Helper ...
fimaHelper.Update(barIndex);
//
XOHCL bar;
XSignal signal;
XBoxZone iZone;
int count = 0;
bool has = false;
int cIdx = barIndex + 1;
int pIdx = cIdx + 1;
string iName = NULL;
XBoxZone supports[];
XBoxZone resistances[];
bool isBullish = false;
bool isBearish = false;
double iPrice = EMPTY_VALUE;
XFIMAMarketStructure structure;
XFIMAConditions fimaConditions;
ENUM_X_PRICE iPriceType = X_PRICE_NONE;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
XPivot pvPivots[];
string pvTrendName = "XXIFMA2PVTrend";
CChartObjectTrend *pvTrendLine = NULL;
ENUM_X_DIRECTION pvTrend = X_DIRECTION_NONE;
//
XPivot zgPivots[];
string zgTrendName = "XFIMA2ZGTrend";
CChartObjectTrend *zgTrendLine = NULL;
ENUM_X_DIRECTION zgTrend = X_DIRECTION_NONE;
//
// Initialize Bar as CBar ...
has = bar.Init(
symbol,
period,
cIdx //
);
if (!has)
{
//
bar.Clean();
return;
}
//
// Retrieve Conditions ...
has = fimaHelper.GetConditions(
fimaConditions,
barIndex,
10 // Loopback ...
);
if (!has)
{
//
bar.Clean();
fimaConditions.Clean();
//
return;
}
//
// Analyse Market ...
poiDetector.AnalyseMarket(
bar,
structure,
analyserConfig //
);
//
// 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 ...
has = hasPinnedBar ||
hasEngulfedBar ||
hasFlagPattern ||
hasStarPattern ||
hasSignalKeyBar ||
hasRisingPattern ||
hasPiercingPattern;
//
// Select Pattern Direction and Price and Price Type ...
if (has)
{
//
if (hasPinnedBar)
{
//
iDir = structure.pinnedDir;
iName = "XPinned_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasEngulfedBar)
{
//
iDir = structure.engulfedDir;
iName = "XEngulfed_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasFlagPattern)
{
//
iDir = structure.flagPatternDir;
iName = "XFlag_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasStarPattern)
{
//
iDir = structure.starPatternDir;
iName = "XStar_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasSignalKeyBar)
{
//
iDir = structure.risingPatternDir;
iName = "XRising_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasRisingPattern)
{
//
iDir = structure.piercingPatternDir;
iName = "XPiercing_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasPiercingPattern)
{
//
iDir = structure.signalKeyBarPatternDir;
iName = "XSignalKey_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
//
isBullish = IsSpecifiedBullish(iDir);
isBearish = IsSpecifiedBearish(iDir);
//
// Retrieve Price Type for Validate ...
iPriceType = isBullish
? X_PRICE_LOW
: X_PRICE_HIGH;
iPrice = bar.GetPrice(iPriceType);
//
has = HasDirection(iDir);
}
//
// Chekc Bullish or Bearish Starter Conditions Exists ...
has =
isBullish ||
isBearish;
if (has)
{
//
// Do Conditions Validating ...
//
// Retrieve MA Band for Validation ...
double iMABandUpper = fimaHelper.GetMABandUpper(barIndex);
double iMABandLower = fimaHelper.GetMABandLower(barIndex);
//
// Validate ...
has = isBullish
? iPrice < iMABandLower
: iPrice > iMABandUpper;
if (!has)
{
//
isBullish = false;
isBearish = false;
iDir = X_DIRECTION_NONE;
}
}
//
// Collect Support and Resistance Zones and Validate by them ...
//
// PV Trend Line ...
bool hasPVAnalysis = structure.pvAnalysis.IsValid();
if (hasPVAnalysis)
{
//
// Support ...
XBoxZone supportBox;
has = structure.pvAnalysis.HasSupportBox(supportBox);
if (has)
{
//
supportBox.to = bar.time;
AddIfNotExists(
supportBox,
supports //
);
// has = poiDrawer.DrawBox(
// supportBox,
// iSupportObj,
// true, // Ignore At ...
// supportBox.type // Name ...
// );
// if (has)
// {
// //
// XPOIStyle iStyle;
// poiDrawer.GetBoxStyle(
// iStyle,
// supportBox.dir //
// );
// poiDrawer.ApplyBoxStyle(
// iSupportObj,
// iStyle //
// );
// iStyle.Clean();
// }
}
//
// Resistance ...
XBoxZone resistanceBox;
has = structure.pvAnalysis.HasResistanceBox(resistanceBox);
if (has)
{
//
resistanceBox.to = bar.time;
AddIfNotExists(
resistanceBox,
supports //
);
// has = poiDrawer.DrawBox(
// resistanceBox,
// iResistanceObj,
// true, // Ignore At ...
// resistanceBox.type // Name ...
// );
// if (has)
// {
// //
// XPOIStyle iStyle;
// poiDrawer.GetBoxStyle(
// iStyle,
// resistanceBox.dir //
// );
// poiDrawer.ApplyBoxStyle(
// iResistanceObj,
// iStyle //
// );
// iStyle.Clean();
// }
}
//
// Pivots ...
XPivot pivots[];
count = poiDetector.ExtractPVPivots(
pivots,
barIndex,
50 //
);
has = IsValidSize(count);
//
// Sort ...
Sort(
pivots,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
// Remove Newest ...
ArrayRemove(
pivots,
0,
1 //
);
//
// Check Trend ...
if (has)
{
//
XPivot highs[];
int highsCount = ExtractPivots(
highs,
pivots,
X_PIVOT_TYPE_PEAK //
);
Sort(
highs,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
XPivot lows[];
int lowsCount = ExtractPivots(
lows,
pivots,
X_PIVOT_TYPE_VALE //
);
Sort(
lows,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
// Check Highs and Lows ...
has = IsValidSize(lowsCount) &&
IsValidSize(highsCount) &&
lowsCount >= 2 &&
highsCount >= 2;
if (has)
{
//
// Try to Get Market Strucutre ...
//
bool hasLowerHigh = highs[0].value < highs[1].value;
bool hasLowerLow = lows[0].value < lows[1].value;
//
bool hasHigherHigh = highs[0].value > highs[1].value;
bool hasHigherLow = lows[0].value > lows[1].value;
//
pvTrend =
(hasHigherHigh &&
hasHigherLow)
? X_DIRECTION_BULLISH
: (hasLowerHigh &&
hasLowerLow)
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
has = HasDirection(pvTrend);
if (has)
{
//
// Select Swings for Trend Line ...
XOHCL tmpBar;
int llIDX = -1;
int hhIDX = -1;
datetime toTime = NULL;
datetime fromTime = NULL;
double toPrice = EMPTY_VALUE;
color trendColor = CLR_NONE;
double fromPrice = EMPTY_VALUE;
if (IsSpecifiedBullish(pvTrend))
{
//
llIDX = GetLowest(lows);
hhIDX = GetHighest(lows);
//
trendColor = clrAqua;
//
toTime = lows[hhIDX].time;
toPrice = lows[hhIDX].value;
//
fromTime = lows[llIDX].time;
fromPrice = lows[llIDX].value;
}
else
{
//
llIDX = GetLowest(highs);
hhIDX = GetHighest(highs);
//
trendColor = clrMagenta;
//
toTime = highs[llIDX].time;
toPrice = highs[llIDX].value;
//
fromTime = highs[hhIDX].time;
fromPrice = highs[hhIDX].value;
}
//
// Check Requirements for Trend ...
has =
NotEmptyZero(toPrice) &&
NotEmptyZero(fromPrice) &&
IsSpecifiedValid(toTime) &&
IsSpecifiedValid(fromTime);
if (has)
{
//
has = poiDrawer.DrawTrendLine(
fromPrice,
fromTime,
toPrice,
toTime,
pvTrendLine,
pvTrendName,
true // Ray Right ...
);
if (has)
{
pvTrendLine.Color(trendColor);
}
}
//
// Cleanup Resources ...
tmpBar.Clean();
}
//
if (!has)
{
SpecifiedClean(pivots);
}
}
//
// Cleanup Resources ...
SpecifiedClean(lows);
SpecifiedClean(highs);
}
//
// Draw Pivots ...
has = HasChild(pivots);
if (has)
{
//
Copy(
pivots,
pvPivots //
);
}
//
// Cleanup Resources ...
SpecifiedClean(pivots);
}
//
// ZigZag Trend Line ...
bool hasZGAnalysis = structure.zigzagAnalysis.IsValid();
if (hasZGAnalysis)
{
//
// Support ...
XBoxZone supportBox;
has = structure.zigzagAnalysis.HasSupportBox(supportBox);
if (has)
{
//
supportBox.to = bar.time;
AddIfNotExists(
supportBox,
supports //
);
}
//
// Resistance ...
XBoxZone resistanceBox;
has = structure.zigzagAnalysis.HasResistanceBox(resistanceBox);
if (has)
{
//
resistanceBox.to = bar.time;
AddIfNotExists(
resistanceBox,
supports //
);
}
//
// Pivots ...
XPivot pivots[];
count = poiDetector.ExtractZigZagPivots(
pivots,
barIndex,
10 //
);
has = IsValidSize(count);
//
// Sort ...
Sort(
pivots,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
// Remove Newest ...
ArrayRemove(
pivots,
0,
1 //
);
//
// Check Trend ...
if (has)
{
//
XPivot highs[];
int highsCount = ExtractPivots(
highs,
pivots,
X_PIVOT_TYPE_PEAK //
);
Sort(
highs,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
XPivot lows[];
int lowsCount = ExtractPivots(
lows,
pivots,
X_PIVOT_TYPE_VALE //
);
Sort(
lows,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
// Check Highs and Lows ...
has = IsValidSize(lowsCount) &&
IsValidSize(highsCount) &&
lowsCount >= 2 &&
highsCount >= 2;
if (has)
{
//
// Try to Get Market Strucutre ...
//
bool hasLowerHigh = highs[0].value < highs[1].value;
bool hasLowerLow = lows[0].value < lows[1].value;
//
bool hasHigherHigh = highs[0].value > highs[1].value;
bool hasHigherLow = lows[0].value > lows[1].value;
//
zgTrend =
(hasHigherHigh &&
hasHigherLow)
? X_DIRECTION_BULLISH
: (hasLowerHigh &&
hasLowerLow)
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
has = HasDirection(zgTrend);
if (has)
{
//
// Select Swings for Trend Line ...
XOHCL tmpBar;
int llIDX = -1;
int hhIDX = -1;
datetime toTime = NULL;
datetime fromTime = NULL;
double toPrice = EMPTY_VALUE;
color trendColor = CLR_NONE;
double fromPrice = EMPTY_VALUE;
if (IsSpecifiedBullish(zgTrend))
{
//
llIDX = GetLowest(lows);
hhIDX = GetHighest(lows);
//
trendColor = clrAqua;
//
toTime = lows[hhIDX].time;
toPrice = lows[hhIDX].value;
//
fromTime = lows[llIDX].time;
fromPrice = lows[llIDX].value;
}
else
{
//
llIDX = GetLowest(highs);
hhIDX = GetHighest(highs);
//
trendColor = clrMagenta;
//
toTime = highs[llIDX].time;
toPrice = highs[llIDX].value;
//
fromTime = highs[hhIDX].time;
fromPrice = highs[hhIDX].value;
}
//
// Check Requirements for Trend ...
has =
NotEmptyZero(toPrice) &&
NotEmptyZero(fromPrice) &&
IsSpecifiedValid(toTime) &&
IsSpecifiedValid(fromTime);
if (has)
{
//
has = poiDrawer.DrawTrendLine(
fromPrice,
fromTime,
toPrice,
toTime,
zgTrendLine,
zgTrendName,
true // Ray Right ...
);
if (has)
{
zgTrendLine.Color(trendColor);
}
}
//
// Cleanup Resources ...
tmpBar.Clean();
}
//
if (!has)
{
SpecifiedClean(pivots);
}
}
//
// Cleanup Resources ...
SpecifiedClean(lows);
SpecifiedClean(highs);
}
//
// Draw Pivots ...
has = HasChild(pivots);
if (has)
{
//
Copy(
pivots,
zgPivots //
);
}
//
// Cleanup Resources ...
SpecifiedClean(pivots);
}
//
// Support ...
bool hasSupport = structure.support.IsValid();
if (hasSupport)
{
//
AddIfNotExists(
structure.support,
supports //
);
// //
// XCBoxObject *iObj;
// has = fima2Signaller.poiDrawer.DrawBox(
// structure.support,
// iObj);
// if (has)
// {
// }
}
//
// Resistance ...
bool hasResistance = structure.resistance.IsValid();
if (hasResistance)
{
//
AddIfNotExists(
structure.resistance,
resistances //
);
// //
// XCBoxObject *iObj;
// has = fima2Signaller.poiDrawer.DrawBox(
// structure.resistance,
// iObj);
// if (has)
// {
// }
}
//
// Validate Positions Support and Resistance Zone ...
int insideZoneIDX = -1;
has = has &&
(isBullish
? HasInside(
insideZoneIDX,
bar,
supports //
)
: HasInside(
insideZoneIDX,
bar,
resistances //
));
//
// Validate Selected Inside Zone ...
// whith Bars Edge ...
has = IsValidIndex(insideZoneIDX);
if (has)
{
//
if (isBullish)
{
iZone = supports[insideZoneIDX];
}
else
{
iZone = resistances[insideZoneIDX];
}
//
has = isBullish
? bar.high > supports[insideZoneIDX].upper
: bar.low < resistances[insideZoneIDX].lower;
if (!has)
{
//
isBullish = false;
isBearish = false;
iDir = X_DIRECTION_NONE;
}
}
else
{
//
isBullish = false;
isBearish = false;
iDir = X_DIRECTION_NONE;
}
//
// Checking Liquidities ...
//
// Do all Draws Here ...
bool canDraw = false;
if (canDraw)
{
//
int iWidth = 2;
XPOIStyle iStyle;
XCBoxObject *iBoxObj = NULL;
color iClr = isBullish
? clrYellow
: clrDarkOrange;
//
// Supports ...
has = HasChild(supports);
if (has)
{
//
count = ArraySize(supports);
for (int i = 0; i < count; i++)
{
//
has = poiDrawer.DrawBox(
supports[i],
iBoxObj,
true, // Ignore At ...
supports[i].type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
supports[i].dir //
);
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
//
iStyle.Clean();
ZeroMemory(iBoxObj);
}
}
//
// Resistances ...
has = HasChild(resistances);
if (has)
{
//
count = ArraySize(resistances);
for (int i = 0; i < count; i++)
{
//
has = poiDrawer.DrawBox(
resistances[i],
iBoxObj,
true, // Ignore At ...
resistances[i].type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
resistances[i].dir //
);
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
//
iStyle.Clean();
ZeroMemory(iBoxObj);
}
}
//
// Selected Zone ...
has = iZone.IsValid();
if (has)
{
//
has = poiDrawer.DrawBox(
iZone,
iBoxObj,
true, // Ignore At ...
iZone.type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
iZone.dir //
);
//
iStyle.clr = iClr;
iStyle.width = iWidth;
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
}
//
// TrendLines ...
//
// Pivots ...
//
has = HasChild(pvPivots);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
count = poiDrawer.DrawPivots(
pvPivots,
drawnPivots //
);
}
//
has = HasChild(zgPivots);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
count = poiDrawer.DrawPivots(
zgPivots,
drawnPivots //
);
}
//
// Patterns Bar ...
has = HasDirection(iDir);
if (has)
{
//
int iCode = 159;
ENUM_ARROW_ANCHOR iAnchor = isBullish
? ANCHOR_TOP
: ANCHOR_BOTTOM;
//
XCBarArrowObject *iPatternObj;
has = poiDrawer.DrawBarArrow(
bar,
iPatternObj,
iPriceType,
iCode,
iClr,
iWidth,
iAnchor,
iName,
true, // Ignore Bar Tag ...
10 // Threshold ...
);
}
}
//
// Check Signal Founded ...
has = HasDirection(iDir);
if (has)
{
//
// TODO: Provided SL ...
double _point = GetPoints(bar.symbol);
double slAddition = 5 * _point;
double slPrice =
isBullish
? iZone.lower - slAddition
: iZone.upper + slAddition;
//
// Prepare Founded Signal ...
XTarget targets[];
has = PrepareSignal(
signal,
iDir,
targets,
0, // Use Default R2R ...
slPrice, // Provided Price for SL ...
0 // Specified Risk in Point ....
);
if (has)
{
//
// Notify On Signal Event ...
NotifySignalEventListeners(signal);
}
}
//
// Cleanup Resources ...
bar.Clean();
iZone.Clean();
signal.Clean();
structure.Clean();
fimaConditions.Clean();
SpecifiedClean(pvPivots);
SpecifiedClean(zgPivots);
SpecifiedClean(supports);
SpecifiedClean(resistances);
}
/**
* Processing New Bar ...
*
* @param barIndex: int, Specified Bar Index ...
*/
void ProcessNewBarNKP1(int barIndex = 0)
{
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
//
// Update Helper ...
fimaHelper.Update(barIndex);
//
XOHCL bar;
XSignal signal;
XBoxZone iZone;
int count = 0;
bool has = false;
int cIdx = 0;
int pIdx = cIdx + 1;
string iName = NULL;
XBoxZone supports[];
XBoxZone resistances[];
bool isBullish = false;
bool isBearish = false;
double iPrice = EMPTY_VALUE;
double iPriceEdge = EMPTY_VALUE;
XFIMAMarketStructure structure;
XFIMAConditions fimaConditions;
ENUM_X_PRICE iPriceType = X_PRICE_NONE;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
ENUM_X_PRICE iPriceEdgeType = X_PRICE_NONE;
//
XPivot pvPivots[];
string pvTrendName = "XXIFMA2PVTrend";
CChartObjectTrend *pvTrendLine = NULL;
ENUM_X_DIRECTION pvTrend = X_DIRECTION_NONE;
//
XPivot zgPivots[];
string zgTrendName = "XFIMA2ZGTrend";
CChartObjectTrend *zgTrendLine = NULL;
ENUM_X_DIRECTION zgTrend = X_DIRECTION_NONE;
//
// Initialize Bar as CBar ...
has = bar.Init(
symbol,
period,
barIndex //
);
if (!has)
{
//
bar.Clean();
return;
}
//
// Retrieve Conditions ...
has = fimaHelper.GetConditions(
fimaConditions,
barIndex,
10 // Loopback ...
);
if (!has)
{
//
bar.Clean();
fimaConditions.Clean();
//
return;
}
//
// Analyse Market ...
poiDetector.AnalyseMarket(
bar,
structure,
analyserConfig //
);
//
// Collect Support and Resistance Zones and Validate by them ...
//
// PV Trend Line ...
bool hasPVAnalysis = structure.pvAnalysis.IsValid();
if (hasPVAnalysis)
{
//
// Support ...
XBoxZone supportBox;
has = structure.pvAnalysis.HasSupportBox(supportBox);
if (has)
{
//
supportBox.to = bar.time;
AddIfNotExists(
supportBox,
supports //
);
}
//
// Resistance ...
XBoxZone resistanceBox;
has = structure.pvAnalysis.HasResistanceBox(resistanceBox);
if (has)
{
//
resistanceBox.to = bar.time;
AddIfNotExists(
resistanceBox,
supports //
);
}
//
// Pivots ...
XPivot pivots[];
count = poiDetector.ExtractPVPivots(
pivots,
barIndex,
50 //
);
has = IsValidSize(count);
//
// Sort ...
Sort(
pivots,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
// Remove Newest ...
ArrayRemove(
pivots,
0,
1 //
);
//
// Check Trend ...
if (has)
{
//
XPivot highs[];
int highsCount = ExtractPivots(
highs,
pivots,
X_PIVOT_TYPE_PEAK //
);
Sort(
highs,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
XPivot lows[];
int lowsCount = ExtractPivots(
lows,
pivots,
X_PIVOT_TYPE_VALE //
);
Sort(
lows,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
// Check Highs and Lows ...
has = IsValidSize(lowsCount) &&
IsValidSize(highsCount) &&
lowsCount >= 2 &&
highsCount >= 2;
if (has)
{
//
// Try to Get Market Strucutre ...
//
bool hasLowerHigh = highs[0].value < highs[1].value;
bool hasLowerLow = lows[0].value < lows[1].value;
//
bool hasHigherHigh = highs[0].value > highs[1].value;
bool hasHigherLow = lows[0].value > lows[1].value;
//
pvTrend =
(hasHigherHigh &&
hasHigherLow)
? X_DIRECTION_BULLISH
: (hasLowerHigh &&
hasLowerLow)
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
has = HasDirection(pvTrend);
if (has)
{
//
// Select Swings for Trend Line ...
XOHCL tmpBar;
int llIDX = -1;
int hhIDX = -1;
datetime toTime = NULL;
datetime fromTime = NULL;
double toPrice = EMPTY_VALUE;
color trendColor = CLR_NONE;
double fromPrice = EMPTY_VALUE;
if (IsSpecifiedBullish(pvTrend))
{
//
llIDX = GetLowest(lows);
hhIDX = GetHighest(lows);
//
trendColor = clrAqua;
//
toTime = lows[hhIDX].time;
toPrice = lows[hhIDX].value;
//
fromTime = lows[llIDX].time;
fromPrice = lows[llIDX].value;
}
else
{
//
llIDX = GetLowest(highs);
hhIDX = GetHighest(highs);
//
trendColor = clrMagenta;
//
toTime = highs[llIDX].time;
toPrice = highs[llIDX].value;
//
fromTime = highs[hhIDX].time;
fromPrice = highs[hhIDX].value;
}
//
// Check Requirements for Trend ...
has =
NotEmptyZero(toPrice) &&
NotEmptyZero(fromPrice) &&
IsSpecifiedValid(toTime) &&
IsSpecifiedValid(fromTime);
if (has)
{
//
has = poiDrawer.DrawTrendLine(
fromPrice,
fromTime,
toPrice,
toTime,
pvTrendLine,
pvTrendName,
true // Ray Right ...
);
if (has)
{
pvTrendLine.Color(trendColor);
}
}
//
// Cleanup Resources ...
tmpBar.Clean();
}
//
if (!has)
{
SpecifiedClean(pivots);
}
}
//
// Cleanup Resources ...
SpecifiedClean(lows);
SpecifiedClean(highs);
}
//
// Draw Pivots ...
has = HasChild(pivots);
if (has)
{
//
Copy(
pivots,
pvPivots //
);
}
//
// Cleanup Resources ...
SpecifiedClean(pivots);
}
//
// ZigZag Trend Line ...
bool hasZGAnalysis = structure.zigzagAnalysis.IsValid();
if (hasZGAnalysis)
{
//
// Support ...
XBoxZone supportBox;
has = structure.zigzagAnalysis.HasSupportBox(supportBox);
if (has)
{
//
supportBox.to = bar.time;
AddIfNotExists(
supportBox,
supports //
);
}
//
// Resistance ...
XBoxZone resistanceBox;
has = structure.zigzagAnalysis.HasResistanceBox(resistanceBox);
if (has)
{
//
resistanceBox.to = bar.time;
AddIfNotExists(
resistanceBox,
supports //
);
}
//
// Pivots ...
XPivot pivots[];
count = poiDetector.ExtractZigZagPivots(
pivots,
barIndex,
10 //
);
has = IsValidSize(count);
//
// Sort ...
Sort(
pivots,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
// Remove Newest ...
ArrayRemove(
pivots,
0,
1 //
);
//
// Check Trend ...
if (has)
{
//
XPivot highs[];
int highsCount = ExtractPivots(
highs,
pivots,
X_PIVOT_TYPE_PEAK //
);
Sort(
highs,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
XPivot lows[];
int lowsCount = ExtractPivots(
lows,
pivots,
X_PIVOT_TYPE_VALE //
);
Sort(
lows,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
// Check Highs and Lows ...
has = IsValidSize(lowsCount) &&
IsValidSize(highsCount) &&
lowsCount >= 2 &&
highsCount >= 2;
if (has)
{
//
// Try to Get Market Strucutre ...
//
bool hasLowerHigh = highs[0].value < highs[1].value;
bool hasLowerLow = lows[0].value < lows[1].value;
//
bool hasHigherHigh = highs[0].value > highs[1].value;
bool hasHigherLow = lows[0].value > lows[1].value;
//
zgTrend =
(hasHigherHigh &&
hasHigherLow)
? X_DIRECTION_BULLISH
: (hasLowerHigh &&
hasLowerLow)
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
has = HasDirection(zgTrend);
if (has)
{
//
// Select Swings for Trend Line ...
XOHCL tmpBar;
int llIDX = -1;
int hhIDX = -1;
datetime toTime = NULL;
datetime fromTime = NULL;
double toPrice = EMPTY_VALUE;
color trendColor = CLR_NONE;
double fromPrice = EMPTY_VALUE;
if (IsSpecifiedBullish(zgTrend))
{
//
llIDX = GetLowest(lows);
hhIDX = GetHighest(lows);
//
trendColor = clrAqua;
//
toTime = lows[hhIDX].time;
toPrice = lows[hhIDX].value;
//
fromTime = lows[llIDX].time;
fromPrice = lows[llIDX].value;
}
else
{
//
llIDX = GetLowest(highs);
hhIDX = GetHighest(highs);
//
trendColor = clrMagenta;
//
toTime = highs[llIDX].time;
toPrice = highs[llIDX].value;
//
fromTime = highs[hhIDX].time;
fromPrice = highs[hhIDX].value;
}
//
// Check Requirements for Trend ...
has =
NotEmptyZero(toPrice) &&
NotEmptyZero(fromPrice) &&
IsSpecifiedValid(toTime) &&
IsSpecifiedValid(fromTime);
if (has)
{
//
has = poiDrawer.DrawTrendLine(
fromPrice,
fromTime,
toPrice,
toTime,
zgTrendLine,
zgTrendName,
true // Ray Right ...
);
if (has)
{
zgTrendLine.Color(trendColor);
}
}
//
// Cleanup Resources ...
tmpBar.Clean();
}
//
if (!has)
{
SpecifiedClean(pivots);
}
}
//
// Cleanup Resources ...
SpecifiedClean(lows);
SpecifiedClean(highs);
}
//
// Draw Pivots ...
has = HasChild(pivots);
if (has)
{
//
Copy(
pivots,
zgPivots //
);
}
//
// Cleanup Resources ...
SpecifiedClean(pivots);
}
//
// Support ...
bool hasSupport = structure.support.IsValid();
if (hasSupport)
{
//
AddIfNotExists(
structure.support,
supports //
);
}
//
// Resistance ...
bool hasResistance = structure.resistance.IsValid();
if (hasResistance)
{
//
AddIfNotExists(
structure.resistance,
resistances //
);
}
//
// 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 ...
has = hasPinnedBar ||
hasEngulfedBar ||
hasFlagPattern ||
hasStarPattern ||
hasSignalKeyBar ||
hasRisingPattern ||
hasPiercingPattern;
if (has)
{
//
if (hasPinnedBar)
{
//
iDir = structure.pinnedDir;
iName = "XPinned_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasEngulfedBar)
{
//
iDir = structure.engulfedDir;
iName = "XEngulfed_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasFlagPattern)
{
//
iDir = structure.flagPatternDir;
iName = "XFlag_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasStarPattern)
{
//
iDir = structure.starPatternDir;
iName = "XStar_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasSignalKeyBar)
{
//
iDir = structure.risingPatternDir;
iName = "XRising_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasRisingPattern)
{
//
iDir = structure.piercingPatternDir;
iName = "XPiercing_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasPiercingPattern)
{
//
iDir = structure.signalKeyBarPatternDir;
iName = "XSignalKey_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
//
isBullish = IsSpecifiedBullish(iDir);
isBearish = IsSpecifiedBearish(iDir);
//
// Retrieve Price Type for Validate ...
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 Calculations ...
has = HasDirection(iDir) &&
(isBullish ||
isBearish) &&
NotEmptyZero(iPrice) &&
NotEmptyZero(iPriceEdge) &&
iPrice != iPriceEdge;
if (!has)
{
//
isBullish = false;
isBearish = false;
iDir = X_DIRECTION_NONE;
}
}
//
// Check Petterns Happens ...
// Chekc Bullish or Bearish Starter Conditions Exists ...
has = HasDirection(iDir);
if (has)
{
//
// Do Conditions Validating ...
//
// Retrieve MA Band for Validation ...
double iMABandUpper = fimaConditions.maBandUpperBuffer[cIdx];
double iMABandLower = fimaConditions.maBandLowerBuffer[cIdx];
//
// Validate ...
//
// Validate by Edge Price ...
has = isBullish
? iPriceEdge < iMABandLower
: iPriceEdge > iMABandUpper;
//
// Validate by Body Price ...
// has = isBullish
// ? iPrice < iMABandLower
// : iPrice > iMABandUpper;
if (!has)
{
//
isBullish = false;
isBearish = false;
iDir = X_DIRECTION_NONE;
}
}
//
// Validate ...
// Detect Support and Resistances ...
// and Validate Price based on it's ...
has = HasDirection(iDir);
if (has)
{
//
// Validate Positions Support and Resistance Zone ...
int insideZoneIDX = -1;
has = has &&
(isBullish
? HasInside(
insideZoneIDX,
bar,
supports //
)
: HasInside(
insideZoneIDX,
bar,
resistances //
));
//
// Validate Selected Inside Zone ...
// whith Bars Edge ...
has = IsValidIndex(insideZoneIDX);
if (has)
{
//
if (isBullish)
{
iZone = supports[insideZoneIDX];
}
else
{
iZone = resistances[insideZoneIDX];
}
//
has = isBullish
? bar.high > supports[insideZoneIDX].upper
: bar.low < resistances[insideZoneIDX].lower;
if (!has)
{
//
isBullish = false;
isBearish = false;
iDir = X_DIRECTION_NONE;
}
}
else
{
//
isBullish = false;
isBearish = false;
iDir = X_DIRECTION_NONE;
}
}
//
// Checking Liquidities ...
//
// Do all Draws Here ...
bool canDraw = true;
if (canDraw)
{
//
int iWidth = 2;
XPOIStyle iStyle;
XCBoxObject *iBoxObj = NULL;
color iClr = isBullish
? clrYellow
: clrDarkOrange;
//
// Supports ...
has = HasChild(supports);
if (has)
{
//
count = ArraySize(supports);
for (int i = 0; i < count; i++)
{
//
has = poiDrawer.DrawBox(
supports[i],
iBoxObj,
true, // Ignore At ...
supports[i].type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
supports[i].dir //
);
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
//
iStyle.Clean();
ZeroMemory(iBoxObj);
}
}
//
// Resistances ...
has = HasChild(resistances);
if (has)
{
//
count = ArraySize(resistances);
for (int i = 0; i < count; i++)
{
//
has = poiDrawer.DrawBox(
resistances[i],
iBoxObj,
true, // Ignore At ...
resistances[i].type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
resistances[i].dir //
);
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
//
iStyle.Clean();
ZeroMemory(iBoxObj);
}
}
//
// Selected Zone ...
has = iZone.IsValid();
if (has)
{
//
has = poiDrawer.DrawBox(
iZone,
iBoxObj,
true, // Ignore At ...
iZone.type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
iZone.dir //
);
//
iStyle.clr = iClr;
iStyle.width = iWidth;
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
}
//
// TrendLines ...
//
// Pivots ...
//
has = HasChild(pvPivots);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
count = poiDrawer.DrawPivots(
pvPivots,
drawnPivots //
);
}
//
has = HasChild(zgPivots);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
count = poiDrawer.DrawPivots(
zgPivots,
drawnPivots //
);
}
//
// Patterns Bar ...
has = HasDirection(iDir);
if (has)
{
//
int iCode = 159;
ENUM_ARROW_ANCHOR iAnchor = isBullish
? ANCHOR_TOP
: ANCHOR_BOTTOM;
//
XCBarArrowObject *iPatternObj;
has = poiDrawer.DrawBarArrow(
bar,
iPatternObj,
iPriceType,
iCode,
iClr,
iWidth,
iAnchor,
iName,
true, // Ignore Bar Tag ...
10 // Threshold ...
);
}
}
//
// Check Signal Founded ...
has = HasDirection(iDir);
//
if (has)
{
Print("a Valid ", ToXString(iDir), " Pattern Exists ...");
}
//
if (has)
{
//
// TODO: Provided SL ...
double _point = GetPoints(bar.symbol);
double slAddition = 5 * _point;
double slPrice =
isBullish
? iZone.lower - slAddition
: iZone.upper + slAddition;
//
// Prepare Founded Signal ...
XTarget targets[];
has = PrepareSignal(
signal,
iDir,
targets,
0, // Use Default R2R ...
slPrice, // Provided Price for SL ...
0 // Specified Risk in Point ....
);
if (has)
{
//
// Notify On Signal Event ...
NotifySignalEventListeners(signal);
}
}
//
// Cleanup Resources ...
bar.Clean();
iZone.Clean();
signal.Clean();
structure.Clean();
fimaConditions.Clean();
SpecifiedClean(pvPivots);
SpecifiedClean(zgPivots);
SpecifiedClean(supports);
SpecifiedClean(resistances);
}
/**
* Processing New Bar ...
*
* @param barIndex: int, Specified Bar Index ...
*/
virtual void ProcessNewBar(int barIndex = 0)
{
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
//
// Update Helper ...
fimaHelper.Update(barIndex);
//
XOHCL bar;
XSignal signal;
XBoxZone iZone;
int count = 0;
bool has = false;
int cIdx = 0;
int pIdx = cIdx + 1;
string iName = NULL;
XBoxZone supports[];
XBoxZone resistances[];
bool isBullish = false;
bool isBearish = false;
double iPrice = EMPTY_VALUE;
double iPriceEdge = EMPTY_VALUE;
XFIMAMarketStructure structure;
XFIMAConditions fimaConditions;
ENUM_X_PRICE iPriceType = X_PRICE_NONE;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
ENUM_X_PRICE iPriceEdgeType = X_PRICE_NONE;
//
XPivot pvPivots[];
string pvTrendName = "XXIFMA2PVTrend";
CChartObjectTrend *pvTrendLine = NULL;
ENUM_X_DIRECTION pvTrend = X_DIRECTION_NONE;
//
XPivot zgPivots[];
string zgTrendName = "XFIMA2ZGTrend";
CChartObjectTrend *zgTrendLine = NULL;
ENUM_X_DIRECTION zgTrend = X_DIRECTION_NONE;
//
// Initialize Bar as CBar ...
has = bar.Init(
symbol,
period,
barIndex //
);
if (!has)
{
//
bar.Clean();
return;
}
//
// Retrieve Conditions ...
has = fimaHelper.GetConditions(
fimaConditions,
barIndex,
10 // Loopback ...
);
if (!has)
{
//
bar.Clean();
fimaConditions.Clean();
//
return;
}
//
// Analyse Market ...
poiDetector.AnalyseMarket(
bar,
structure,
analyserConfig //
);
//
// Collect Support and Resistance Zones and Validate by them ...
//
// PV Trend Line ...
bool hasPVAnalysis = structure.pvAnalysis.IsValid();
if (hasPVAnalysis)
{
//
// Support ...
XBoxZone supportBox;
has = structure.pvAnalysis.HasSupportBox(supportBox);
if (has)
{
//
supportBox.to = bar.time;
AddIfNotExists(
supportBox,
supports //
);
}
//
// Resistance ...
XBoxZone resistanceBox;
has = structure.pvAnalysis.HasResistanceBox(resistanceBox);
if (has)
{
//
resistanceBox.to = bar.time;
AddIfNotExists(
resistanceBox,
supports //
);
}
//
// Pivots ...
XPivot pivots[];
count = poiDetector.ExtractPVPivots(
pivots,
barIndex,
50 //
);
has = IsValidSize(count);
//
// Sort ...
Sort(
pivots,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
// Remove Newest ...
ArrayRemove(
pivots,
0,
1 //
);
//
// Check Trend ...
if (has)
{
//
XPivot highs[];
int highsCount = ExtractPivots(
highs,
pivots,
X_PIVOT_TYPE_PEAK //
);
Sort(
highs,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
XPivot lows[];
int lowsCount = ExtractPivots(
lows,
pivots,
X_PIVOT_TYPE_VALE //
);
Sort(
lows,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
// Check Highs and Lows ...
has = IsValidSize(lowsCount) &&
IsValidSize(highsCount) &&
lowsCount >= 2 &&
highsCount >= 2;
if (has)
{
//
// Try to Get Market Strucutre ...
//
bool hasLowerHigh = highs[0].value < highs[1].value;
bool hasLowerLow = lows[0].value < lows[1].value;
//
bool hasHigherHigh = highs[0].value > highs[1].value;
bool hasHigherLow = lows[0].value > lows[1].value;
//
pvTrend =
(hasHigherHigh &&
hasHigherLow)
? X_DIRECTION_BULLISH
: (hasLowerHigh &&
hasLowerLow)
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
has = HasDirection(pvTrend);
if (has)
{
//
// Select Swings for Trend Line ...
XOHCL tmpBar;
int llIDX = -1;
int hhIDX = -1;
datetime toTime = NULL;
datetime fromTime = NULL;
double toPrice = EMPTY_VALUE;
color trendColor = CLR_NONE;
double fromPrice = EMPTY_VALUE;
if (IsSpecifiedBullish(pvTrend))
{
//
llIDX = GetLowest(lows);
hhIDX = GetHighest(lows);
//
trendColor = clrAqua;
//
toTime = lows[hhIDX].time;
toPrice = lows[hhIDX].value;
//
fromTime = lows[llIDX].time;
fromPrice = lows[llIDX].value;
}
else
{
//
llIDX = GetLowest(highs);
hhIDX = GetHighest(highs);
//
trendColor = clrMagenta;
//
toTime = highs[llIDX].time;
toPrice = highs[llIDX].value;
//
fromTime = highs[hhIDX].time;
fromPrice = highs[hhIDX].value;
}
//
// Check Requirements for Trend ...
has =
NotEmptyZero(toPrice) &&
NotEmptyZero(fromPrice) &&
IsSpecifiedValid(toTime) &&
IsSpecifiedValid(fromTime);
if (has)
{
//
has = poiDrawer.DrawTrendLine(
fromPrice,
fromTime,
toPrice,
toTime,
pvTrendLine,
pvTrendName,
true // Ray Right ...
);
if (has)
{
pvTrendLine.Color(trendColor);
}
}
//
// Cleanup Resources ...
tmpBar.Clean();
}
//
if (!has)
{
SpecifiedClean(pivots);
}
}
//
// Cleanup Resources ...
SpecifiedClean(lows);
SpecifiedClean(highs);
}
//
// Draw Pivots ...
has = HasChild(pivots);
if (has)
{
//
Copy(
pivots,
pvPivots //
);
}
//
// Cleanup Resources ...
SpecifiedClean(pivots);
}
//
// ZigZag Trend Line ...
bool hasZGAnalysis = structure.zigzagAnalysis.IsValid();
if (hasZGAnalysis)
{
//
// Support ...
XBoxZone supportBox;
has = structure.zigzagAnalysis.HasSupportBox(supportBox);
if (has)
{
//
supportBox.to = bar.time;
AddIfNotExists(
supportBox,
supports //
);
}
//
// Resistance ...
XBoxZone resistanceBox;
has = structure.zigzagAnalysis.HasResistanceBox(resistanceBox);
if (has)
{
//
resistanceBox.to = bar.time;
AddIfNotExists(
resistanceBox,
supports //
);
}
//
// Pivots ...
XPivot pivots[];
count = poiDetector.ExtractZigZagPivots(
pivots,
barIndex,
10 //
);
has = IsValidSize(count);
//
// Sort ...
Sort(
pivots,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
// Remove Newest ...
ArrayRemove(
pivots,
0,
1 //
);
//
// Check Trend ...
if (has)
{
//
XPivot highs[];
int highsCount = ExtractPivots(
highs,
pivots,
X_PIVOT_TYPE_PEAK //
);
Sort(
highs,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
XPivot lows[];
int lowsCount = ExtractPivots(
lows,
pivots,
X_PIVOT_TYPE_VALE //
);
Sort(
lows,
X_SORT_BY_DATE,
X_DIRECTION_BEARISH //
);
//
// Check Highs and Lows ...
has = IsValidSize(lowsCount) &&
IsValidSize(highsCount) &&
lowsCount >= 2 &&
highsCount >= 2;
if (has)
{
//
// Try to Get Market Strucutre ...
//
bool hasLowerHigh = highs[0].value < highs[1].value;
bool hasLowerLow = lows[0].value < lows[1].value;
//
bool hasHigherHigh = highs[0].value > highs[1].value;
bool hasHigherLow = lows[0].value > lows[1].value;
//
zgTrend =
(hasHigherHigh &&
hasHigherLow)
? X_DIRECTION_BULLISH
: (hasLowerHigh &&
hasLowerLow)
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
has = HasDirection(zgTrend);
if (has)
{
//
// Select Swings for Trend Line ...
XOHCL tmpBar;
int llIDX = -1;
int hhIDX = -1;
datetime toTime = NULL;
datetime fromTime = NULL;
double toPrice = EMPTY_VALUE;
color trendColor = CLR_NONE;
double fromPrice = EMPTY_VALUE;
if (IsSpecifiedBullish(zgTrend))
{
//
llIDX = GetLowest(lows);
hhIDX = GetHighest(lows);
//
trendColor = clrAqua;
//
toTime = lows[hhIDX].time;
toPrice = lows[hhIDX].value;
//
fromTime = lows[llIDX].time;
fromPrice = lows[llIDX].value;
}
else
{
//
llIDX = GetLowest(highs);
hhIDX = GetHighest(highs);
//
trendColor = clrMagenta;
//
toTime = highs[llIDX].time;
toPrice = highs[llIDX].value;
//
fromTime = highs[hhIDX].time;
fromPrice = highs[hhIDX].value;
}
//
// Check Requirements for Trend ...
has =
NotEmptyZero(toPrice) &&
NotEmptyZero(fromPrice) &&
IsSpecifiedValid(toTime) &&
IsSpecifiedValid(fromTime);
if (has)
{
//
has = poiDrawer.DrawTrendLine(
fromPrice,
fromTime,
toPrice,
toTime,
zgTrendLine,
zgTrendName,
true // Ray Right ...
);
if (has)
{
zgTrendLine.Color(trendColor);
}
}
//
// Cleanup Resources ...
tmpBar.Clean();
}
//
if (!has)
{
SpecifiedClean(pivots);
}
}
//
// Cleanup Resources ...
SpecifiedClean(lows);
SpecifiedClean(highs);
}
//
// Draw Pivots ...
has = HasChild(pivots);
if (has)
{
//
Copy(
pivots,
zgPivots //
);
}
//
// Cleanup Resources ...
SpecifiedClean(pivots);
}
//
// Support ...
bool hasSupport = structure.support.IsValid();
if (hasSupport)
{
//
AddIfNotExists(
structure.support,
supports //
);
}
//
// Resistance ...
bool hasResistance = structure.resistance.IsValid();
if (hasResistance)
{
//
AddIfNotExists(
structure.resistance,
resistances //
);
}
//
// 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 ...
has = hasPinnedBar ||
hasEngulfedBar ||
hasFlagPattern ||
hasStarPattern ||
hasSignalKeyBar ||
hasRisingPattern ||
hasPiercingPattern;
if (has)
{
//
if (hasPinnedBar)
{
//
iDir = structure.pinnedDir;
iName = "XPinned_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasEngulfedBar)
{
//
iDir = structure.engulfedDir;
iName = "XEngulfed_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasFlagPattern)
{
//
iDir = structure.flagPatternDir;
iName = "XFlag_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasStarPattern)
{
//
iDir = structure.starPatternDir;
iName = "XStar_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasSignalKeyBar)
{
//
iDir = structure.risingPatternDir;
iName = "XRising_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasRisingPattern)
{
//
iDir = structure.piercingPatternDir;
iName = "XPiercing_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasPiercingPattern)
{
//
iDir = structure.signalKeyBarPatternDir;
iName = "XSignalKey_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
//
isBullish = IsSpecifiedBullish(iDir);
isBearish = IsSpecifiedBearish(iDir);
//
// Retrieve Price Type for Validate ...
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 Calculations ...
has = HasDirection(iDir) &&
(isBullish ||
isBearish) &&
NotEmptyZero(iPrice) &&
NotEmptyZero(iPriceEdge) &&
iPrice != iPriceEdge;
if (!has)
{
//
isBullish = false;
isBearish = false;
iDir = X_DIRECTION_NONE;
}
}
//
// Strategy 1 ...
has = Strategy1HasSignal(
bar,
iZone,
iName,
supports,
resistances,
iDir,
fimaConditions,
structure //
);
//
// Do all Draws Here ...
bool canDraw = true;
if (canDraw && has)
{
//
int iWidth = 2;
XPOIStyle iStyle;
XCBoxObject *iBoxObj = NULL;
color iClr = isBullish
? clrYellow
: clrDarkOrange;
//
// Supports ...
has = HasChild(supports);
if (has)
{
//
count = ArraySize(supports);
for (int i = 0; i < count; i++)
{
//
has = poiDrawer.DrawBox(
supports[i],
iBoxObj,
true, // Ignore At ...
supports[i].type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
supports[i].dir //
);
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
//
iStyle.Clean();
ZeroMemory(iBoxObj);
}
}
//
// Resistances ...
has = HasChild(resistances);
if (has)
{
//
count = ArraySize(resistances);
for (int i = 0; i < count; i++)
{
//
has = poiDrawer.DrawBox(
resistances[i],
iBoxObj,
true, // Ignore At ...
resistances[i].type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
resistances[i].dir //
);
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
//
iStyle.Clean();
ZeroMemory(iBoxObj);
}
}
//
// Selected Zone ...
has = iZone.IsValid();
if (has)
{
//
has = poiDrawer.DrawBox(
iZone,
iBoxObj,
true, // Ignore At ...
iZone.type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
iZone.dir //
);
//
iStyle.clr = iClr;
iStyle.width = iWidth;
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
}
//
// TrendLines ...
//
// Pivots ...
//
has = HasChild(pvPivots);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
count = poiDrawer.DrawPivots(
pvPivots,
drawnPivots //
);
}
//
has = HasChild(zgPivots);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
count = poiDrawer.DrawPivots(
zgPivots,
drawnPivots //
);
}
//
// Patterns Bar ...
has = HasDirection(iDir);
if (has)
{
//
int iCode = 159;
ENUM_ARROW_ANCHOR iAnchor = isBullish
? ANCHOR_TOP
: ANCHOR_BOTTOM;
//
XCBarArrowObject *iPatternObj;
has = poiDrawer.DrawBarArrow(
bar,
iPatternObj,
iPriceType,
iCode,
iClr,
iWidth,
iAnchor,
iName,
true, // Ignore Bar Tag ...
10 // Threshold ...
);
}
}
//
if (has)
{
Print("a Valid ", ToXString(iDir), " Pattern Exists ...");
}
//
if (has)
{
//
// TODO: Provided SL ...
double _point = GetPoints(bar.symbol);
double slAddition = 5 * _point;
double slPrice =
isBullish
? iZone.lower - slAddition
: iZone.upper + slAddition;
//
// Prepare Founded Signal ...
XTarget targets[];
has = PrepareSignal(
signal,
iDir,
targets,
0, // Use Default R2R ...
slPrice, // Provided Price for SL ...
0 // Specified Risk in Point ....
);
if (has)
{
//
// Notify On Signal Event ...
NotifySignalEventListeners(signal);
}
}
//
// Cleanup Resources ...
bar.Clean();
iZone.Clean();
signal.Clean();
structure.Clean();
fimaConditions.Clean();
SpecifiedClean(pvPivots);
SpecifiedClean(zgPivots);
SpecifiedClean(supports);
SpecifiedClean(resistances);
}
/**
* Check Guards Based on MarketConditions ...
*
* @param guards: XGuard[]
* @param barIndex: int
*
* @return ( int )
*/
int virtual CheckForGuard(
XGuard &guards[],
int barIndex = 0 //
)
{
//
int result = 0;
//
SpecifiedClean(guards);
//
result = ArraySize(guards);
//
return result;
}
//
// Private ...
private:
//
// Props ...
//
// Implementing Strategies ...
/**
* 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) &&
fimaConditions.IsValid();
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.maBandUpperBuffer[cIdx];
double iMABandLower = fimaConditions.maBandLowerBuffer[cIdx];
//
// Validate by Edge Price ...
result = isBullish
? iPriceEdge < iMABandLower
: iPriceEdge > iMABandUpper;
if (!result)
{
return result;
}
//
return result;
}
/**
* Check Pattern Has Signal Based on Strategy 1 ...
*
* @param bar: XOHCL, reference to Pattern Bar ...
* @param iZone: XBoxZone, reference to holds affected zone ...
* @param patternName: string, detected pattern's name ...
* @param supports: XBoxZone, array reference to Provide Exists Supports ...
* @param resistances: XBoxZone, array reference to Provide Exists Resistances ...
* @param patternDir: ENUM_X_DIRECTION, detected pattern's direction ...
* @param fimaConditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
* @param fimaMarketStructure: XFIMAMarketStructure, refrence to Provides Market Structure ...
*
* @return ( bool )
*/
bool Strategy1HasSignal(
XOHCL &bar,
XBoxZone &iZone,
string patternName,
XBoxZone &supports[],
XBoxZone &resistances[],
ENUM_X_DIRECTION patternDir,
XFIMAMarketStructure &structure,
XFIMAConditions &fimaConditions,
XFIMAMarketStructure &fimaMarketStructure //
)
{
//
bool result = false;
//
// Prepare ...
iZone.Clean();
//
// Validate ...
result = bar.IsValid() &&
IsXValid(patternName) &&
HasDirection(patternDir) &&
fimaConditions.IsValid();
if (!result)
{
return result;
}
//
// Validate Pattern Based on MA Band ...
result = ValidatePatternBasedOnMABand(
bar,
patternName,
patternDir,
fimaConditions //
);
if (!result)
{
return result;
}
//
// Check Affected Zone ...
// Select a Support or Resistance ...
int insideZoneIDX = -1;
result =
(isBullish
? HasInside(
insideZoneIDX,
bar,
supports //
)
: HasInside(
insideZoneIDX,
bar,
resistances //
));
if (!result)
{
return result;
}
//
// Filling Affected Zone ...
// and Validate it ...
if (IsXBullish(patternDir))
{
iZone = supports[insideZoneIDX];
}
else if (IsXBearish(patternDir))
{
iZone = resistances[insideZoneIDX];
}
result = iZOne.IsValid();
if (!result)
{
return result;
}
//
// Validate affected Zone based on Pattern's Bar ...
result = IsXBullish(patternDir)
? bar.high > iZZone.upper
: IsXBearish(patternDir)
? bar.low < iZone.lower
: false;
//
// Cleanup Resources ...
if (!result)
{
iZone.Clean();
}
//
return result;
}
/**
* Check Pattern Has Signal Based on Strategy 1 ...
*
* @param bar: XOHCL, reference to Pattern Bar ...
* @param iZone: XBoxZone, reference to holds affected zone ...
* @param patternName: string, detected pattern's name ...
* @param supports: XBoxZone, array reference to Provide Exists Supports ...
* @param resistances: XBoxZone, array reference to Provide Exists Resistances ...
* @param patternDir: ENUM_X_DIRECTION, detected pattern's direction ...
* @param fimaConditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
* @param fimaMarketStructure: XFIMAMarketStructure, refrence to Provides Market Structure ...
*
* @return ( bool )
*/
bool Strategy2HasSignal(
XOHCL &bar,
XBoxZone &iZone,
string patternName,
XBoxZone &supports[],
XBoxZone &resistances[],
ENUM_X_DIRECTION patternDir,
XFIMAMarketStructure &structure,
XFIMAConditions &fimaConditions,
XFIMAMarketStructure &fimaMarketStructure //
)
{
//
bool result = false;
//
// Prepare ...
//
// Validate ...
//
// Do Detection ...
//
// Validate result ...
//
// Cleanup Resources ...
//
return result;
}
//
};
//