2495 lines
52 KiB
Plaintext
2495 lines
52 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;
|
|
}
|
|
|
|
//
|
|
// Detect Decision Zone ...
|
|
bool DetectDecisionZone(
|
|
XCXCAEAHelper *helper,
|
|
XCXCAEAPOIDrawer *drawer,
|
|
XBoxZone &box,
|
|
ENUM_X_DIRECTION &dir,
|
|
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
|
|
.IsOrderBlock(
|
|
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;
|
|
|
|
//
|
|
// Testing Conditions ...
|
|
|
|
//
|
|
// Detect Fibo Section Changed ...
|
|
if (isFiboSectionChanged)
|
|
{
|
|
// Print("Fibo Section Changed ...");
|
|
}
|
|
|
|
//
|
|
// PVPivot Conditions ...
|
|
if (isCIsPeakPivot ||
|
|
isCIsValePivot)
|
|
{
|
|
// //
|
|
// ENUM_X_DIRECTION iPVPivotDir =
|
|
// isCIsValePivot
|
|
// ? X_DIRECTION_BULLISH
|
|
// : X_DIRECTION_BEARISH;
|
|
|
|
// //
|
|
// int timeOffset = (int)cBar.time;
|
|
// string iName = ToString(iPVPivotDir) + "_PVPVT_" + ToString(timeOffset);
|
|
// color iColor = isCIsValePivot
|
|
// ? 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);
|
|
// }
|
|
|
|
// //
|
|
// Print("Conditions Finder ...");
|
|
}
|
|
|
|
//
|
|
// Testing Sar Changes ...
|
|
if (isSarSwitchedToBullish ||
|
|
isSarSwitchedToBearish)
|
|
{
|
|
//
|
|
// ENUM_X_DIRECTION iSarChangeDir =
|
|
// isSarSwitchedToBullish
|
|
// ? X_DIRECTION_BULLISH
|
|
// : X_DIRECTION_BEARISH;
|
|
|
|
// //
|
|
// int timeOffset = (int)cBar.time;
|
|
// string iName = ToString(iSarChangeDir) + "_SAR_" + ToString(timeOffset);
|
|
// color iColor = isSarSwitchedToBullish
|
|
// ? 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);
|
|
// }
|
|
|
|
//
|
|
// Print("Conditions Finder ...");
|
|
}
|
|
|
|
//
|
|
// Score and Volume Conditions ...
|
|
if (isScoreVolumeNeuturalBullishPowered ||
|
|
isScoreVolumeNeuturalBearishPowered)
|
|
{
|
|
//
|
|
// ENUM_X_DIRECTION iScoreVolumeDir =
|
|
// isScoreVolumeNeuturalBullishPowered
|
|
// ? X_DIRECTION_BULLISH
|
|
// : X_DIRECTION_BEARISH;
|
|
|
|
// //
|
|
// int timeOffset = (int)cBar.time;
|
|
// string iName = ToString(iScoreVolumeDir) + "_SCVM_" + ToString(timeOffset);
|
|
// color iColor = isScoreVolumeNeuturalBullishPowered
|
|
// ? 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);
|
|
// }
|
|
|
|
// //
|
|
// Print("Conditions Finder ...");
|
|
}
|
|
|
|
//
|
|
// Custom Senarios ...
|
|
|
|
//
|
|
bool isCond1Bullish =
|
|
isBullishOB &&
|
|
isCIsValePivot &&
|
|
isRSICrossedOverOS &&
|
|
!isFiboSectionChanged &&
|
|
isSarSwitchedToBullish;
|
|
|
|
//
|
|
bool isCond1Bearish =
|
|
isBearishOB &&
|
|
isCIsPeakPivot &&
|
|
isRSICrossedUnderOB &&
|
|
!isFiboSectionChanged &&
|
|
isSarSwitchedToBearish;
|
|
|
|
//
|
|
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)
|
|
{
|
|
//
|
|
// Style Object ...
|
|
}
|
|
}
|
|
|
|
//
|
|
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)
|
|
{
|
|
//
|
|
// Do Signal Preparing ...
|
|
|
|
//
|
|
// 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();
|
|
}
|
|
|
|
//
|
|
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,
|
|
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,
|
|
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
|
|
// Box Starts With FVG ...
|
|
bool CanTriggerCond2(
|
|
XCXCAEAHelper *helper,
|
|
XBoxZone &box,
|
|
ENUM_X_DIRECTION &dir,
|
|
double &sl,
|
|
double &tp,
|
|
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;
|
|
}
|
|
|
|
//
|
|
XBoxZone activatedFVG;
|
|
bool hasActivatedFVG = IsBoxHasActivatedFVG(
|
|
helper,
|
|
box,
|
|
activatedFVG,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
|
|
//
|
|
bool hasBullishActivatedFVG =
|
|
hasActivatedFVG &&
|
|
activatedFVG.IsBullish();
|
|
|
|
//
|
|
bool hasBearishActivatedFVG =
|
|
hasActivatedFVG &&
|
|
activatedFVG.IsBearish();
|
|
|
|
//
|
|
if (hasActivatedFVG)
|
|
{
|
|
//
|
|
// Preparing TP and SL ...
|
|
|
|
//
|
|
sl = hasBullishActivatedFVG
|
|
? box.lower // activatedFVG.lower
|
|
: box.upper; // activatedFVG.upper;
|
|
|
|
//
|
|
// Since Here TP Must Calculated
|
|
// Using R2R we Ignore Target ...
|
|
tp = 0;
|
|
}
|
|
|
|
//
|
|
// Summarizing ...
|
|
|
|
//
|
|
bool canTriggerLong =
|
|
hasBullishActivatedFVG;
|
|
|
|
//
|
|
bool canTriggerShort =
|
|
hasBearishActivatedFVG;
|
|
|
|
//
|
|
result = canTriggerLong ||
|
|
canTriggerShort;
|
|
if (result)
|
|
{
|
|
//
|
|
dir = canTriggerLong
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
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;
|
|
}
|
|
|
|
// |