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

3727 lines
95 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.parser.class.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 ...
//
CArrayObj drawnObjects; // Drawing Objects Holder ...
XFIMAInputs fimaInputs; // XFIMA Inputs ...
XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ...
XCXFIMAPOIDrawer *poiDrawer; // XFIMA POI Drawer ...
XCXFIMAHelperParser *fimaParser; // XFIMA Helper Parser ...
XCXFIMAPOIDetector *poiDetector; // XFIMA POI Detector ...
XFIMAMarketStructureConfig structureConfig; // XFIMA Market Structure Detector Config ...
XFIMAMarketStructureDrawerConfig structureDrawConfig; // XFIMA Market Structure Draw Config ...
//
// 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);
}
}
//
// Instantiate XFIMA Helper Parser ...
fimaParser = new XCXFIMAHelperParser(fimaHelper);
//
poiDrawer = new XCXFIMAPOIDrawer();
poiDetector = new XCXFIMAPOIDetector(fimaHelper, fimaParser);
//
// Configure ...
structureConfig.Default();
structureDrawConfig.Default();
}
//
// Deconstructor ...
~XCXFIMABaseSignaller()
{
Destroy();
}
//
// Overrides ...
//
// Actions ...
/**
* Destroy ...
*/
void Destroy()
{
//
BeforeDestroy();
//
fimaInputs.Clean();
//
delete fimaHelper;
ZeroMemory(fimaHelper);
//
delete poiDrawer;
ZeroMemory(poiDrawer);
//
delete poiDetector;
ZeroMemory(poiDetector);
//
structureConfig.Clean();
structureDrawConfig.Clean();
}
//
// 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;
if (!result)
{
return result;
}
//
return result;
}
/**
* Normalizing Signal by Signaller Custom Props ...
*
* @param signal: XSignal ...
*/
void virtual NormalizeSignal(XSignal &signal)
{
}
//
// Protected ...
protected:
//
//
// Protected Actions ...
//
// Private ...
private:
//
};
//
// XFIMA Strategy 2 Signaller Class ...
class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
{
//
// Public ...
public:
//
// Props ...
//
// 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 ...
drawLeg = false;
drawZones = false;
drawIZones = false;
drawTrends = false;
drawSCTrend = false;
drawMCTrend = false;
drawLCTrend = false;
drawHCTrend = false;
drawSupport = false;
drawISupport = false;
drawOrderFlow = false;
drawResistance = false;
drawIResistance = false;
//
manageLegs = true;
manageZones = true;
manageIZones = true;
manageTrends = false;
manageOrderFlow = true;
//
structureConfig.Default();
structureDrawConfig.Default();
}
//
// Deconstructor ...
~XCXFIMAStrategy1Signaller()
{
//
Destroy();
}
//
// 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;
XBoxZone iZone;
XSignal iSignal;
bool has = false;
XTarget iTargets[];
bool isBullish = false;
bool isBearish = false;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
// Initialize Bar as CBar ...
has = iBar.Init(
symbol,
period,
barIndex //
);
if (!has)
{
//
iBar.Clean();
return;
}
//
// Manage ...
Manage(iBar);
//
// Strategy X ...
has = HasSignal(
iBar,
iZone,
iTargets,
iDir //
);
//
// Handle Resting Signals ...
has = HasDirection(iDir) &&
iZone.IsValid();
//
// Prepare Signal ...
if (has)
{
//
isBullish = IsXBullish(iDir);
isBearish = IsXBearish(iDir);
//
// Provided SL ...
double points = GetPoints(symbol);
double spread = GetSpread(symbol);
double entry = GetEntry(symbol, iDir);
//
// Calculate SL Addition ...
double slAddition =
slAdditionDistance <= 0
? 0
: slAdditionDistance * points;
//
// Calculate SL Price ...
double sl =
isBullish
? iZone.lower - slAddition
: iZone.upper + slAddition;
//
// Prepare Signal ...
has = PrepareSignal(
iSignal,
iDir,
iTargets,
0, // Use Default R2R ...
sl, // Provided Price for SL ...
0 // Specified Risk in Point ....
);
}
//
// Notify On Signal Event ...
if (has)
{
NotifySignalEventListeners(iSignal);
}
//
// Cleanup ...
iBar.Clean();
iZone.Clean();
iSignal.Clean();
XClean(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;
//
XClean(guards);
return result;
//
int positionsCount = ArraySize(positions);
if (!IsValidSize(positionsCount))
{
return result;
}
//
// Requirements ...
XGuard iGuard;
bool has = false;
int samePeaks = 0;
int sameVales = 0;
double iValue = 0;
double points10 = 0;
double points50 = 0;
double points100 = 0;
int samePVValidation = 5;
bool isPeakOverLast = false;
bool isValeUnderLast = false;
//
for (int i = 0; i < positionsCount; i++)
{
//
points10 = 10 * positions[i].GetPointsValue();
points50 = 50 * positions[i].GetPointsValue();
points100 = 100 * positions[i].GetPointsValue();
//
// Near to TP Guard ...
has = positions[i].profit > 0;
if (has)
{
//
// Has Same Peaks or Vales ...
samePeaks = fimaParser.CountSamePeaks(barIndex);
sameVales = fimaParser.CountSameVales(barIndex);
isPeakOverLast = (fimaParser.IsPeakOverLast(barIndex) ||
fimaParser.IsPeakOverLast(barIndex + 1));
isValeUnderLast = (fimaParser.IsValeUnderLast(barIndex) ||
fimaParser.IsValeUnderLast(barIndex + 1));
has = (positions[i].IsBullish()
? (
isPeakOverLast &&
sameVales >= samePVValidation &&
fimaHelper.GetVale(barIndex) > positions[i].sl)
: positions[i].IsBearish()
? (
isValeUnderLast &&
samePeaks >= samePVValidation &&
fimaHelper.GetPeak(barIndex) < positions[i].sl)
: false);
if (has)
{
//
iGuard.Clean();
iGuard.time = TimeCurrent();
iGuard.symbol = positions[i].symbol;
iGuard.period = positions[i].period;
iGuard.ticket = positions[i].ticket;
iGuard.provider = positions[i].provider;
iGuard.sl = positions[i].IsBullish()
? fimaHelper.GetVale(barIndex) - points10
: fimaHelper.GetPeak(barIndex) + points10;
iGuard.action = X_GUARD_ACTION_TRAIL_STOP;
//
has = iGuard.IsValid();
if (has)
{
AddRef(iGuard, guards);
//
// Remove TP if in Profit SL ...
iValue = (positions[i].IsBullish() ? positions[i].entry + points10 : positions[i].entry - points10);
has =
(positions[i].IsBullish() && HasResistance())
? (iGuard.sl >= iValue &&
positions[i].tp < resistance.lower)
: (positions[i].IsBearish() && HasSupport())
? (iGuard.sl <= iValue &&
positions[i].tp > support.upper)
: false;
if (has)
{
//
iGuard.Clean();
iGuard.force = false;
iGuard.tp = positions[i].IsBullish()
? resistance.lower
: support.upper;
iGuard.time = TimeCurrent();
iGuard.symbol = positions[i].symbol;
iGuard.period = positions[i].period;
iGuard.ticket = positions[i].ticket;
iGuard.provider = positions[i].provider;
iGuard.action = X_GUARD_ACTION_TRAIL_TARGET;
//
has = iGuard.IsValid();
if (has)
{
AddRef(iGuard, guards);
}
}
}
}
}
}
//
result = ArraySize(guards);
//
// Cleanup ...
iGuard.Clean();
//
return result;
}
//
// Protected ...
protected:
//
//
void Manage(XOHCL &bar)
{
//
bool has = bar.IsValid();
if (!has)
{
return;
}
//
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
has = bar.GetPreviousBar(pBar);
has = has &&
pBar.GetPreviousBar(p2Bar);
has = has &&
p2Bar.GetPreviousBar(p3Bar);
if (!has)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
}
//
ManageLeg(bar);
ManageTrends(bar);
ManageZones(p2Bar);
ManageIZones(p2Bar);
ManageOrderFlow(p3Bar);
//
// Cleanup ...
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
}
//
// Private ...
private:
//
// Props ...
//
// Leg ...
XLeg leg; // Exists Leg ...
bool drawLeg; // Draw Leg ...
bool manageLegs;
//
bool HasLeg()
{
return leg.IsValid();
}
//
bool ValidateLeg(XOHCL &bar)
{
//
bool result = false;
//
result = HasLeg() &&
bar.IsValid();
if (!result)
{
return result;
}
//
result =
leg.IsBullish()
? bar.low > leg.lower
: leg.IsBearish()
? bar.high < leg.upper
: false;
//
return result;
}
//
void DrawLeg()
{
//
if (!drawLeg)
{
return;
}
//
if (!HasLeg())
{
return;
}
//
// Update to Times ...
leg.UpdateTimes();
//
// Draw Leg Box ...
XBoxZone legZone;
leg.ToBox(legZone);
if (legZone.IsValid())
{
//
legZone.to = TimeCurrent();
poiDrawer.DrawZone(legZone, structureDrawConfig.drawConfig);
}
//
// Draw Legs Other Stufs ...
return;
//
// FVGs ...
poiDrawer.DrawZones(leg.bullishFVGs, structureDrawConfig.drawConfig);
poiDrawer.DrawZones(leg.bearishFVGs, structureDrawConfig.drawConfig);
//
// Support and Resistances ...
poiDrawer.DrawZones(leg.supports, structureDrawConfig.drawConfig);
poiDrawer.DrawZones(leg.resistances, structureDrawConfig.drawConfig);
//
// Patterns ...
poiDrawer.DrawPatternAnalysises(leg.patterns, structureDrawConfig.barAnalysisDrawConfig);
}
//
void ManageLeg(XOHCL &bar)
{
//
// Validate Exists ...
if (HasLeg())
{
//
if (!ValidateLeg(bar))
{
//
// Invalidate XLeg ...
leg.Clean();
}
}
//
// Detect New ...
if (!HasLeg())
{
poiDetector.IsLegPattern(bar, leg);
}
//
// Update Exists ...
if (HasLeg())
{
//
// Update to Times ...
leg.UpdateTimes();
//
DrawLeg();
}
}
//
// Order Flow ...
//
bool drawOrderFlow;
XBoxZone orderFlow[];
bool manageOrderFlow;
ENUM_X_DIRECTION orderFlowDir;
//
bool HasOrderFlow()
{
//
return HasChild(orderFlow) &&
HasDirection(orderFlowDir);
}
//
bool HasBullishOrderFlow()
{
return HasOrderFlow() &&
IsXBullish(orderFlowDir);
}
//
bool HasBearishOrderFlow()
{
return HasOrderFlow() &&
IsXBearish(orderFlowDir);
}
//
bool GetOrderFlowBoundary(
double &upper,
double &lower //
)
{
//
bool result = false;
//
// Prepare ...
upper = EMPTY_VALUE;
lower = EMPTY_VALUE;
//
// Validate ...
result = HasOrderFlow();
if (!result)
{
return result;
}
//
int idx = -1;
//
// Upper ...
idx = GetHighest(orderFlow);
if (IsValidIndex(idx))
{
upper = orderFlow[idx].upper;
}
//
// Lower ...
idx = GetLowest(orderFlow);
if (IsValidIndex(idx))
{
lower = orderFlow[idx].lower;
}
//
result = NotEmptyZero(upper) &&
NotEmptyZero(lower) &&
upper > lower;
//
// Cleanup ...
if (!result)
{
//
upper = EMPTY_VALUE;
lower = EMPTY_VALUE;
}
//
return result;
}
//
bool ValidateOrderFlow(XOHCL &bar)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
HasOrderFlow();
if (!result)
{
return result;
}
//
double upper = EMPTY_VALUE;
double lower = EMPTY_VALUE;
result = GetOrderFlowBoundary(upper, lower);
result = result &&
HasBullishOrderFlow()
? bar.low > lower
: bar.high < upper;
//
return result;
}
//
void DrawOrderFlow()
{
//
if (!drawOrderFlow || !HasOrderFlow())
{
return;
}
//
poiDrawer.DrawZones(orderFlow, structureDrawConfig.drawConfig);
}
//
void ManageOrderFlow(XOHCL &bar)
{
//
// Validate Exists ...
if (HasOrderFlow())
{
//
if (!ValidateOrderFlow(bar))
{
//
// Invalidate OrderFlow ...
XClean(orderFlow);
orderFlowDir = X_DIRECTION_NONE;
}
}
//
// Detect New ...
if (!HasOrderFlow())
{
//
XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig;
// patternConfig.Default();
// patternConfig.supportAndResistanceLoopbackLength = 21;
// patternConfig.supportAndResistanceValidationLength = 7;
//
poiDetector.HasOrderFlow(
bar,
orderFlowDir,
orderFlow,
structureConfig.orderFlowValidation,
structureConfig.orderFlowUseOB,
structureConfig.orderFlowUseFVG,
structureConfig.orderFlowUseSupportAndResistance,
patternConfig.supportAndResistanceLoopbackLength,
patternConfig.supportAndResistanceValidationLength,
structureConfig.loopback //
);
}
//
// Update Exists ...
if (HasOrderFlow())
{
//
// Update to Times ...
UpdateToTime(orderFlow, TimeCurrent());
//
DrawOrderFlow();
}
}
//
// Zone ...
//
XBoxZone support;
XBoxZone resistance;
bool drawZones;
bool drawSupport;
bool manageZones;
bool drawResistance;
//
bool HasZones()
{
return HasSupport() ||
HasResistance();
}
//
bool HasSupport()
{
return support.IsValid();
}
//
bool HasResistance()
{
return resistance.IsValid();
}
//
bool ValidateZones(XOHCL &bar)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
HasZones();
if (!result)
{
return result;
}
//
// Support ...
bool hasSupport = HasSupport();
if (hasSupport)
{
//
result = bar.close > support.lower &&
!IsBreaked(support, X_PRICE_CLOSE);
if (!result)
{
//
iResistance = support;
iResistance.breakAt = NULL;
iResistance.dir = X_DIRECTION_BEARISH;
iResistance.to = bar.time + (PeriodSeconds(bar.period));
iResistance.from = bar.time - (PeriodSeconds(bar.period));
//
support.breakAt = bar.time;
support.Clean();
}
}
//
// Resistance ...
bool hasResistance = HasResistance();
if (hasResistance)
{
//
result = bar.close < resistance.upper &&
!IsBreaked(resistance, X_PRICE_CLOSE);
if (!result)
{
//
iSupport = resistance;
iSupport.breakAt = NULL;
iSupport.dir = X_DIRECTION_BULLISH;
iSupport.to = bar.time + (PeriodSeconds(bar.period));
iSupport.from = bar.time - (PeriodSeconds(bar.period));
//
resistance.breakAt = bar.time;
resistance.Clean();
}
}
//
result =
(hasSupport && !HasSupport()) ||
(hasResistance && !HasResistance());
//
return result;
}
//
void DrawZones()
{
//
if (!drawZones || !HasZones())
{
return;
}
//
if (drawSupport && HasSupport())
{
poiDrawer.DrawZone(support, structureDrawConfig.drawConfig);
}
//
if (drawResistance && HasResistance())
{
poiDrawer.DrawZone(resistance, structureDrawConfig.drawConfig);
}
}
//
void ManageZones(XOHCL &bar)
{
//
// Validate Exists ...
if (HasZones())
{
//
if (!ValidateZones(bar))
{
//
// Invalidate Zones ...
//
// Support ...
if (IsXValid(support.breakAt))
{
//
iResistance = support;
iResistance.breakAt = NULL;
iResistance.dir = X_DIRECTION_BEARISH;
iResistance.to = bar.time + (PeriodSeconds(bar.period));
iResistance.from = bar.time - (PeriodSeconds(bar.period));
//
support.Clean();
}
//
// Resistance ...
if (IsXValid(resistance.breakAt))
{
//
iSupport = resistance;
iSupport.breakAt = NULL;
iSupport.dir = X_DIRECTION_BULLISH;
iSupport.to = bar.time + (PeriodSeconds(bar.period));
iSupport.from = bar.time - (PeriodSeconds(bar.period));
//
resistance.Clean();
}
}
}
//
// Detect New ...
XOHCL tmpBar;
bool has = false;
//
// Detect Support ...
if (!HasSupport())
{
//
has = poiDetector.HasSupport(
bar,
tmpBar,
structureConfig.barsAnalysisConfig.supportAndResistanceValidationLength,
structureConfig.barsAnalysisConfig.supportAndResistanceLoopbackLength //
);
if (has)
{
//
has = ToSupportBox(tmpBar, support, bar.time);
has =
has &&
!IsBreaked(support, X_PRICE_CLOSE);
if (!has)
{
//
if (support.IsValid())
{
//
iResistance = support;
iResistance.breakAt = NULL;
iResistance.dir = X_DIRECTION_BEARISH;
iResistance.to = bar.time + (PeriodSeconds(bar.period));
iResistance.from = bar.time - (PeriodSeconds(bar.period));
}
//
support.Clean();
}
}
}
//
// Detect Resistance ...
if (!HasResistance())
{
//
has = poiDetector.HasResistance(
bar,
tmpBar,
structureConfig.barsAnalysisConfig.supportAndResistanceValidationLength,
structureConfig.barsAnalysisConfig.supportAndResistanceLoopbackLength //
);
if (has)
{
//
has = ToResistanceBox(tmpBar, resistance, bar.time);
has =
has &&
!IsBreaked(resistance, X_PRICE_CLOSE);
if (!has)
{
//
if (resistance.IsValid())
{
//
iSupport = resistance;
iSupport.breakAt = NULL;
iSupport.dir = X_DIRECTION_BULLISH;
iSupport.to = bar.time + (PeriodSeconds(bar.period));
iSupport.from = bar.time - (PeriodSeconds(bar.period));
}
//
resistance.Clean();
}
}
}
//
// Update Exists ...
if (HasZones())
{
//
if (HasSupport())
{
//
support.to = bar.time;
support.type = "XFIMASup";
}
//
if (HasResistance())
{
//
resistance.to = bar.time;
resistance.type = "XFIMARes";
}
//
DrawZones();
}
//
// Cleanup ...
tmpBar.Clean();
}
//
XBoxZone iSupport;
XBoxZone iResistance;
bool drawIZones;
bool drawISupport;
bool manageIZones;
bool drawIResistance;
//
bool HasIZones()
{
//
return HasISupport() ||
HasIResistance();
}
//
bool HasISupport()
{
return iSupport.IsValid();
}
//
bool HasIResistance()
{
return iResistance.IsValid();
}
//
void DrawIZones()
{
//
if (!drawIZones || !HasIZones())
{
return;
}
//
if (drawISupport && HasISupport())
{
poiDrawer.DrawZone(iSupport, structureDrawConfig.drawConfig);
}
//
if (drawIResistance && HasIResistance())
{
poiDrawer.DrawZone(iResistance, structureDrawConfig.drawConfig);
}
}
//
bool ValidateIZones(XOHCL &bar)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
HasIZones();
if (!result)
{
return result;
}
//
//
// Support ...
bool hasSupport = HasISupport();
if (hasSupport)
{
//
result = bar.close > iSupport.lower &&
!IsBreaked(iSupport, X_PRICE_CLOSE);
if (!result)
{
//
iSupport.breakAt = bar.time;
iSupport.Clean();
}
}
//
// Resistance ...
bool hasResistance = HasIResistance();
if (hasResistance)
{
//
result = bar.close < iResistance.upper &&
!IsBreaked(iResistance, X_PRICE_CLOSE);
if (!result)
{
//
iResistance.breakAt = bar.time;
iResistance.Clean();
}
}
//
result =
(hasSupport && !HasISupport()) ||
(hasResistance && !HasIResistance());
//
return result;
}
//
void ManageIZones(XOHCL &bar)
{
//
// Validate Exists ...
if (HasIZones())
{
//
if (!ValidateIZones(bar))
{
//
// Invalidate Zones ...
//
// Support ...
if (IsXValid(iSupport.breakAt))
{
iSupport.Clean();
}
//
// Resistance ...
if (IsXValid(iResistance.breakAt))
{
iResistance.Clean();
}
}
}
//
// Update Exists ...
if (HasIZones())
{
//
if (HasISupport())
{
//
iSupport.to = bar.time;
iSupport.type = "XFIMAISup";
}
//
if (HasIResistance())
{
//
iResistance.to = bar.time;
iResistance.type = "XFIMAIRes";
}
//
DrawIZones();
}
}
//
// Trends ...
//
XTrend scTrend;
XTrend mcTrend;
XTrend lcTrend;
XTrend hcTrend;
//
bool drawTrends;
bool drawSCTrend;
bool drawMCTrend;
bool drawLCTrend;
bool drawHCTrend;
bool manageTrends;
//
bool HasTrend()
{
//
bool result =
HasSCTrend() ||
HasMCTrend() ||
HasLCTrend() ||
HasHCTrend();
//
return result;
}
//
bool HasSCTrend()
{
return scTrend.IsValid() &&
scTrend.HasTrend();
}
//
bool HasMCTrend()
{
return mcTrend.IsValid() &&
mcTrend.HasTrend();
}
//
bool HasLCTrend()
{
return lcTrend.IsValid() &&
lcTrend.HasTrend();
}
//
bool HasHCTrend()
{
return hcTrend.IsValid() &&
hcTrend.HasTrend();
}
//
void DrawTrends()
{
//
if (!drawTrends || !HasTrend())
{
return;
}
//
// SC ...
if (drawSCTrend && HasSCTrend())
{
poiDrawer.DrawTrendLine(scTrend, structureDrawConfig.drawConfig);
}
//
// MC ...
if (drawMCTrend && HasMCTrend())
{
poiDrawer.DrawTrendLine(mcTrend, structureDrawConfig.drawConfig);
}
//
// LC ...
if (drawLCTrend && HasLCTrend())
{
poiDrawer.DrawTrendLine(lcTrend, structureDrawConfig.drawConfig);
}
//
// HC ...
if (drawHCTrend && HasHCTrend())
{
poiDrawer.DrawTrendLine(hcTrend, structureDrawConfig.drawConfig);
}
}
//
void ManageTrends(XOHCL &bar)
{
//
// Validate ...
bool has = bar.IsValid();
if (!has)
{
return;
}
//
XTrend tmpTrend;
//
// SC ...
tmpTrend.Clean();
has = fimaParser.HasSCTrend(tmpTrend, bar.Index());
if (has)
{
scTrend = tmpTrend;
}
//
// MC ...
tmpTrend.Clean();
has = fimaParser.HasMCTrend(tmpTrend, bar.Index());
if (has)
{
mcTrend = tmpTrend;
}
//
// LC ...
tmpTrend.Clean();
has = fimaParser.HasLCTrend(tmpTrend, bar.Index());
if (has)
{
lcTrend = tmpTrend;
}
//
// HC ...
tmpTrend.Clean();
has = fimaParser.HasHCTrend(tmpTrend, bar.Index());
if (has)
{
hcTrend = tmpTrend;
}
//
DrawTrends();
//
// Cleanup ...
tmpTrend.Clean();
}
//
// Implementing Strategies ...
/**
* Check Bar Has Signal Based on Strategy X ...
*
* @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 ...
*
* @return ( bool )
*/
bool HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Configuration Flags ...
//
// Signaller Flags ...
bool useSignaller1 = true;
bool useSignaller2 = false;
bool useSignaller3 = false;
bool useSignaller4 = false;
//
XBoxZone tmpZone;
string provider = NULL;
ENUM_X_DIRECTION tmpDir;
//
bool signaller1HasSignal = false;
bool signaller2HasSignal = false;
bool signaller3HasSignal = false;
bool signaller4HasSignal = false;
//
// Validator Flags ...
bool validateByOrderFlow = false;
//
// Target Flags ...
bool hasPartialCloseOnTp1 = false;
//
bool doRFOnEntryOnTP1 = false;
//
// Draw Flags ...
bool draw = true;
bool drawZone = true;
bool drawMarketStructurePivots = false;
bool drawMarketStructureAnalysis = false;
bool drawMarketStructureOrderFlow = false;
XPOIDrawConfig iDrawConfig;
//
drawLeg = false;
drawZones = false;
drawIZones = false;
drawTrends = false;
drawSCTrend = false;
drawMCTrend = false;
drawLCTrend = false;
drawHCTrend = false;
drawSupport = false;
drawISupport = false;
drawOrderFlow = false;
drawResistance = false;
drawIResistance = false;
//
// Signal Checking ...
//
// Analyse Market Strucutre ...
XFIMAMarketStructure marketStructure;
//
// Signal Detection Flags ...
//
// Signaller 1 ...
if (useSignaller1)
{
//
signaller1HasSignal = Strategy1HasSignal(
bar,
tmpZone,
targets,
tmpDir //
);
//
if (signaller1HasSignal)
{
//
provider += "1";
//
if (!zone.IsValid())
{
//
dir = tmpDir;
zone = tmpZone;
}
}
//
tmpZone.Clean();
tmpDir = X_DIRECTION_NONE;
}
//
// Signaller 2 ...
if (useSignaller2)
{
//
signaller2HasSignal = Strategy2HasSignal(
bar,
tmpZone,
targets,
tmpDir //
);
//
if (signaller2HasSignal)
{
//
provider += "2";
//
if (!zone.IsValid())
{
//
dir = tmpDir;
zone = tmpZone;
}
}
//
tmpZone.Clean();
tmpDir = X_DIRECTION_NONE;
}
//
// Signaller 3 ...
if (useSignaller3)
{
//
signaller3HasSignal = Strategy3HasSignal(
bar,
tmpZone,
targets,
tmpDir //
);
//
if (signaller3HasSignal)
{
//
provider += "3";
//
if (!zone.IsValid())
{
//
dir = tmpDir;
zone = tmpZone;
}
}
//
tmpZone.Clean();
tmpDir = X_DIRECTION_NONE;
}
//
// Signaller 4 ...
if (useSignaller4)
{
//
signaller4HasSignal = Strategy4HasSignal(
bar,
tmpZone,
targets,
tmpDir //
);
//
if (signaller4HasSignal)
{
//
provider += "4";
//
if (!zone.IsValid())
{
//
dir = tmpDir;
zone = tmpZone;
}
}
//
tmpZone.Clean();
tmpDir = X_DIRECTION_NONE;
}
//
// Summarize Signallers Result ...
result = signaller1HasSignal ||
signaller2HasSignal ||
signaller3HasSignal ||
signaller4HasSignal;
//
// Signal Validating ...
//
// Validate Signals by Order Flow ...
if (result && validateByOrderFlow)
{
//
// Analyse Market Structure if Required ...
if (!marketStructure.IsValid())
{
//
poiDetector.AnalyseMarket(
marketStructure,
structureConfig,
bar.Index() //
);
}
//
bool isBullish = IsXBullish(dir) &&
marketStructure.HasBullishOrderFlow();
//
bool isBearish = IsXBearish(dir) &&
marketStructure.HasBearishOrderFlow();
//
// Summarizing result ...
result = isBullish ||
isBearish;
}
//
// Targets, Restrictions and Risk Management ...
if (result)
{
//
// Requirements ...
XTarget iTarget;
//
// Checking Direction of Signal ...
bool isBullish = IsXBullish(dir);
bool isBearish = IsXBearish(dir);
//
// Provided SL ...
double points = GetPoints(symbol);
double spread = GetSpread(symbol);
double entry = GetEntry(symbol, dir);
//
// Calculate SL Addition ...
double slAddition =
slAdditionDistance <= 0
? 0
: slAdditionDistance * points;
//
// Calculate SL Price ...
double sl =
isBullish
? zone.lower - slAddition
: zone.upper + slAddition;
//
// Calculate Risk ...
double risk = MathAbs(entry - sl);
//
// Calculate Reward ...
double reward = defaultSignalR2R * risk;
//
// Calculate TP1 ...
double tp1 = isBullish
? entry + risk
: entry - risk;
double tp2 = isBullish
? entry + (2 * risk)
: entry - (2 * risk);
//
// Calculate TP ...
double tp = isBullish
? entry + reward
: entry - reward;
//
// Check Max Allowed Risk ...
bool hasTooMuchRisk = maxAllowedRiskDistance <= 0
? false
: risk >= (maxAllowedRiskDistance * points);
if (hasTooMuchRisk)
{
//
// Clean Signal if Too much Risk ...
zone.Clean();
dir = X_DIRECTION_NONE;
}
//
// Common Targets ...
//
// Partial Close on TP 1 ...
if (hasPartialCloseOnTp1)
{
//
iTarget.Clean();
iTarget.target = tp1;
iTarget.actingDistance = 5;
iTarget.volumeMultiplier = 0.8;
iTarget.doRFOnEntry = doRFOnEntryOnTP1;
//
AddRef(iTarget, targets);
}
//
// Custom Signaller Targets ...
//
// Restrictions Handling ...
if (risk > 0 && HasRestrictions())
{
//
// Reset Restricitons if necessary ...
ResetRestrictions();
//
// Handle Custom Restrictions Senario ...
}
//
// Ignore Targets ...
if (ignoreTargets)
{
XClean(targets);
}
//
// Summarize Result ...
result = zone.IsValid() &&
HasDirection(dir);
//
// Cleanup ...
iTarget.Clean();
}
//
// Draws ...
if (result && draw)
{
//
// Prepare Draw Config ...
iDrawConfig = structureDrawConfig.drawConfig;
iDrawConfig.zonesWidth = 3;
iDrawConfig.zonesStyle = STYLE_DASH;
iDrawConfig.bullishColor = clrYellow;
iDrawConfig.bearishColor = clrDarkOrange;
//
// Draw Zone ...
if (drawZone)
{
poiDrawer.DrawZone(zone, iDrawConfig);
}
//
// Draw Market Structure ...
//
// Analyse Market Structure if Required ...
if (!marketStructure.IsValid())
{
//
poiDetector.AnalyseMarket(
marketStructure,
structureConfig,
bar.Index() //
);
}
if (marketStructure.IsValid())
{
//
// Order Flow ...
if (drawMarketStructureOrderFlow && marketStructure.HasOrderFlow())
{
poiDrawer.DrawZones(marketStructure.orderFlow, iDrawConfig);
}
//
// Pivots ...
if (drawMarketStructurePivots)
{
//
XPivot pivots[];
int pivotsCount = marketStructure.CollectPivots(
pivots,
true // Contains Patterns ...
);
if (IsValidSize(pivotsCount))
{
poiDrawer.DrawPivots(pivots, iDrawConfig);
}
//
XClean(pivots);
}
//
// Analysis ...
if (drawMarketStructureAnalysis)
{
//
}
}
//
// Other Drawing Materials ...
Print("Signaller Providers: ", provider);
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
//
// Cleanup ...
tmpZone.Clean();
iDrawConfig.Clean();
marketStructure.Clean();
//
return result;
}
//
// Custom Signal Strategies ...
/**
* Check Bar Has Signal Based on Strategy 3 ...
*
* @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 ...
*
* @return ( bool )
*/
bool Strategy1HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
return result;
}
//
// Reading Conditions ...
int pullBackStartBar = -1;
bool isPullBack = result &&
poiDetector.IsPullbackPattern(
pBar,
zone,
dir,
2,
false // Force Break ...
);
bool isPullbackBullish = isPullBack &&
IsXBullish(dir);
bool isPullbackBearish = isPullBack &&
IsXBearish(dir);
if (isPullBack)
{
pullBackStartBar = zone.FromIndex();
}
//
// Reading HK Band ...
//
double pHKBandUpper = fimaHelper.GetHKBandUpper(pBar.Index());
double pHKBandLower = fimaHelper.GetHKBandLower(pBar.Index());
int overHKBandUpperCount = fimaParser.CountOverHKBandUpper(pullBackStartBar, X_PRICE_LOW);
int underHKBandLowerCount = fimaParser.CountUnderHKBandLower(pullBackStartBar, X_PRICE_HIGH);
//
// Reading PV Requirements ...
//
int lastPeakOverLastIDX = -1;
int lastValeUnderLastIDX = -1;
double pPeak = fimaHelper.GetPeak(pBar.Index());
double pVale = fimaHelper.GetVale(pBar.Index());
int samePeaks = fimaParser.CountSamePeaks(pBar.Index());
int sameVales = fimaParser.CountSameVales(pBar.Index());
fimaParser.FindLastPeakOverLast(lastPeakOverLastIDX, pBar.Index());
fimaParser.FindLastValeUnderLast(lastValeUnderLastIDX, pBar.Index());
//
// Reading pBar Patterns ...
XOHCL _tmpBar;
XPivot _tmpPivot;
XBoxZone _support;
XBoxZone _resistance;
XPatternAnalysis pBarPatterns;
poiDetector.AnalyseBarPatterns(
pBar,
pBarPatterns,
structureConfig.barsAnalysisConfig //
);
bool hasSupport = pBarPatterns.IsSupport();
bool hasResistance = pBarPatterns.IsResistance();
if (hasSupport)
{
hasSupport = pBarPatterns.GetSupport(_tmpBar, _tmpPivot, _support);
}
if (hasResistance)
{
hasResistance = pBarPatterns.GetResistance(_tmpBar, _tmpPivot, _resistance);
}
//
// Check Bar Patterns ...
bool isPBarHasBullishPatterns =
(bar.close > pBar.low ||
bar.open > pBar.low) &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
//
);
bool isPBarHasBearishPatterns =
(bar.close < pBar.high ||
bar.open < pBar.high) &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
// Check PBar Close Over Under Fast Ma ...
bool isPBarCloseOverFast = pBar.close > fimaHelper.GetMAFast(pBar.Index());
bool isPBarCloseUnderFast = pBar.close < fimaHelper.GetMAFast(pBar.Index());
//
// Try To Find Affected Zone ...
//
// Collecting Zones ...
XBoxZone zones[];
XBoxZone affectedZones[];
XBoxZone affectedZonesBullish[];
XBoxZone affectedZonesBearish[];
int zonesCount = poiDetector.CollectZones(
pBar,
zones, //
5, // Zones Loopback ...
3 // Zones Validation Length ...
// Required Zones ...
// Loopback ...
);
int affectedZonesCount = ExtractAffectedZones(
pBar,
zones,
affectedZones //
);
int affectedZonesBullishCount = ExtractByDirection(
affectedZonesBullish,
affectedZones,
X_DIRECTION_BULLISH //
);
int affectedZonesBearishCount = ExtractByDirection(
affectedZonesBearish,
affectedZones,
X_DIRECTION_BEARISH //
);
//
int insideBullishIDX = -1;
int insideBearishIDX = -1;
bool hasBullishInside =
pBar.IsBullish() &&
HasInside(
insideBullishIDX,
pBar,
affectedZonesBullish //
);
bool hasBearishInside =
pBar.IsBearish() &&
HasInside(
insideBearishIDX,
pBar,
affectedZonesBearish //
);
//
// Detecting Boundary Trend ...
XTrend boundaryTrend;
double boundaryMin = fimaParser.GetBoundaryMin(pBar.Index());
double boundaryMax = fimaParser.GetBoundaryMax(pBar.Index());
bool hasBoundaryTrend = fimaParser.HasBoundaryTrend(boundaryTrend, pBar.Index());
bool hasBoundaryBullishTrend = hasBoundaryTrend && boundaryTrend.IsBullish();
bool hasBoundaryBearishTrend = hasBoundaryTrend && boundaryTrend.IsBearish();
//
// Do ...
//
isBullish =
//
hasBullishInside &&
isPullbackBullish &&
isPBarHasBullishPatterns &&
fimaParser.IsSARBullish(pBar.Index()) &&
(pVale >= affectedZonesBullish[insideBullishIDX].lower &&
pVale <= affectedZonesBullish[insideBullishIDX].upper)
//
;
//
isBearish =
//
hasBearishInside &&
isPullbackBearish &&
isPBarHasBearishPatterns &&
fimaParser.IsSARBearish(pBar.Index()) &&
(pPeak >= affectedZonesBearish[insideBearishIDX].lower &&
pPeak <= affectedZonesBearish[insideBearishIDX].upper)
//
;
//
// Validate ...
result = isBullish ||
isBearish;
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
zone.Clean();
if (isBullish)
{
zone = affectedZonesBullish[insideBullishIDX];
}
else
{
zone = affectedZonesBearish[insideBearishIDX];
}
//
result = zone.IsValid();
//
// Zone Validations ...
if (result)
{
//
if (boundaryTrend.IsValid())
{
poiDrawer.DrawTrendLine(boundaryTrend, structureDrawConfig.drawConfig);
}
//
poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
//
if (hasSupport)
{
poiDrawer.DrawZone(_support, structureDrawConfig.drawConfig);
}
//
if (hasResistance)
{
poiDrawer.DrawZone(_resistance, structureDrawConfig.drawConfig);
}
//
if (HasChild(affectedZones))
{
poiDrawer.DrawZones(affectedZones, structureDrawConfig.drawConfig);
}
//
if (NotEmptyZero(boundaryMin))
{
//
XTrend trend;
trend.Init(
pBar.symbol,
pBar.period,
bar.time,
boundaryMin,
pBar.BeforeOn(),
boundaryMin,
pBar.NextAt() //
);
if (trend.IsValid())
{
//
XPOIDrawConfig iConfig = structureDrawConfig.drawConfig;
iConfig.trendRayLeft = false;
iConfig.trendRayRight = false;
//
poiDrawer.DrawTrendLine(trend, iConfig);
//
iConfig.Clean();
}
//
trend.Clean();
}
//
if (NotEmptyZero(boundaryMax))
{
//
XTrend trend;
trend.Init(
pBar.symbol,
pBar.period,
bar.time,
boundaryMax,
pBar.BeforeOn(),
boundaryMax,
pBar.NextAt() //
);
if (trend.IsValid())
{
//
XPOIDrawConfig iConfig = structureDrawConfig.drawConfig;
iConfig.trendRayLeft = false;
iConfig.trendRayRight = false;
//
poiDrawer.DrawTrendLine(trend, iConfig);
//
iConfig.Clean();
}
//
trend.Clean();
}
//
DebugBreak();
}
//
result = zone.IsValid();
//
// Reset Flags ...
if (!result)
{
//
zone.Clean();
isBullish = false;
isBearish = false;
}
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
XClean(zones);
_tmpBar.Clean();
_support.Clean();
_tmpPivot.Clean();
_resistance.Clean();
pBarPatterns.Clean();
boundaryTrend.Clean();
XClean(affectedZones);
XClean(affectedZonesBullish);
XClean(affectedZonesBearish);
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 2 ...
*
* Strategy 2:
* ===========
* - Works Based On PBar Patterns Focused on PinBar ...
* - Looking for a Bar Directional Pattern Happens ...
* - Validate Fast Ma Over/Under Slow ...
* - Validate P2Peak/Vale doesnt Under or Over Last (InDirectional) ...
* - Validate P2Bar Has Directional Market Strucuture Zone (OB, FVG, Support/Resistance) ...
*
* Manipulations:
* ================
* there are Some Flags properties to Change Validations in Strategy ...
* we can use them for Testing Purposes ...
*
* @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 ...
*
* @return ( bool )
*/
bool Strategy2HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
result = result &&
p2Bar.GetPreviousBar(p3Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
//
return result;
}
//
// Reading pBar Patterns ...
XPatternAnalysis pBarPatterns;
poiDetector.AnalyseBarPatterns(
pBar,
pBarPatterns,
structureConfig.barsAnalysisConfig //
);
bool hasSupport = pBarPatterns.IsSupport();
bool hasResistance = pBarPatterns.IsResistance();
//
// Check Boundary Trend ...
XTrend boundaryTrend;
bool hasBoundaryTrend = fimaParser.HasBoundaryTrend(boundaryTrend, pBar.Index());
bool hasBoundaryBullishTrend = hasBoundaryTrend && boundaryTrend.IsBullish();
bool hasBoundaryBearishTrend = hasBoundaryTrend && boundaryTrend.IsBearish();
//
// Check Bar Patterns ...
//
// Bars Sequences ...
bool hasBullishSequence = p3Bar.IsBearish() &&
pBar.IsBullish();
bool hasBearishSequence = p3Bar.IsBullish() &&
pBar.IsBearish();
//
// Bullish ...
bool isPBarHasBullishPatterns =
(bar.close > pBar.low ||
bar.open > pBar.low) &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
//
);
//
// Bearish ...
bool isPBarHasBearishPatterns =
(bar.close < pBar.high ||
bar.open < pBar.high) &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
double peak = fimaHelper.GetPeak(bar.Index());
double vale = fimaHelper.GetVale(bar.Index());
double pPeak = fimaHelper.GetPeak(pBar.Index());
double pVale = fimaHelper.GetVale(pBar.Index());
double p2Peak = fimaHelper.GetPeak(p2Bar.Index());
double p2Vale = fimaHelper.GetVale(p2Bar.Index());
bool isPPeakOverLast = fimaParser.IsPeakOverLast(pBar.Index());
bool isPValeUnderLast = fimaParser.IsValeUnderLast(pBar.Index());
bool isP2PeakOverLast = fimaParser.IsPeakOverLast(p2Bar.Index());
bool isP2ValeUnderLast = fimaParser.IsValeUnderLast(p2Bar.Index());
bool isPeakOverLast = isPPeakOverLast ||
isP2PeakOverLast;
bool isValeUnderLast = isPValeUnderLast ||
isP2ValeUnderLast;
bool isP2ValeOverLast = pVale > p2Vale;
bool isP2PeakUnderLast = pPeak < p2Peak;
//
// Check PBar Close Over Under Fast Ma ...
bool isPBarCloseOverFast = pBar.close > fimaHelper.GetMAFast(pBar.Index());
bool isPBarCloseUnderFast = pBar.close < fimaHelper.GetMAFast(pBar.Index());
bool isFastOverLast = fimaHelper.GetMAFast(pBar.Index()) > fimaHelper.GetMAFast(p2Bar.Index());
bool isFastUnderLast = fimaHelper.GetMAFast(pBar.Index()) < fimaHelper.GetMAFast(p2Bar.Index());
//
// Force P2Bar is Pin Bar ...
ENUM_X_DIRECTION p2Dir;
bool isP2BarPinned = poiDetector.IsPinnedBar(
p2Bar,
p2Dir //
);
bool isP2BarBullishPinned =
isP2BarPinned &&
IsXBullish(p2Dir);
bool isP2BarBearishPinned =
isP2BarPinned &&
IsXBearish(p2Dir);
//
// Check Based On LC and HC MA State ...
//
bool isLCMABullish = fimaParser.IsLCMABullish(pBar.Index());
bool isHCMABullish = fimaParser.IsHCMABullish(pBar.Index());
bool isCycleMABullish = isLCMABullish && isHCMABullish;
//
bool isLCMABearish = fimaParser.IsLCMABearish(pBar.Index());
bool isHCMABearish = fimaParser.IsHCMABearish(pBar.Index());
bool isCycleMABearish = isLCMABearish && isHCMABearish;
//
// Do ...
//
isBullish =
//
hasSupport &&
isFastOverLast &&
isValeUnderLast &&
isCycleMABullish &&
hasBullishSequence &&
!isP2PeakUnderLast &&
isPBarCloseOverFast &&
isP2BarBullishPinned &&
hasBoundaryBullishTrend &&
isPBarHasBullishPatterns
//
;
//
isBearish =
//
hasResistance &&
isPeakOverLast &&
isFastUnderLast &&
isCycleMABearish &&
!isP2ValeOverLast &&
hasBearishSequence &&
isPBarCloseUnderFast &&
isP2BarBearishPinned &&
hasBoundaryBearishTrend &&
isPBarHasBearishPatterns
//
;
//
// Validate ...
result = isBullish ||
isBearish;
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
zone.Clean();
result = ToBox(
p2Bar,
zone,
dir,
X_BAR_PATTERN_PINNED //
);
//
// Draws ...
if (result)
{
//
// XPOIDrawConfig iConfig = structureDrawConfig.drawConfig;
// iConfig.trendRayLeft = false;
// iConfig.trendRayRight = false;
// poiDrawer.DrawTrendLine(boundaryTrend, iConfig);
// poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
// iConfig.Clean();
//
// DebugBreak();
}
//
result = zone.IsValid();
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
pBarPatterns.Clean();
boundaryTrend.Clean();
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 3 ...
*
* Strategy 3:
* ===========
* - Works Based On Breaked Support or Resistances ...
* - Looking for a Support or Resistance to Breaked ...
* - Validate Breaker Bar to Change Peak or Vale ...
* - Validate Bar Opposit Side of Breaker Bar's Shadow ...
* - Validate by Checking Market Strucutre to Has Directional Zone
* (Support for Resistance Break / Resistance for Support Break) ...
* - Validate Breaker Bar to Has Directional FVG ...
*
* Manipulations:
* ================
* there are Some Flags properties to Change Validations in Strategy ...
* we can use them for Testing Purposes ...
*
* @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 ...
*
* @return ( bool )
*/
bool Strategy3HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Validation Flags ...
//
bool validateByPVChanges = true;
bool validateByGapExists = true;
bool validateByBarShadows = true;
bool validateHasDirectionalZone = true;
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
result = result &&
p2Bar.GetPreviousBar(p3Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
//
return result;
}
//
// Do ...
//
// Retrieve pBar Patterns ...
XBoxZone _fvg;
XBoxZone _support;
XBoxZone _resistance;
XPatternAnalysis pBarPatterns;
XPatternAnalysis p2BarPatterns;
XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig;
//
poiDetector.AnalyseBarPatterns(
pBar,
pBarPatterns,
patternConfig //
);
poiDetector.AnalyseBarPatterns(
p2Bar,
p2BarPatterns,
patternConfig //
);
//
// Price Must Break Support or Resistance ...
//
// Extract Support and Resistance ...
bool hasSupport = p2BarPatterns.IsSupport();
bool hasResistance = p2BarPatterns.IsResistance();
if (hasSupport)
{
//
XOHCL tmpBar;
XPivot tmpPivot;
hasSupport = p2BarPatterns.GetSupport(tmpBar, tmpPivot, _support);
tmpBar.Clean();
tmpPivot.Clean();
}
if (hasResistance)
{
//
XOHCL tmpBar;
XPivot tmpPivot;
hasResistance = p2BarPatterns.GetResistance(tmpBar, tmpPivot, _resistance);
tmpBar.Clean();
tmpPivot.Clean();
}
//
bool hasBreakedSupport = hasSupport &&
pBar.close < _support.lower &&
p2Bar.close > _support.lower;
bool hasBreakedResistance = hasResistance &&
pBar.close > _resistance.upper &&
p2Bar.close < _resistance.upper;
//
isBullish = hasBreakedResistance;
isBearish = hasBreakedSupport;
//
result = isBullish || isBearish;
//
// Validate By PV Changed ...
// Breaker Bar must Change Peak or Value ...
if (result && validateByPVChanges)
{
//
bool isPeakOverLast = fimaParser.IsPeakOverLast(pBar.Index());
bool isValeUnderLast = fimaParser.IsValeUnderLast(pBar.Index());
//
isBullish =
isBullish &&
isPeakOverLast;
//
isBearish =
isBearish &&
isValeUnderLast;
//
// Summarize Result ...
result = isBullish || isBearish;
}
//
// Validate by Bar Shadows ...
// Breakre Bar Side Shadow must not Reached ...
if (result && validateByBarShadows)
{
//
isBullish =
isBullish &&
pBar.low > p2Bar.low;
//
isBearish =
isBearish &&
pBar.high < p2Bar.high;
//
// Summarize Result ...
result = isBullish || isBearish;
}
//
// Validate Has Directional Zone ...
if (result && validateHasDirectionalZone)
{
//
isBullish =
isBullish &&
hasSupport;
//
isBearish =
isBearish &&
hasResistance;
//
// Summarize Result ...
result = isBullish || isBearish;
}
//
// Validate By Gap Exists ...
if (result && validateByGapExists)
{
//
ENUM_X_DIRECTION tmpDir;
bool hasFVG = poiDetector.HasFVG(
pBar,
tmpDir,
_fvg //
);
//
isBullish =
isBullish &&
hasFVG &&
IsXBullish(tmpDir);
//
isBearish =
isBearish &&
hasFVG &&
IsXBearish(tmpDir);
//
// Summarize Result ...
result = isBullish || isBearish;
}
//
// Prepare Direction and Zone ...
if (result)
{
//
if (isBullish)
{
//
zone = _resistance;
zone.dir = Opposit(_resistance.dir);
dir = zone.dir;
zone.upper = MathMax(zone.upper, _fvg.upper);
zone.lower = MathMin(zone.lower, _fvg.lower);
}
//
if (isBearish)
{
//
zone = _support;
zone.dir = Opposit(_support.dir);
dir = zone.dir;
zone.upper = MathMax(zone.upper, _fvg.upper);
zone.lower = MathMin(zone.lower, _fvg.lower);
}
//
// Zone Validation Base ...
result = zone.IsValid();
if (result)
{
//
// Validate By Trend of Zone ...
XTrend zoneTrend;
XTrend zoneToTrend;
//
// Detecting Trends ...
result = poiDetector.HasBoundaryTrend(zone, zoneTrend, false);
result = result &&
poiDetector.HasBoundaryTrend(zone, zoneToTrend, true);
//
// Validate Trend ...
result =
result &&
zone.dir == zoneTrend.dir &&
zone.dir == zoneToTrend.dir;
//
// Draw ...
if (result)
{
// //
// XPOIDrawConfig iConfig = structureDrawConfig.drawConfig;
// iConfig.trendRayLeft = false;
// iConfig.trendRayRight = false;
// //
// poiDrawer.DrawTrendLine(zoneTrend, iConfig);
// poiDrawer.DrawTrendLine(zoneToTrend, iConfig);
// //
// iConfig.Clean();
}
//
// Cleanup ...
zoneTrend.Clean();
zoneToTrend.Clean();
//
// Reset Flags ...
if (!result)
{
//
zone.Clean();
isBullish = false;
isBearish = false;
}
}
//
result = zone.IsValid();
}
//
if (result)
{
//
if (_support.IsValid())
{
poiDrawer.DrawZone(_support, structureDrawConfig.drawConfig);
}
//
if (_resistance.IsValid())
{
poiDrawer.DrawZone(_resistance, structureDrawConfig.drawConfig);
}
//
if (pBarPatterns.IsValid())
{
poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
}
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
pBarPatterns.Clean();
p2BarPatterns.Clean();
patternConfig.Clean();
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 4 ...
*
* Strategy 4:
* ===========
* - Works Based on Order Flow ...
* - Looking for new and Fresh Order Flow ...
* - Validate Bar is Inside Order Flow ...
* - Validate Bar has Proper Pattern ...
* - Validate Bar Based on ATR Band in two Step:
* - Step 1: Bars is Inside ATR Band (Middle) ...
* - Step 2: Trigger Bars Close Price based on ATR Band ...
* - Validate Order Flow based on Market Structure Zone ...
* - Validate Trigger Bar based on InDirectional Market Structure Zones ...
*
* Manipulations:
* ================
* there are Some Flags properties to Change Validations in Strategy ...
* we can use them for Testing Purposes ...
*
* @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 ...
*
* @return ( bool )
*/
bool Strategy4HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Validation Flags ...
bool validateBarInsideZone = true;
bool validateByBarPatterns = true;
bool validateByXFIMABoundary = true;
bool validateByBarInsideATRBand = true;
bool validateByBarBasedOnATRBand = true;
bool validateByXFIMABoundaryTrend = true;
bool validateMarketStructureHasDirectionalZone = true;
bool validateMarketStructureDirectionalZoneInsideOrderFlow = true;
bool validateMarketStructureHasNotInDirectionalZoneOrUnReachedTP = true;
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
result = result &&
p2Bar.GetPreviousBar(p3Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
//
return result;
}
//
// Do ...
//
// Retrieve pBar Patterns ...
XPatternAnalysis pBarPatterns;
XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig;
//
poiDetector.AnalyseBarPatterns(
pBar,
pBarPatterns,
patternConfig //
);
//
// Detecting OrderFlow ...
XBoxZone oFlow[];
bool hasOrderFlow = poiDetector.HasOrderFlow(
p3Bar,
dir,
oFlow,
structureConfig.orderFlowValidation,
structureConfig.orderFlowUseOB,
structureConfig.orderFlowUseFVG,
structureConfig.orderFlowUseSupportAndResistance,
patternConfig.supportAndResistanceLoopbackLength,
patternConfig.supportAndResistanceValidationLength,
structureConfig.loopback //
);
//
XTrend boundaryTrend;
XTrend boundaryZoneTrend;
//
double atrBandUpper = EMPTY_VALUE;
double atrBandLower = EMPTY_VALUE;
double atrBandMiddle = EMPTY_VALUE;
//
isBullish = hasOrderFlow &&
IsXBullish(dir);
//
isBearish = hasOrderFlow &&
IsXBearish(dir);
//
// Summarize Result ...
result = isBullish || isBearish;
//
// Force Price of p2Bar is Inside Order Flow ...
if (result && validateBarInsideZone)
{
//
double orderFlowUpper = 0;
double orderFlowLower = 0;
//
int idx = -1;
idx = GetHighest(oFlow);
if (IsValidIndex(idx))
{
orderFlowUpper = oFlow[idx].upper;
}
idx = GetLowest(oFlow);
if (IsValidIndex(idx))
{
orderFlowLower = oFlow[idx].lower;
}
//
result = NotEmptyZero(orderFlowUpper) &&
NotEmptyZero(orderFlowLower) &&
orderFlowUpper > orderFlowLower &&
(isBullish
? p2Bar.low < orderFlowUpper
: p2Bar.high > orderFlowLower);
//
// Reset Flags ...
if (!result)
{
//
isBullish = false;
isBearish = false;
}
}
//
// Force PBar Has Pattern ...
if (result && validateByBarPatterns)
{
//
// Analyse Bar Patterns ...
result = pBarPatterns.IsValid();
//
// Bullish ...
bool isPBarHasBullishPatterns =
result &&
// (bar.close > pBar.low ||
// bar.open > pBar.low) &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
//
);
//
// Bearish ...
bool isPBarHasBearishPatterns =
result &&
// (bar.close < pBar.high ||
// bar.open < pBar.high) &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
isBullish =
isBullish &&
isPBarHasBullishPatterns &&
!isPBarHasBearishPatterns;
//
isBearish =
isBearish &&
isPBarHasBearishPatterns &&
!isPBarHasBullishPatterns;
//
// Summarize Result ...
result = isBullish || isBearish;
//
// Reset Flags ...
if (!result)
{
//
isBullish = false;
isBearish = false;
}
}
//
// Force P2Bar Place Checking based on ATR Band ...
if (result && validateByBarInsideATRBand)
{
//
atrBandUpper = fimaHelper.GetATRBandUpper(p2Bar.Index());
atrBandLower = fimaHelper.GetATRBandLower(p2Bar.Index());
//
atrBandMiddle = atrBandLower + ((atrBandUpper - atrBandLower) / 2);
//
isBullish =
isBullish &&
NotEmptyZero(atrBandMiddle) &&
p2Bar.low < atrBandMiddle;
//
isBearish =
isBearish &&
NotEmptyZero(atrBandMiddle) &&
p2Bar.high > atrBandMiddle;
//
// Summarize Result ...
result = isBullish || isBearish;
//
// Reset Flags ...
if (!result)
{
//
isBullish = false;
isBearish = false;
}
}
//
// Force PBar Place Checking based on ATR Band ...
if (result && validateByBarBasedOnATRBand)
{
//
atrBandUpper = fimaHelper.GetATRBandUpper(pBar.Index());
atrBandLower = fimaHelper.GetATRBandLower(pBar.Index());
//
result =
NotEmptyZero(atrBandUpper) &&
NotEmptyZero(atrBandLower) &&
(isBullish
? pBar.close > atrBandLower
: pBar.close < atrBandUpper);
//
// Reset Flags ...
if (!result)
{
//
isBullish = false;
isBearish = false;
}
}
//
// for Bullish has Support ...
// for Bearish has Resistance ...
if (result && validateMarketStructureHasDirectionalZone)
{
//
XOHCL tmpBar;
XPivot tmpPivot;
XBoxZone _support;
XBoxZone _resistance;
//
// Check Market Strucutre Has Support / Resistance ...
bool hasSupport = pBarPatterns.IsSupport();
bool hasResistance = pBarPatterns.IsResistance();
//
// Retrieve Support / Resistance Zone ...
if (hasSupport)
{
pBarPatterns.GetSupport(tmpBar, tmpPivot, _support);
}
if (hasResistance)
{
pBarPatterns.GetResistance(tmpBar, tmpPivot, _resistance);
}
//
// Validate Support and Resistance by Order Flow ...
//
// Converts Order Flow to Zone ...
XBoxZone ofZone;
bool hasOFBox = ToBox(ofZone, oFlow);
//
// Check Market Strucutre Support and Resistance Validation ...
if (validateMarketStructureDirectionalZoneInsideOrderFlow)
{
//
hasSupport =
hasOFBox &&
hasSupport &&
ofZone.lower < _support.lower &&
ofZone.upper > _support.upper;
//
hasResistance =
hasOFBox &&
hasResistance &&
ofZone.lower < _resistance.lower &&
ofZone.upper > _resistance.upper;
}
//
// Validate Directional Support or Resistance Exists ...
//
isBullish =
isBullish &&
hasSupport;
//
isBearish =
isBearish &&
hasResistance;
//
// Cleanup ...
ofZone.Clean();
tmpBar.Clean();
_support.Clean();
tmpPivot.Clean();
_resistance.Clean();
//
// Summarize Result ...
result = isBullish || isBearish;
}
//
// Validate Makret Structure Has Not Indirectional Zone ...
if (result && validateMarketStructureHasNotInDirectionalZoneOrUnReachedTP)
{
//
XOHCL tmpBar;
XPivot tmpPivot;
XBoxZone _support;
XBoxZone _resistance;
//
// Check Market Strucutre Has Support / Resistance ...
bool hasSupport = pBarPatterns.IsSupport();
bool hasResistance = pBarPatterns.IsResistance();
//
// Retrieve Support / Resistance Zone ...
if (hasSupport)
{
pBarPatterns.GetSupport(tmpBar, tmpPivot, _support);
}
if (hasResistance)
{
pBarPatterns.GetResistance(tmpBar, tmpPivot, _resistance);
}
//
// Converts Order Flow to Zone ...
XBoxZone ofZone;
bool hasOFBox = ToBox(ofZone, oFlow);
//
bool hasIndirectionalZone =
(isBullish && hasResistance) ||
(isBearish && hasSupport);
if (hasIndirectionalZone)
{
//
// Here we Have to Validate Zone Place ...
//
double point = GetPoints(bar.symbol);
double entry = GetEntry(bar.symbol, dir);
double slAddition = slAdditionDistance > 0 ? slAdditionDistance : 0;
double risk = MathAbs(entry - (isBullish ? oFlow[0].lower : oFlow[0].upper)) + (slAddition * point);
double reward = (defaultSignalR2R * risk);
double tp = isBullish
? entry + reward
: entry - reward;
//
// Bullish ...
if (isBullish && hasResistance)
{
hasResistance = _resistance.lower <= tp;
}
//
// Bearish ...
if (isBearish && hasSupport)
{
hasSupport = _support.upper >= tp;
}
}
//
isBullish =
isBullish &&
!hasResistance;
//
isBearish =
isBearish &&
!hasSupport;
//
// Cleanup ...
ofZone.Clean();
tmpBar.Clean();
_support.Clean();
tmpPivot.Clean();
_resistance.Clean();
//
// Summarize Result ...
result = isBullish || isBearish;
}
//
// Validate ...
result = isBullish || isBearish;
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone and do Zone Based Validations ...
if (result)
{
//
zone.Clean();
result = ToBox(
p2Bar,
zone,
dir,
X_BAR_PATTERN_PINNED //
);
//
// Refine Zone ...
zone.to = bar.time;
zone.upper = MathMax(zone.upper, atrBandMiddle);
zone.lower = MathMin(zone.lower, atrBandMiddle);
//
// Validate by XFIMA Boundary ...
if (result && validateByXFIMABoundary)
{
//
// Try to Retrieve Boundary To Trend ...
result = poiDetector.HasBoundaryTrend(
zone,
boundaryTrend,
true //
);
//
// Try to Retrieve Boundary Zone Trend ...
result =
result &&
poiDetector.HasBoundaryTrend(
zone,
boundaryZoneTrend,
false //
);
//
// Check and Validate Trend Direction ...
result =
result &&
zone.dir == boundaryTrend.dir &&
zone.dir == boundaryZoneTrend.dir;
//
// Reset Flags ...
if (!result)
{
//
zone.Clean();
result = false;
isBullish = false;
isBearish = false;
}
}
//
// Manage Stops ...
if (result)
{
//
// Since Stop Management Changes Zones Edge(s) ...
// we do it here for Refining Zone ...
}
//
result = zone.IsValid();
}
//
// Prepare Targets ...
if (result)
{
//
XTarget iTarget;
//
// Calculate Requirements ...
double point = GetPoints(bar.symbol);
double entry = GetEntry(bar.symbol, dir);
double slAddition = slAdditionDistance > 0 ? slAdditionDistance : 0;
double risk = MathAbs(entry - (isBullish ? zone.lower : zone.upper)) + (slAddition * point);
double reward = (defaultSignalR2R * risk);
double tp = isBullish
? entry + reward
: entry - reward;
//
// High Risk Target is Used to Protect In Profit Positiions
// from Reversal Patterns ...
double highRiskR2r = (defaultSignalR2R / 5) * 4;
double highRiskReward = highRiskR2r * risk;
double highRiskTP = isBullish
? entry + highRiskReward
: entry - highRiskReward;
iTarget.Clean();
iTarget.actingDistance = 5;
iTarget.doRFOnEntry = true;
iTarget.target = highRiskTP;
iTarget.volumeMultiplier = 0.8;
// AddRef(iTarget, targets);
//
// Cleanup ...
iTarget.Clean();
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
XClean(oFlow);
pBarPatterns.Clean();
boundaryTrend.Clean();
patternConfig.Clean();
boundaryZoneTrend.Clean();
//
return result;
}
//
};
//