Files
MQL5Data/XCAEA/Libraries/xcaea.signaller.lib.mq5
T
2025-05-13 16:32:44 +03:30

3329 lines
68 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: XCAEASignaller Lib
// Description: Library for XCAEA Signaller ...
//
//
// 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 Library for XCAEA Signaller"
#property strict
//
// Imports ...
#include "../../Libraries/x-saherelm.common.lib.mq5"
#include "../../Libraries/x-saherelm.x-poi.lib.mq5"
#include "../../Libraries/x-saherelm.x-trade.lib.mq5"
#include "../Classes/xcaea.x-poi.detector.class.mq5"
#include "../Classes/xcaea.x-poi.drawer.class.mq5"
#include "../Helpers/xcaea.helper.mq5"
//
// Enumeration ...
//
// Guard Actions ...
enum ENUM_GUARD_ACTIONS
{
X_GUARD_ACTION_NONE, // Nothing to Do
X_GUARD_ACTION_CLOSE, // Close Specified Position
X_GUARD_ACTION_CLOSE_ALL, // Close All Positions
X_GUARD_ACTION_CLOSE_LONGS, // Close All Long Positions
X_GUARD_ACTION_CLOSE_SHORTS, // Close All Short Position
X_GUARD_ACTION_PARTIAL_CLOSE, // Partial Close Specified Position
X_GUARD_ACTION_TRAIL_STOP, // Trail Stop of Specified Position
X_GUARD_ACTION_TRAIL_TARGET, // Trail Target of Specified Position
X_GUARD_ACTION_HEDGE, // Hedge Specified Positions
};
//
// Definitions ...
//
// Conditions Struct ...
struct XCAEAStrategyConditions
{
//
// Props ...
//
string symbol;
ENUM_TIMEFRAMES period;
//
// Setup Props ...
//
double sl;
double tp;
double pivot;
double point;
double entry;
double reward;
string provider;
double targets[];
//
datetime time;
datetime setupTime;
datetime triggerTime;
//
double partialCloseOnTPLevel;
double partialCloseMultiplier;
//
ENUM_X_DIRECTION dir;
XBoxZone decisionZone;
ENUM_X_POSITION_TYPES type;
XCAEAConditions conditions;
//
// Constructor ...
XCAEAStrategyConditions()
{
Clean();
}
//
// Tools ...
/**
* Cleaning Up ...
*/
void Clean()
{
//
sl = 0;
tp = 0;
pivot = 0;
point = 0;
entry = 0;
reward = 0;
//
symbol = NULL;
period = NULL;
provider = NULL;
//
time = NULL;
setupTime = NULL;
triggerTime = NULL;
//
partialCloseOnTPLevel = 0;
partialCloseMultiplier = 0;
//
Clean(targets);
//
conditions.Clean();
decisionZone.Clean();
//
dir = X_DIRECTION_NONE;
type = X_POSITION_TYPE_NONE;
//
ZeroMemory(this);
}
//
// Signalling ...
/**
* Validate ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result = IsSpecifiedValid(symbol) &&
IsSpecifiedValid(period) &&
IsSpecifiedValid(time);
//
return result;
}
/**
* Check Conditions Has Valid Bullish Signal ...
*
* @return ( bool )
*/
bool HasBullishSignal()
{
//
bool result = false;
//
result =
(sl > 0 ||
tp > 0) &&
IsValid() &&
HasDirection(dir);
if (!result)
{
return result;
}
//
result =
IsBullish(dir);
//
return result;
}
/**
* Check Conditions Has Valid Bearish Signal ...
*
* @return ( bool )
*/
bool HasBearishSignal()
{
//
bool result = false;
//
result =
(sl > 0 ||
tp > 0) &&
IsValid() &&
HasDirection(dir);
if (!result)
{
return result;
}
//
result =
IsBearish(dir);
//
return result;
}
//
// Setting Up and Triggering Up ...
/**
* Check Condition is Setting Up ...
*
* @param dir: ENUM_X_DIRECTION member, Setting Up Direction ...
*
* @return ( bool )
*/
bool IsSetuped()
{
//
bool result = false;
//
result = IsValid(setupTime) &&
HasDirection(dir);
if (!result)
{
return result;
}
//
return result;
}
/**
* Calculate Setup Age ...
*
* @return ( int )
*/
int GetSetupAge()
{
//
int result = 0;
//
if (!IsSetuped())
{
return result;
}
//
result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period);
//
return result;
}
/**
* Detect How we Can Trigger Signal ...
*
* @return ( bool )
*/
bool CanTrigger()
{
//
bool result = false;
//
result =
//
sl > 0 &&
IsValid(symbol) &&
IsValid(period) &&
IsValid(triggerTime) &&
type != X_POSITION_TYPE_ALL &&
type != X_POSITION_TYPE_NONE
//
;
//
return result;
}
//
};
//
// Model a Guard Action ...
struct XCAEAGuard
{
//
// Props ...
ENUM_GUARD_ACTIONS action;
datetime time;
//
string symbol;
string provider;
//
// Specified Position ...
ulong ticket;
//
// Partial Close ...
double volumeMultiplier;
//
// SL Trial ...
double sl;
//
// TP Trial ...
double tp;
//
// Constructor ...
XCAEAGuard()
{
Clean();
}
//
// Tools ...
/**
* Cleanup ...
*/
void Clean()
{
//
time = NULL;
action = X_GUARD_ACTION_NONE;
//
symbol = NULL;
provider = NULL;
//
ticket = 0;
//
volumeMultiplier = 0;
//
sl = 0;
tp = 0;
//
ZeroMemory(this);
}
/**
* Validate ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
//
IsValid(time) &&
IsValid(symbol) &&
IsValid(provider) &&
action != X_GUARD_ACTION_NONE
//
;
if (!result)
{
return result;
}
//
// Validate Model Based On Specified Guard Actions ...
//
return result;
}
};
/**
* Add Guard to Collection ...
*
* @param guard: XCAEAGuard instance ...
* @param guards: XCAEAGuard instance Collection ...
*
* @return ( int )
*/
int AddGuard(
XCAEAGuard &guard,
XCAEAGuard &guards[] //
)
{
//
int result = 0;
//
if (!guard.IsValid())
{
return result;
}
//
AddRef(
guard,
guards //
);
//
result = ArraySize(guards);
//
return result;
}
//
enum ENUM_XCAEA_LQ_TYPES
{
XCAEA_LQ_TYPE_NONE = 0,
XCAEA_LQ_TYPE_PEAK = 1,
XCAEA_LQ_TYPE_VALE = 2,
};
struct XCAEALQSweep
{
//
// Props ...
int length;
datetime to;
string symbol;
datetime from;
double sweeped;
double reverse;
ENUM_TIMEFRAMES period;
ENUM_XCAEA_LQ_TYPES type;
//
// Constructor ...
XCAEALQSweep()
{
Clean();
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
to = NULL;
length = 0;
from = NULL;
sweeped = 0;
reverse = 0;
symbol = NULL;
period = NULL;
type = XCAEA_LQ_TYPE_NONE;
}
//
// Validation ...
bool IsValid()
{
//
bool result = false;
//
result =
//
length > 0 &&
IsValid(to) &&
sweeped > 0 &&
reverse > 0 &&
IsValid(from) &&
IsValid(symbol) &&
IsValid(period) &&
type != XCAEA_LQ_TYPE_NONE
//
;
//
return result;
}
//
string GetTag()
{
//
string result = NULL;
//
if (!IsValid())
{
return result;
}
//
result = symbol +
ToString(period) +
"XLQ" +
(type == XCAEA_LQ_TYPE_PEAK ? "Peak" : "Vale") +
ToString(sweeped);
//
return result;
}
};
//
// Tools ...
//
// Detect Decision Zone ...
bool DetectDecisionZone(
XCXCAEAHelper *helper,
XCXCAEAPOIDrawer *drawer,
XBoxZone &box,
ENUM_X_DIRECTION &dir,
XBoxZone &unavailables[],
XCAEAConditions &conditions,
int barIndex = 0,
int loopback = 10 //
)
{
//
bool result = false;
//
int idx = -1;
int count = 0;
bool has = false;
//
box.Clean();
conditions.Clean();
dir = X_DIRECTION_NONE;
barIndex = NormalizeInt(barIndex, 0);
loopback = NormalizeInt(loopback, 5);
//
// Retrieve Some Requirements ...
string symbol = helper.GetSymbol();
ENUM_TIMEFRAMES period = helper.GetPeriod();
double points = GetPoints(symbol);
//
// Retrieve Conditions for Processing ...
result = helper.GetConditions(
conditions,
barIndex,
loopback //
);
if (!result)
{
//
box.Clean();
conditions.Clean();
//
return result;
}
//
// Define IDXses ...
int zIDX = barIndex;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
int p2IDX = pIDX + 1;
int p3IDX = p2IDX + 1;
int p4IDX = p3IDX + 1;
//
XOHCL zBar;
XOHCL cBar;
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
XOHCL p4Bar;
result = zBar.Init(
symbol,
period,
zIDX //
);
result =
result &&
zBar.GetPreviousBar(cBar);
result =
result &&
cBar.GetPreviousBar(pBar);
result =
result &&
pBar.GetPreviousBar(p2Bar);
result =
result &&
p2Bar.GetPreviousBar(p3Bar);
result =
result &&
p3Bar.GetPreviousBar(p4Bar);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
box.Clean();
conditions.Clean();
//
return result;
}
//
// Bars Conditions ...
//
// Score ...
//
double bullishScore = 0;
double bearishScore = 0;
conditions.GenerateScore(
bullishScore,
bearishScore //
);
//
bool isScoreBullish =
bullishScore > bearishScore;
//
bool isScoreBearish =
bearishScore > bullishScore;
//
bool isScoreNeutural = MathAbs(bullishScore - bearishScore) == 0;
//
// Calculating Range Volumes ...
//
double bullishVolume = 0;
double bearishVolume = 0;
helper.barAnalyser.CalculateRangeVolume(
cBar,
bullishVolume,
bearishVolume,
loopback //
);
//
bool isVolumeNeutural = MathAbs(bullishVolume - bearishVolume) == 0;
//
// Checking OB ...
XBoxZone ob;
bool isOB = helper
.barAnalyser
.IsOB(
cBar,
ob,
false, // Force FVG Bar Type
true // Force Two Bar Start ...
);
bool isBullishOB =
isOB &&
ob.IsBullish();
bool isBearishOB =
isOB &&
ob.IsBearish();
//
// Reading Values ...
//
// SAR ...
double zSar = conditions.sarBuffer[zIDX];
double cSar = conditions.sarBuffer[cIDX];
double pSar = conditions.sarBuffer[pIDX];
double p2Sar = conditions.sarBuffer[p2IDX];
double p3Sar = conditions.sarBuffer[p3IDX];
//
// PEAK ...
double zPeak = conditions.peakBuffer[zIDX];
double cPeak = conditions.peakBuffer[cIDX];
double pPeak = conditions.peakBuffer[pIDX];
double p2Peak = conditions.peakBuffer[p2IDX];
double p3Peak = conditions.peakBuffer[p3IDX];
double p4Peak = conditions.peakBuffer[p4IDX];
//
// VALE ...
double zVale = conditions.valeBuffer[zIDX];
double cVale = conditions.valeBuffer[cIDX];
double pVale = conditions.valeBuffer[pIDX];
double p2Vale = conditions.valeBuffer[p2IDX];
double p3Vale = conditions.valeBuffer[p3IDX];
double p4Vale = conditions.valeBuffer[p4IDX];
//
// SWING Low ...
double zSWL = conditions.swingLowBuffer[zIDX];
double cSWL = conditions.swingLowBuffer[cIDX];
double pSWL = conditions.swingLowBuffer[pIDX];
double p2SWL = conditions.swingLowBuffer[p2IDX];
double p3SWL = conditions.swingLowBuffer[p3IDX];
//
// SWING High ...
double zSWH = conditions.swingHighBuffer[zIDX];
double cSWH = conditions.swingHighBuffer[cIDX];
double pSWH = conditions.swingHighBuffer[pIDX];
double p2SWH = conditions.swingHighBuffer[p2IDX];
double p3SWH = conditions.swingHighBuffer[p3IDX];
//
// SUPPORT ...
double zSupport = conditions.supportBuffer[zIDX];
double cSupport = conditions.supportBuffer[cIDX];
double pSupport = conditions.supportBuffer[pIDX];
double p2Support = conditions.supportBuffer[p2IDX];
double p3Support = conditions.supportBuffer[p3IDX];
//
// RESISTANCE ...
double zResistance = conditions.resistanceBuffer[zIDX];
double cResistance = conditions.resistanceBuffer[cIDX];
double pResistance = conditions.resistanceBuffer[pIDX];
double p2Resistance = conditions.resistanceBuffer[p2IDX];
double p3Resistance = conditions.resistanceBuffer[p3IDX];
//
// MAH ...
double zMAH = conditions.mahBuffer[zIDX];
double cMAH = conditions.mahBuffer[cIDX];
double pMAH = conditions.mahBuffer[pIDX];
double p2MAH = conditions.mahBuffer[p2IDX];
double p3MAH = conditions.mahBuffer[p3IDX];
//
// MAL ...
double zMAL = conditions.malBuffer[zIDX];
double cMAL = conditions.malBuffer[cIDX];
double pMAL = conditions.malBuffer[pIDX];
double p2MAL = conditions.malBuffer[p2IDX];
double p3MAL = conditions.malBuffer[p3IDX];
//
// MAC ...
double zMAC = conditions.macBuffer[zIDX];
double cMAC = conditions.macBuffer[cIDX];
double pMAC = conditions.macBuffer[pIDX];
double p2MAC = conditions.macBuffer[p2IDX];
double p3MAC = conditions.macBuffer[p3IDX];
//
// FIBO Level 1 ...
double zFib1 = conditions.fiboLevel1Buffer[zIDX];
double cFib1 = conditions.fiboLevel1Buffer[cIDX];
double pFib1 = conditions.fiboLevel1Buffer[pIDX];
double p2Fib1 = conditions.fiboLevel1Buffer[p2IDX];
double p3Fib1 = conditions.fiboLevel1Buffer[p3IDX];
//
// FIBO Level 2 ...
double zFib2 = conditions.fiboLevel2Buffer[zIDX];
double cFib2 = conditions.fiboLevel2Buffer[cIDX];
double pFib2 = conditions.fiboLevel2Buffer[pIDX];
double p2Fib2 = conditions.fiboLevel2Buffer[p2IDX];
double p3Fib2 = conditions.fiboLevel2Buffer[p3IDX];
//
// FIBO Level 3 ...
double zFib3 = conditions.fiboLevel3Buffer[zIDX];
double cFib3 = conditions.fiboLevel3Buffer[cIDX];
double pFib3 = conditions.fiboLevel3Buffer[pIDX];
double p2Fib3 = conditions.fiboLevel3Buffer[p2IDX];
double p3Fib3 = conditions.fiboLevel3Buffer[p3IDX];
//
// FIBO Level 4 ...
double zFib4 = conditions.fiboLevel4Buffer[zIDX];
double cFib4 = conditions.fiboLevel4Buffer[cIDX];
double pFib4 = conditions.fiboLevel4Buffer[pIDX];
double p2Fib4 = conditions.fiboLevel4Buffer[p2IDX];
double p3Fib4 = conditions.fiboLevel4Buffer[p3IDX];
//
// FIBO Level 5 ...
double zFib5 = conditions.fiboLevel5Buffer[zIDX];
double cFib5 = conditions.fiboLevel5Buffer[cIDX];
double pFib5 = conditions.fiboLevel5Buffer[pIDX];
double p2Fib5 = conditions.fiboLevel5Buffer[p2IDX];
double p3Fib5 = conditions.fiboLevel5Buffer[p3IDX];
//
// FAST ...
double zFast = conditions.fastBuffer[zIDX];
double cFast = conditions.fastBuffer[cIDX];
double pFast = conditions.fastBuffer[pIDX];
double p2Fast = conditions.fastBuffer[p2IDX];
double p3Fast = conditions.fastBuffer[p3IDX];
//
// FAST State ...
double zFastState = conditions.fastStateBuffer[zIDX];
double cFastState = conditions.fastStateBuffer[cIDX];
double pFastState = conditions.fastStateBuffer[pIDX];
double p2FastState = conditions.fastStateBuffer[p2IDX];
double p3FastState = conditions.fastStateBuffer[p3IDX];
//
// RSI ...
double zRSI = conditions.rsiBuffer[zIDX];
double cRSI = conditions.rsiBuffer[cIDX];
double pRSI = conditions.rsiBuffer[pIDX];
double p2RSI = conditions.rsiBuffer[p2IDX];
double p3RSI = conditions.rsiBuffer[p3IDX];
//
// Create Custom Conditions ...
//
// Bar and Fibo Conditions ...
//
// Bearish ...
//
// Strong Reversal ...
bool isZBarOnFiboStrongBearish = zBar.low > zFib5;
bool isCBarOnFiboStrongBearish = cBar.low > cFib5;
bool isPBarOnFiboStrongBearish = pBar.low > pFib5;
bool isP2BarOnFiboStrongBearish = p2Bar.low > p2Fib5;
bool isP3BarOnFiboStrongBearish = p3Bar.low > p3Fib5;
//
// Golden Zone Reversal ...
bool isZBarOnFiboGoldenBearish = zBar.low > zFib3 &&
zBar.high < zFib4;
bool isCBarOnFiboGoldenBearish = cBar.low > cFib3 &&
cBar.high < cFib4;
bool isPBarOnFiboGoldenBearish = pBar.low > pFib3 &&
pBar.high < pFib4;
bool isP2BarOnFiboGoldenBearish = p2Bar.low > p2Fib3 &&
p2Bar.high < p2Fib4;
bool isP3BarOnFiboGoldenBearish = p3Bar.low > p3Fib3 &&
p3Bar.high < p3Fib4;
//
// Bullish ...
//
// Strong Reversal ...
bool isZBarOnFiboStrongBullish = zBar.high < zFib1;
bool isCBarOnFiboStrongBullish = cBar.high < cFib1;
bool isPBarOnFiboStrongBullish = pBar.high < pFib1;
bool isP2BarOnFiboStrongBullish = p2Bar.high < p2Fib1;
bool isP3BarOnFiboStrongBullish = p3Bar.high < p3Fib1;
//
// Golden Zone Reversal ...
bool isZBarOnFiboGoldenBullish = zBar.low > zFib2 &&
zBar.high < zFib3;
bool isCBarOnFiboGoldenBullish = cBar.low > cFib2 &&
cBar.high < cFib3;
bool isPBarOnFiboGoldenBullish = pBar.low > pFib2 &&
pBar.high < pFib3;
bool isP2BarOnFiboGoldenBullish = p2Bar.low > p2Fib2 &&
p2Bar.high < p2Fib3;
bool isP3BarOnFiboGoldenBullish = p3Bar.low > p3Fib2 &&
p3Bar.high < p3Fib3;
//
// Score and Volume Conditions ...
//
bool isScoreVolumeNeutural = isScoreNeutural ||
isVolumeNeutural;
//
bool isScoreVolumeNeuturalInFiboStrongBullish =
isScoreNeutural &&
isCBarOnFiboStrongBullish;
//
bool isScoreVolumeNeuturalInFiboGoldenBullish =
isScoreNeutural &&
isCBarOnFiboGoldenBullish;
//
bool isScoreVolumeNeuturalInFiboStrongBearish =
isScoreNeutural &&
isCBarOnFiboStrongBearish;
//
bool isScoreVolumeNeuturalInFiboGoldenBearish =
isScoreNeutural &&
isCBarOnFiboGoldenBearish;
//
bool isScoreVolumeNeuturalBullishPowered =
isScoreVolumeNeuturalInFiboStrongBullish ||
isScoreVolumeNeuturalInFiboGoldenBullish;
//
bool isScoreVolumeNeuturalBearishPowered =
isScoreVolumeNeuturalInFiboStrongBearish ||
isScoreVolumeNeuturalInFiboGoldenBearish;
//
// PEAK and VALES ...
//
// PEAK Pivot ...
bool isZIsPeakPivot =
zPeak == cPeak &&
zPeak == zSWH &&
zPeak == zResistance &&
isZBarOnFiboStrongBearish;
bool isCIsPeakPivot =
cPeak == pPeak &&
cPeak == cSWH &&
cPeak == cResistance &&
isCBarOnFiboStrongBearish;
bool isPIsPeakPivot =
pPeak == p2Peak &&
pPeak == pSWH &&
pPeak == pResistance &&
isPBarOnFiboStrongBearish;
bool isP2IsPeakPivot =
p2Peak == p3Peak &&
p2Peak == p2SWH &&
p2Peak == p2Resistance &&
isP2BarOnFiboStrongBearish;
bool isP3IsPeakPivot =
p3Peak == p4Peak &&
p3Peak == p3SWH &&
p3Peak == p3Resistance &&
isP3BarOnFiboStrongBearish;
//
// VALE Pivot ...
bool isZIsValePivot =
zVale == cVale &&
zVale == zSWL &&
zVale == zSupport &&
isZBarOnFiboStrongBullish;
bool isCIsValePivot =
cVale == pVale &&
cVale == cSWL &&
cVale == cSupport &&
isCBarOnFiboStrongBullish;
bool isPIsValePivot =
pVale == p2Vale &&
pVale == pSWL &&
pVale == pSupport &&
isPBarOnFiboStrongBullish;
bool isP2IsValePivot =
p2Vale == p3Vale &&
p2Vale == p2SWL &&
p2Vale == p2Support &&
isP2BarOnFiboStrongBullish;
bool isP3IsValePivot =
p3Vale == p4Vale &&
p3Vale == p3SWL &&
p3Vale == p3Support &&
isP3BarOnFiboStrongBullish;
//
// FIBO Section Change Detection ...
bool isFiboSectionChanged =
//
(cFib1 != pFib1 &&
cFib2 != pFib2 &&
cFib3 != pFib3 &&
cFib4 != pFib4 &&
cFib5 != pFib5)
//
&&
//
(conditions.isPeakUnderLast ||
conditions.isValeOverLast ||
conditions.isSwingLowOverLast ||
conditions.isSwingHighUnderLast)
//
;
//
// SAR Change ...
//
bool isSarSwitchedInFiboStrongBullish =
isCBarOnFiboStrongBullish &&
conditions.isSarSwitchedToBullish;
//
bool isSarSwitchedInFiboGoldenBullish =
isCBarOnFiboGoldenBullish &&
conditions.isSarSwitchedToBullish;
//
bool isSarSwitchedInFiboStrongBearish =
isCBarOnFiboStrongBearish &&
conditions.isSarSwitchedToBearish;
//
bool isSarSwitchedInFiboGoldenBearish =
isCBarOnFiboGoldenBearish &&
conditions.isSarSwitchedToBearish;
//
bool isSarSwitchedToBullish =
cFastState > 0 &&
isSarSwitchedInFiboStrongBullish;
//
bool isSarSwitchedToBearish =
cFastState < 0 &&
isSarSwitchedInFiboStrongBearish;
//
// RSI Conditions ...
//
bool isRSICrossedOverOS =
p3RSI < conditions.rsiOSLevel &&
cRSI > conditions.rsiOSLevel;
//
bool isRSICrossedUnderOB =
p3RSI > conditions.rsiOBLevel &&
cRSI < conditions.rsiOBLevel;
//
// Custom Senarios ...
//
bool isCond1Bullish =
//
isBullishOB
//
;
//
bool isCond1Bearish =
//
isBearishOB
//
;
//
bool isCond1 =
isCond1Bullish ||
isCond1Bearish;
if (isCond1)
{
//
ENUM_X_DIRECTION iCond1Dir =
isCond1Bullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
int timeOffset = (int)cBar.time;
string iName = ToString(iCond1Dir) + "_COND1_" + ToString(timeOffset);
color iColor = isCond1Bullish
? clrAqua
: clrMagenta;
ENUM_LINE_STYLE iStyle = STYLE_DOT;
//
CChartObjectVLine *iObj;
iObj = new CChartObjectVLine();
has = iObj.Create(
0,
iName,
0,
cBar.time //
);
if (has)
{
//
iObj.Color(iColor);
iObj.Style(iStyle);
}
//
// Create Signal Box Based on Cond1 ...
//
double upper =
isCond1Bullish
? cBar.FindHighest(5, MODE_HIGH)
: MathMax(cPeak, cSWH);
//
double lower =
isCond1Bullish
? MathMin(cVale, cSWL)
: cBar.FindLowest(5, MODE_LOW);
//
int toIDX = cBar.Index();
int fromIDX = cBar.Index() + 5;
//
datetime toTime = GetBarTime(
symbol,
period,
toIDX //
);
datetime fromTime = GetBarTime(
symbol,
period,
fromIDX //
);
//
XBoxZone iBox;
//
iBox.to = toTime;
iBox.upper = upper;
iBox.lower = lower;
iBox.type = "COND1";
iBox.symbol = symbol;
iBox.period = period;
iBox.dir = iCond1Dir;
iBox.from = fromTime;
//
has = iBox.IsValid();
if (has)
{
//
XCBoxObject *iObj;
has = helper
.poiDrawer
.DrawBox(
iBox,
iObj //
);
if (has)
{
}
}
//
box = iBox;
dir = iBox.dir;
//
iBox.Clean();
//
// Print("Conditions Finder ...");
}
//
// bool isCond2 = isFiboSectionChanged;
// if (isCond2)
// {
// //
// Print("Decision Zone Full Cond1");
// }
//
// Summarise Result ...
//
bool isBullish =
false ||
isCond1Bullish;
//
bool isBearish =
false ||
isCond1Bearish;
//
result = isBullish ||
isBearish;
if (result)
{
//
// Check UnAvailables ...
int idx = -1;
has = FindBoxIndex(
idx,
box,
unavailables //
);
if (has)
{
//
box.Clean();
conditions.Clean();
dir = X_DIRECTION_NONE;
}
//
// Check Box Size ...
double range = box.GetRange();
double maxAllowedBoxRange = 400;
double ponts = GetPoints(box.symbol);
bool isTooLarget = range > (maxAllowedBoxRange * points);
if (isTooLarget)
{
Print("Too Large ...");
}
//
// Check Box is Prepared or Not ...
result = box.IsValid();
}
//
// Cleaning Up ...
//
ob.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
if (!result)
{
//
box.Clean();
conditions.Clean();
dir = X_DIRECTION_NONE;
}
//
return result;
}
//
// Trigger Conditions ...
//
// Detect Trigger Based On Decision Zone's
// Volume and Score ...
bool CanTriggerCond0(
XCXCAEAHelper *helper,
XBoxZone &box,
ENUM_X_DIRECTION &dir,
double &sl,
double &tp,
CArrayObj *drawns,
int barIndex = 0,
int loopback = 5,
double scorePassMultiplier = 1 //
)
{
//
bool result = false;
//
// Normalize Args ...
sl = 0;
tp = 0;
dir = X_DIRECTION_NONE;
loopback = NormalizeInt(loopback, 5);
barIndex = NormalizeInt(barIndex, 0);
//
// Validate Decision Box ...
result = box.IsValid() &&
helper != NULL;
if (!result)
{
return result;
}
//
// Define Requirements ...
//
bool isBullish = box.IsBullish();
bool isBearish = box.IsBearish();
//
// Scores ...
double bullScores[];
double bearScores[];
//
// Volumes ...
double bullVolumes[];
double bearVolumes[];
//
// Create a Loop through Loopack ...
XOHCL iBar;
bool has = false;
int start = barIndex;
XCAEAConditions iConditions;
int end = barIndex + loopback;
for (int i = end; i >= start; i--)
{
//
// Retrieve Bar ...
has = iBar.Init(
box.symbol,
box.period,
i //
);
if (!has)
{
//
iBar.Clean();
iConditions.Clean();
//
continue;
}
//
// Retrieve Conditions ...
has = helper.GetConditions(
iConditions,
i //
);
if (!has)
{
//
iBar.Clean();
iConditions.Clean();
//
continue;
}
//
// Retrieve Scores ...
double iBullScore = 0;
double iBearScore = 0;
iConditions
.GenerateScore(
iBullScore,
iBearScore //
);
Add(
iBullScore,
bullScores //
);
Add(
iBearScore,
bearScores //
);
//
// Retrieve Volumes ...
double iBullVolume = 0;
double iBearVolume = 0;
helper
.barAnalyser
.CalculateRangeVolume(
iBar,
iBullVolume,
iBearVolume,
2 // Loopback ...
);
Add(
iBullVolume,
bullVolumes //
);
Add(
iBearVolume,
bearVolumes //
);
//
iBar.Clean();
iConditions.Clean();
}
//
// Calculating Requirements ...
//
// Scores ...
//
// Bullish ...
double bullScore = GetSum(bullScores);
double bullScoreMax = GetMax(bullScores);
double bullScoreMin = GetMin(bullScores);
//
// Bearish ...
double bearScore = GetSum(bearScores);
double bearScoreMax = GetMax(bearScores);
double bearScoreMin = GetMin(bearScores);
//
// Volumes ...
//
// Bullish ...
double bullVolume = GetSum(bullVolumes);
double bullVolumeMax = GetMax(bullVolumes);
double bullVolumeMin = GetMin(bullVolumes);
//
// Bearish ...
double bearVolume = GetSum(bearVolumes);
double bearVolumeMax = GetMax(bearVolumes);
double bearVolumeMin = GetMin(bearVolumes);
//
// Creating Result Conditions ...
//
bool isBullishPassed =
isBullish &&
bullScore >= (scorePassMultiplier * bearScore) &&
bullVolume >= (scorePassMultiplier * bearVolume);
//
bool isBearishPassed =
isBearish &&
bearScore >= (scorePassMultiplier * bullScore) &&
bearVolume >= (scorePassMultiplier * bullVolume);
//
result = isBullishPassed ||
isBearishPassed;
if (!result)
{
//
iBar.Clean();
Clean(bullScores);
Clean(bearScores);
Clean(bullVolumes);
Clean(bearVolumes);
iConditions.Clean();
//
return result;
}
//
// Validating Box to Find a Rejection ...
//
// Validating Box to Has a Gap ...
//
// Validating Box to Has a Block ...
//
bool isPassed =
isBullishPassed ||
isBearishPassed;
if (isPassed)
{
//
// Preparing TP and SL ...
//
sl = isBullishPassed
? box.lower
: box.upper;
//
tp = 0;
}
//
// Summarizing ...
//
bool canTriggerLong =
isBullishPassed;
//
bool canTriggerShort =
isBearishPassed;
//
result = canTriggerLong ||
canTriggerShort;
if (result)
{
//
dir = canTriggerLong
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
// Cleanup Resources ...
//
iBar.Clean();
Clean(bullScores);
Clean(bearScores);
Clean(bullVolumes);
Clean(bearVolumes);
iConditions.Clean();
//
return result;
}
//
// Detect Trigger Based On Decision Zone's
// Fake Breaked out ...
bool CanTriggerCond1(
XCXCAEAHelper *helper,
XBoxZone &box,
ENUM_X_DIRECTION &dir,
double &sl,
double &tp,
CArrayObj *drawns,
int barIndex = 0,
int loopback = 10 //
)
{
//
bool result = false;
//
// Normalize Args ...
sl = 0;
tp = 0;
dir = X_DIRECTION_NONE;
loopback = NormalizeInt(loopback, 5);
barIndex = NormalizeInt(barIndex, 0);
//
// Validate Decision Box ...
result = box.IsValid() &&
helper != NULL;
if (!result)
{
return result;
}
//
// Check Box is Faked Breaked Out ...
//
XBoxZone validatorFVG;
//
bool isBullishFakedBreakedOut = IsBoxFakedBreakout(
helper,
box,
validatorFVG,
X_DIRECTION_BULLISH,
barIndex,
100, // Loopback For FVG ...
true, // Force FVg Validation ...
true // Force FVG Bar Type ...
);
//
bool isBearishFakedBreakedOut = IsBoxFakedBreakout(
helper,
box,
validatorFVG,
X_DIRECTION_BEARISH,
barIndex,
100, // Loopback For FVG ...
true, // Force FVg Validation ...
true // Force FVG Bar Type ...
);
//
bool isFakeBreaked =
isBullishFakedBreakedOut ||
isBearishFakedBreakedOut;
if (isFakeBreaked)
{
//
// Preparing TP and SL ...
//
sl = isBullishFakedBreakedOut
? validatorFVG.lower
: validatorFVG.upper;
//
tp = isBullishFakedBreakedOut
? box.upper
: box.lower;
}
//
// Summarizing ...
//
bool canTriggerLong =
isBullishFakedBreakedOut;
//
bool canTriggerShort =
isBearishFakedBreakedOut;
//
result = canTriggerLong ||
canTriggerShort;
if (result)
{
//
dir = canTriggerLong
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
// Cleanup Resources ...
validatorFVG.Clean();
//
return result;
}
//
// Detect Trigger Based On Decision Zone's
// Using OB inside Boxes ...
bool CanTriggerCond2(
XCXCAEAHelper *helper,
XBoxZone &decisionZone,
XBoxZone &decisionPivots[],
ENUM_X_DIRECTION &dir,
double &sl,
double &tp,
CArrayObj *drawns,
int barIndex = 0,
int loopback = 10 //
)
{
//
bool result = false;
//
// Normalize Args ...
sl = 0;
tp = 0;
dir = X_DIRECTION_NONE;
loopback = NormalizeInt(loopback, 5);
barIndex = NormalizeInt(barIndex, 0);
//
// Validate Decision Box ...
result = decisionZone.IsValid() &&
helper != NULL;
if (!result)
{
return result;
}
//
string symbol = helper.GetSymbol();
bool isBullish = decisionZone.IsBullish();
bool isBearish = decisionZone.IsBearish();
ENUM_TIMEFRAMES period = helper.GetPeriod();
//
int zIndex = barIndex;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int p2Index = pIndex + 1;
//
// Extract Bars ...
XOHCL zBar;
XOHCL cBar;
result = zBar.Init(
symbol,
period,
cIndex //
);
result =
result &&
zBar.GetPreviousBar(cBar);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
//
return result;
}
//
bool has = false;
XBoxZone selectedPivot;
bool hasPivots = HasChild(decisionPivots);
int pivotsCount = ArraySize(decisionPivots);
//
// Select Activated Pivot ...
if (hasPivots)
{
//
for (int i = 0; i < pivotsCount; i++)
{
//
// Check Rejection of Block ...
has =
isBullish
? cBar.IsBullish() &&
decisionPivots[i].IsBullish() &&
cBar.low < decisionPivots[i].upper &&
cBar.low > decisionPivots[i].lower &&
cBar.close > decisionPivots[i].upper
: cBar.IsBearish() &&
decisionPivots[i].IsBearish() &&
cBar.high > decisionPivots[i].lower &&
cBar.high < decisionPivots[i].upper &&
cBar.close < decisionPivots[i].lower;
if (has)
{
selectedPivot = decisionPivots[i];
}
// //
// // Draw Pivot ...
// XCBoxObject *iObj;
// //
// has = helper.poiDrawer.DrawBox(
// decisionPivots[i],
// iObj //
// );
// if (has)
// {
// drawns.Add(iObj);
// }
// //
// ZeroMemory(iObj);
}
}
//
// Check Selected Pivot is Exists or not ...
bool hasSelectedPivot = selectedPivot.IsValid();
//
// Detect Liquidity For Selected Pivot ...
double ssl = 0;
double bsl = 0;
bool hasSSL = false;
bool hasBSL = false;
if (hasSelectedPivot)
{
//
// Required Info ...
// int toIDX = selectedPivot.ToIndex();
// int fromIDX = selectedPivot.FromIndex();
// //
// // SSL ...
// datetime sslTo = NULL;
// datetime sslFrom = NULL;
// //
// // BSL ...
// datetime bslTo = NULL;
// datetime bslFrom = NULL;
// //
// // Loop ...
// XOHCL iBar;
// for (int i = fromIDX; i > toIDX; i--)
// {
// //
// hasSSL =
// ssl > 0 &&
// IsValid(sslTo) &&
// IsValid(sslFrom);
// //
// hasBSL =
// bsl > 0 &&
// IsValid(bslTo) &&
// IsValid(bslFrom);
// //
// iBar.Clean();
// //
// if (hasSSL && hasBSL)
// {
// break;
// }
// }
// iBar.Clean();
}
//
// Draw Selected Pivot ...
if (hasSelectedPivot)
{
//
// Draw Pivot ...
XCBoxObject *iObj;
//
has = helper.poiDrawer.DrawBox(
selectedPivot,
iObj //
);
if (has)
{
//
color iColor =
isBullish
? clrAqua
: clrMagenta;
//
iObj.BoxWidth(2);
iObj.BoxColor(iColor);
iObj.BoxStyle(STYLE_SOLID);
//
drawns.Add(iObj);
}
//
ZeroMemory(iObj);
}
//
// Summarizing ...
//
bool canTriggerLong =
isBullish &&
hasSelectedPivot &&
selectedPivot.IsBullish();
//
bool canTriggerShort =
isBearish &&
hasSelectedPivot &&
selectedPivot.IsBearish();
//
result = canTriggerLong ||
canTriggerShort;
if (result)
{
//
dir = canTriggerLong
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
// Preparing TP and SL ...
//
sl = canTriggerLong
? selectedPivot.lower // activatedFVG.lower
: selectedPivot.upper; // activatedFVG.upper;
//
// Since Here TP Must Calculated
// Using R2R we Ignore Target ...
tp = 0;
}
//
// Cleanup Resources ...
zBar.Clean();
cBar.Clean();
//
return result;
}
//
// Detect Trigger Based On Decision Zone's
// Block Based Triggering ...
bool CanTriggerCond3(
XCXCAEAHelper *helper,
XBoxZone &box,
ENUM_X_DIRECTION &dir,
double &sl,
double &tp,
CArrayObj *drawns,
int barIndex = 0,
int loopback = 10 //
)
{
//
bool result = false;
//
// Normalize Args ...
sl = 0;
tp = 0;
dir = X_DIRECTION_NONE;
loopback = NormalizeInt(loopback, 5);
barIndex = NormalizeInt(barIndex, 0);
//
// Validate Decision Box ...
result = box.IsValid() &&
helper != NULL;
if (!result)
{
return result;
}
//
bool isBullish = box.IsBullish();
bool isBearish = box.IsBearish();
//
bool has = false;
int swingLoopback = 7;
ENUM_TIMEFRAMES period = helper.GetPeriod();
string symbol = helper.GetSymbol();
int toIDX = box.ToIndex(period);
int fromIDX = box.FromIndex(period);
datetime cTime = GetBarTime(
symbol,
period,
barIndex //
);
//
// Initialize iBar ...
XOHCL iBar;
result = iBar.Init(
symbol,
period,
barIndex //
);
if (!result)
{
//
iBar.Clean();
//
return result;
}
//
// Validate Box ...
// For Box Validating we use 50% of Box Range ...
// if Price Touched Box 50% rate we Invalidate Box ...
// r if Prce Touched Leg 2 of Box Size ...
double boxLeg2 = box.GetLeg(2);
//
// Draw Box Leg2 ...
string iLeg2Name = box.GetMiddleTag();
StringReplace(
iLeg2Name,
"Mid",
"Leg2" //
);
CChartObjectTrend *iLeg2Obj;
iLeg2Obj = new CChartObjectTrend();
has = iLeg2Obj.Create(
helper.poiDrawer.ChartIdentification(),
iLeg2Name,
helper.poiDrawer.SubWindowIdentification(),
box.from,
boxLeg2,
box.to,
boxLeg2 //
);
if (has)
{
//
iLeg2Obj.Color(clrYellow);
//
drawns.Add(iLeg2Obj);
}
ZeroMemory(iLeg2Obj);
//
bool isBoxValid =
isBullish
? iBar.close < boxLeg2
: iBar.close > boxLeg2;
result = isBoxValid;
if (!result)
{
//
box.Clean();
iBar.Clean();
//
return result;
}
iBar.Clean();
//
// Detect Box FVG ...
//
// we Have to Detect a Broken Liquidity for Box ...
//
XBoxZone fvg;
XBoxZone fvgs[];
for (int i = fromIDX + loopback; i > barIndex; i--)
{
//
// Initialize iBar ...
XOHCL iBar;
has = iBar.Init(
symbol,
period,
i //
);
if (!has)
{
//
iBar.Clean();
//
break;
}
//
// Check iBar Has FVG ...
XBoxZone iFVG;
has = helper
.barAnalyser
.IsFVG(
iBar,
iFVG,
true //
);
has =
//
// Check FVG Exists ...
has &&
//
// Check FVG Direction ...
iFVG.dir == box.dir &&
//
// Check FVG not Breaked ...
!IsBoxBreaked(
helper,
iFVG,
barIndex //
) &&
//
// Check FVG Placement ...
(iFVG.IsBullish()
? iFVG.lower < box.upper
: iFVG.upper > box.lower);
if (has)
{
//
iFVG.to = cTime;
//
AddRef(
iFVG,
fvgs //
);
}
//
iBar.Clean();
iFVG.Clean();
}
//
// Detecting Target FVG ...
int idx = isBullish
? GetHighest(fvgs)
: GetLowest(fvgs);
has = IsValidIndex(idx);
if (has)
{
//
fvg = fvgs[idx];
//
fvg.to = cTime;
}
//
// Ensure FVG must Exists ...
result = fvg.IsValid();
if (!result)
{
//
fvg.Clean();
Clean(fvgs);
//
return result;
}
//
// Check FVg Break ...
bool isBreaked = IsBoxBreaked(
helper,
fvg,
barIndex //
);
result = !isBreaked;
if (!result)
{
//
fvg.Clean();
Clean(fvgs);
//
return result;
}
//
// Draw FVG ...
XCBoxObject *iObj;
has = helper.poiDrawer.DrawBox(
fvg,
iObj //
);
if (has)
{
//
color fvgColor =
isBullish
? clrLime
: clrRed;
//
iObj.BoxWidth(2);
iObj.BoxColor(fvgColor);
iObj.Style(STYLE_SOLID);
//
drawns.Add(iObj);
}
ZeroMemory(iObj);
//
// Detecting Liquiidties ...
XCAEALQSweep iLQ;
XCAEALQSweep lqs[];
toIDX = fvg.ToIndex();
fromIDX = fvg.FromIndex();
XCAEAConditions iConditions;
double fvgPrice = isBullish
? fvg.upper
: fvg.lower;
double fvgReversePrice = isBullish
? fvg.lower
: fvg.upper;
for (int i = fromIDX; i > toIDX; i--)
{
//
// Initialize iBar ...
has = iBar.Init(
symbol,
period,
i //
);
if (!has)
{
//
iBar.Clean();
iConditions.Clean();
//
continue;
}
//
// Reading Conditions ...
has = helper.GetConditions(
iConditions,
i,
5 //
);
if (!has)
{
//
iBar.Clean();
iConditions.Clean();
//
break;
}
//
double iSweep =
isBullish
? iConditions.valeBuffer[1]
: iConditions.peakBuffer[1];
double iSweepP =
isBullish
? iConditions.valeBuffer[2]
: iConditions.peakBuffer[2];
double iSweepP2 =
isBullish
? iConditions.valeBuffer[3]
: iConditions.peakBuffer[3];
double iReverse =
isBullish
? iConditions.peakBuffer[1]
: iConditions.valeBuffer[1];
//
bool isSweepContinue =
iSweepP == iSweep &&
(isBullish
? iSweep > fvgPrice
: iSweep < fvgPrice);
//
bool isSweepContinueP =
iSweepP2 == iSweepP &&
(isBullish
? iSweepP > fvgPrice
: iSweepP < fvgPrice);
//
bool isSweepStart =
isSweepContinue &&
!isSweepContinueP;
//
bool isSweepFinished =
!isSweepContinue &&
isSweepContinueP;
//
if (isSweepStart)
{
//
iLQ.Clean();
//
iLQ.symbol = iBar.symbol;
iLQ.period = iBar.period;
iLQ.type = isBullish
? XCAEA_LQ_TYPE_VALE
: XCAEA_LQ_TYPE_PEAK;
iLQ.to = iBar.time;
iLQ.from = iBar.time;
//
iLQ.length = 1;
iLQ.sweeped = iSweep;
iLQ.reverse = iReverse;
}
//
if (isSweepContinue)
{
//
iLQ.length++;
iLQ.to = iBar.time;
iLQ.sweeped = iSweep;
iLQ.reverse = MathMin(iLQ.reverse, iReverse);
}
//
if (isSweepFinished)
{
//
AddRef(
iLQ,
lqs //
);
//
iLQ.Clean();
}
//
iBar.Clean();
iConditions.Clean();
}
//
// Retrieve Bar and Conditions ...
has = iBar.Init(
symbol,
period,
barIndex //
);
has = has &&
helper.GetConditions(
iConditions,
barIndex,
loopback //
);
result = has;
if (!result)
{
//
Clean(lqs);
fvg.Clean();
iLQ.Clean();
Clean(fvgs);
iBar.Clean();
iConditions.Clean();
//
return result;
}
//
// Select Peak/Vale Value Based on Box ...
double iPV = isBullish
? iConditions.valeBuffer[1]
: iConditions.peakBuffer[1];
double iPVReverse = isBullish
? iConditions.peakBuffer[1]
: iConditions.valeBuffer[1];
//
// Validate Liquidities Exists ...
result = HasChild(lqs);
if (!result)
{
//
Clean(lqs);
fvg.Clean();
iLQ.Clean();
Clean(fvgs);
iBar.Clean();
iConditions.Clean();
//
return result;
}
//
// Draw Liquidities ...
for (int i = 0; i < ArraySize(lqs); i++)
{
//
iLQ = lqs[i];
//
CChartObjectTrend *iTrend;
iTrend = new CChartObjectTrend();
string itName = iLQ.GetTag();
has = iTrend.Create(
0,
itName,
0,
iLQ.from,
iLQ.sweeped,
iLQ.to,
iLQ.sweeped //
);
if (has)
{
//
color itColor =
isBullish
? clrLime
: clrRed;
//
iTrend.Width(2);
iTrend.Color(itColor);
iTrend.Style(STYLE_SOLID);
//
drawns.Add(iTrend);
}
//
ZeroMemory(iTrend);
}
//
// PV Must go Inside FVG ...
has =
isBullish
? iPV < fvgPrice
: iPV > fvgPrice;
result = has;
if (!result)
{
//
Clean(lqs);
fvg.Clean();
iLQ.Clean();
Clean(fvgs);
iBar.Clean();
iConditions.Clean();
//
return result;
}
//
// Detect a Traget for SL based on Activated FVG ...
XBoxZone slTarget;
double fvgValidatorPrice =
isBullish
? fvg.lower
: fvg.upper;
for (int i = 0; i < ArraySize(fvgs); i++)
{
//
XBoxZone iFVG = fvgs[i];
//
double iFVGPrice =
isBullish
? iFVG.upper
: iFVG.lower;
//
// Validate Placement ...
has = iFVGPrice > fvgValidatorPrice;
if (!has)
{
//
iFVG.Clean();
//
continue;
}
//
// Set slTarget ...
double slTargetPrice = (isBullish
? slTarget.upper
: slTarget.lower);
has =
!slTarget.IsValid()
? true
: (isBullish
? slTargetPrice < iFVGPrice
: slTargetPrice > iFVGPrice);
if (has)
{
slTarget = iFVG;
}
}
//
// Ensure SL Target Exists ...
result = slTarget.IsValid();
if (!result)
{
//
Clean(lqs);
fvg.Clean();
iLQ.Clean();
Clean(fvgs);
iBar.Clean();
iConditions.Clean();
//
return result;
}
//
// Darw SL Target Zone ...
slTarget.to = cTime;
XCBoxObject *iSLObj;
has = helper.poiDrawer.DrawBox(
slTarget,
iSLObj //
);
if (has)
{
//
color slTargetColor =
isBullish
? clrAqua
: clrMagenta;
//
iSLObj.BoxWidth(1);
iSLObj.BoxColor(slTargetColor);
//
drawns.Add(iSLObj);
}
ZeroMemory(iSLObj);
//
// Summarizing ...
//
bool canTriggerLong =
isBullish &&
fvg.IsBullish() &&
slTarget.IsBullish();
//
bool canTriggerShort =
isBearish &&
fvg.IsBearish() &&
slTarget.IsBearish();
//
result = canTriggerLong ||
canTriggerShort;
if (result)
{
//
dir = canTriggerLong
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
// Preparing TP and SL ...
//
sl = isBullish
? slTarget.lower
: slTarget.upper;
//
// Since Here TP Must Calculated
// Using R2R we Ignore Target ...
tp = 0;
//
// Add Target if price is Inside Analyse Box ...
double price = iBar.close;
double target =
isBullish
? box.upper
: box.lower;
has =
isBullish
? price < target
: price > target;
if (has)
{
tp = target;
}
}
//
// Cleanup Resources ...
//
Clean(lqs);
fvg.Clean();
iLQ.Clean();
Clean(fvgs);
iBar.Clean();
iConditions.Clean();
//
return result;
}
//
// Helper Functions ...
//
// Check a Box is Breaked or Not ...
bool IsBoxBreaked(
XCXCAEAHelper *helper,
XBoxZone &box,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize Args ...
barIndex = NormalizeInt(barIndex, 0);
//
// Validate Args ...
result =
box.IsValid() &&
helper != NULL;
if (!result)
{
//
// Assume Box Invalid and Breaked
// When Args not Valid ...
result = true;
return result;
}
//
bool isBullish = box.IsBullish();
bool isBearish = box.IsBearish();
//
// Extract Bars ...
//
XOHCL cBar;
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
//
result = cBar.Init(
box.symbol,
box.period,
barIndex + 1 //
);
result = result &&
cBar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
result = result &&
p2Bar.GetPreviousBar(p3Bar);
if (!result)
{
//
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
//
// Assume Box Invalid and Breaked
// When Args not Valid ...
result = true;
//
return result;
}
//
// Check Box is Breaked or not ...
// a Box Assume Breakes when at least 3 Bars Close over / under applied Price ...
//
double appliedPrice =
isBullish
? box.lower
: box.upper;
//
bool isBullishBreaked =
isBullish &&
cBar.close < appliedPrice &&
pBar.close < appliedPrice &&
p2Bar.close < appliedPrice;
//
bool isBearishBreaked =
isBearish &&
cBar.close > appliedPrice &&
pBar.close > appliedPrice &&
p2Bar.close > appliedPrice;
//
result = isBullishBreaked ||
isBearishBreaked;
//
// Cleanup Resources ...
//
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
//
return result;
}
//
// Detect Fake Breakout ...
bool IsBoxFakedBreakout(
XCXCAEAHelper *helper,
XBoxZone &box,
XBoxZone &validatorFVG,
ENUM_X_DIRECTION forDir,
int barIndex = 0,
int loopback = 100,
bool forceFVGValidating = false,
bool forceFVGBarType = false //
)
{
//
bool result = false;
//
validatorFVG.Clean();
//
// Normalizing Args ...
barIndex = NormalizeInt(barIndex, 0);
loopback = NormalizeInt(loopback, 10);
//
// Validate Decision Box ...
result = box.IsValid() &&
helper != NULL &&
(HasDirection(forDir));
if (!result)
{
return result;
}
//
double points = GetPoints(box.symbol);
//
// Extract Bars ...
//
XOHCL cBar;
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
//
result = cBar.Init(
box.symbol,
box.period,
barIndex + 1 //
);
result = result &&
cBar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
result = result &&
p2Bar.GetPreviousBar(p3Bar);
if (!result)
{
//
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
//
return result;
}
//
// Bar Conditions ...
//
ENUM_X_DIRECTION barDir;
//
// Engulfed ...
bool isCBarEngulfed = helper
.barAnalyser
.IsEngulfed(
cBar,
barDir //
);
bool isCBarBullishEngulfed =
isCBarEngulfed &&
IsBullish(barDir);
bool isCBarBearishEngulfed =
isCBarEngulfed &&
IsBearish(barDir);
//
// Rejected ...
bool isCBarRejected = helper
.barAnalyser
.IsRejected(
cBar,
barDir,
false, // Force Type ...
true // Force Fibo Pressure ...
);
bool isCBarBullishRejected =
isCBarRejected &&
IsBullish(barDir);
bool isCBarBearishRejected =
isCBarRejected &&
IsBearish(barDir);
//
bool isCBarHasBullishPower = isCBarBullishRejected ||
isCBarBullishEngulfed;
//
bool isCBarHasBearishPower = isCBarBearishRejected ||
isCBarBearishEngulfed;
//
bool isBullish = box.IsBullish();
bool isBearish = box.IsBearish();
//
bool lookForBullish = IsBullish(forDir);
bool lookForBearish = IsBearish(forDir);
//
// Calculate each Direction Breake Price ...
double bullishAppliedPrice = box.lower;
double bearishAppliedPrice = box.upper;
//
bool isCBarPressedForBullish =
//
isCBarHasBullishPower &&
cBar.low < bullishAppliedPrice &&
cBar.close > bullishAppliedPrice
//
;
//
bool isCBarPressedForBearish =
//
isCBarHasBearishPower &&
cBar.high > bearishAppliedPrice &&
cBar.close < bearishAppliedPrice
//
;
//
bool isPBarBreakedBullishAppliedPrice =
pBar.low < bullishAppliedPrice &&
pBar.high > bullishAppliedPrice;
//
bool isPBarBreakedBearishAppliedPrice =
pBar.low < bearishAppliedPrice &&
pBar.high > bearishAppliedPrice;
//
bool isP2BarBreakedBullishAppliedPrice =
p2Bar.low < bullishAppliedPrice &&
p2Bar.high > bullishAppliedPrice;
//
bool isP2BarBreakedBearishAppliedPrice =
p2Bar.low < bearishAppliedPrice &&
p2Bar.high > bearishAppliedPrice;
//
bool isBullishAppliedPriceBreaked =
isPBarBreakedBullishAppliedPrice ||
isP2BarBreakedBullishAppliedPrice;
//
bool isBearishAppliedPriceBreaked =
isPBarBreakedBearishAppliedPrice ||
isP2BarBreakedBearishAppliedPrice;
//
bool isBullishFakeBreakedOut =
lookForBullish &&
isCBarPressedForBullish &&
isBullishAppliedPriceBreaked;
//
bool isBearishFakeBreakedOut =
lookForBearish &&
isCBarPressedForBearish &&
isBearishAppliedPriceBreaked;
//
result = isBullishFakeBreakedOut ||
isBearishFakeBreakedOut;
//
// Validating Using FVG if necessary ...
if (forceFVGValidating)
{
//
// Detecting All FVGs Which Placed in Box till Loopback ...
XBoxZone fvg;
//
XOHCL iBar;
bool has = false;
int start = cBar.Index();
int end = start + loopback;
for (int i = start; i < end; i++)
{
//
// Initialize Bar ...
has = iBar.Init(
cBar.symbol,
cBar.period,
i //
);
if (!has)
{
//
fvg.Clean();
iBar.Clean();
//
continue;
}
//
// Check FVG ...
has = helper
.barAnalyser
.IsFVG(
iBar,
fvg,
forceFVGBarType //
);
if (!has)
{
//
fvg.Clean();
iBar.Clean();
//
continue;
}
//
bool isBullishFVG =
fvg.IsBullish() &&
isBullishFakeBreakedOut;
//
bool isBearishFVG =
fvg.IsBearish() &&
isBearishFakeBreakedOut;
//
// Checking FVG Dir ...
has = isBullishFVG ||
isBearishFVG;
if (!has)
{
//
fvg.Clean();
iBar.Clean();
//
continue;
}
//
// Check CBar Must Inside FVG ...
//
bool isFVGBullishBreaked =
isBullishFVG &&
cBar.low < fvg.upper &&
cBar.close > fvg.upper &&
isBullishFakeBreakedOut;
//
bool isFVGBearishBreaked =
isBearishFVG &&
cBar.high > fvg.lower &&
cBar.close < fvg.lower &&
isBearishFakeBreakedOut;
//
has =
isFVGBullishBreaked ||
isFVGBearishBreaked;
if (has)
{
//
iBar.Clean();
//
break;
}
//
fvg.Clean();
iBar.Clean();
}
//
result =
result &&
fvg.IsValid();
if (result)
{
//
fvg.to = cBar.time;
//
// Check FVG Size ...
double fvgRange = fvg.upper - fvg.lower;
bool canApplyLastBar = fvgRange < (5 * points);
if (canApplyLastBar)
{
//
// Retrieve FVG Start Bar ...
XOHCL fvgStartBar;
has = fvgStartBar.Init(
cBar.symbol,
cBar.period,
cBar.Index() + 3 //
);
if (has)
{
//
if (fvg.IsBullish())
{
fvg.lower = fvgStartBar.low;
}
else
{
fvg.upper = fvgStartBar.high;
}
}
//
fvgStartBar.Clean();
}
//
validatorFVG = fvg;
//
XCBoxObject *iObj;
has = helper.poiDrawer.DrawBox(
fvg,
iObj //
);
ZeroMemory(iObj);
}
//
fvg.Clean();
iBar.Clean();
}
//
// Cleanup Resources ...
//
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
//
return result;
}
//
// Detect Activated FVG ...
bool IsBoxHasActivatedFVG(
XCXCAEAHelper *helper,
XBoxZone &box,
XBoxZone &fvg,
int barIndex = 0,
int loopback = 10,
bool forceFVGBarType = false //
)
{
//
bool result = false;
//
fvg.Clean();
//
// Normalize Args ...
barIndex = NormalizeInt(barIndex, 0);
loopback = NormalizeInt(loopback, 10);
//
// Validate Decision Box ...
result = box.IsValid() &&
helper != NULL;
if (!result)
{
return result;
}
//
bool isBullish = box.IsBullish();
bool isBearish = box.IsBearish();
double points = GetPoints(box.symbol);
//
// Retrieve Conditions ...
XCAEAConditions conditions;
result = helper.GetConditions(
conditions,
barIndex,
loopback //
);
if (!result)
{
//
conditions.Clean();
//
return result;
}
//
// Extract Bars ...
//
XOHCL cBar;
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
//
result = cBar.Init(
box.symbol,
box.period,
barIndex + 1 //
);
result = result &&
cBar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
result = result &&
p2Bar.GetPreviousBar(p3Bar);
if (!result)
{
//
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
conditions.Clean();
//
return result;
}
//
// Find FVG ...
//
XOHCL iBar;
bool has = false;
int start = cBar.Index();
int end = start + loopback;
for (int i = start; i < end; i++)
{
//
// Initialize Bar ...
has = iBar.Init(
cBar.symbol,
cBar.period,
i //
);
if (!has)
{
//
fvg.Clean();
iBar.Clean();
//
continue;
};
//
// Check FVG ...
has = helper
.barAnalyser
.IsFVG(
iBar,
fvg,
forceFVGBarType //
);
if (!has)
{
//
fvg.Clean();
iBar.Clean();
//
continue;
}
//
// Validate FVG ...
has =
//
fvg.IsValid() &&
fvg.dir == box.dir &&
fvg.from > box.from &&
fvg.upper <= box.upper &&
fvg.lower >= box.lower
//
;
if (!has)
{
//
fvg.Clean();
iBar.Clean();
//
continue;
}
//
// Check CBar FVG Validations ...
//
bool isCBarBullishRejected =
isBullish &&
cBar.low < fvg.upper &&
cBar.close > fvg.upper;
//
bool isCBarBearishRejected =
isBearish &&
cBar.high > fvg.lower &&
cBar.close < fvg.lower;
//
has = isCBarBullishRejected ||
isCBarBearishRejected;
if (has)
{
//
iBar.Clean();
//
break;
}
//
fvg.Clean();
iBar.Clean();
}
//
result = fvg.IsValid();
if (result)
{
//
fvg.to = cBar.time;
//
// Check FVG Size ...
double fvgRange = fvg.upper - fvg.lower;
bool canApplyLastBar = true;
// fvgRange < (5 * points);
if (canApplyLastBar)
{
//
// Retrieve FVG Start Bar ...
XOHCL fvgStartBar;
has = fvgStartBar.Init(
cBar.symbol,
cBar.period,
cBar.Index() + 4 //
);
if (has)
{
//
if (fvg.IsBullish())
{
fvg.lower = fvgStartBar.low;
}
else
{
fvg.upper = fvgStartBar.high;
}
}
//
fvgStartBar.Clean();
}
//
XCBoxObject *iObj;
helper.poiDrawer.DrawBox(
fvg,
iObj //
);
ZeroMemory(iObj);
}
//
// Cleanup Resources ...
//
iBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
conditions.Clean();
//
return result;
}
//