2927 lines
60 KiB
Plaintext
2927 lines
60 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;
|
|
|
|
//
|
|
XTarget targets[];
|
|
|
|
//
|
|
datetime time;
|
|
datetime setupTime;
|
|
datetime triggerTime;
|
|
|
|
//
|
|
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;
|
|
|
|
//
|
|
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 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
|
|
bool CanTriggerCondTEMP(
|
|
XCXCAEAHelper *helper,
|
|
XBoxZone &decisionZone,
|
|
XBoxZone &decisionPivots[],
|
|
ENUM_X_DIRECTION &dir,
|
|
double &sl,
|
|
XTarget &targets[],
|
|
bool allowDraws,
|
|
CArrayObj *drawns,
|
|
int barIndex = 0,
|
|
int loopback = 10 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize Args ...
|
|
sl = 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;
|
|
}
|
|
|
|
//
|
|
// Define Requirements ...
|
|
|
|
//
|
|
string symbol = helper.GetSymbol();
|
|
bool isBullish = decisionZone.IsBullish();
|
|
bool isBearish = decisionZone.IsBearish();
|
|
ENUM_TIMEFRAMES period = helper.GetPeriod();
|
|
|
|
//
|
|
// Parse Conditions ...
|
|
|
|
//
|
|
// Summarizing ...
|
|
|
|
//
|
|
bool canTriggerLong =
|
|
false;
|
|
|
|
//
|
|
bool canTriggerShort =
|
|
false;
|
|
|
|
//
|
|
result = canTriggerLong ||
|
|
canTriggerShort;
|
|
if (result)
|
|
{
|
|
//
|
|
// Trigger Direction ...
|
|
dir = canTriggerLong
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
// Trigger Stop Loss ...
|
|
sl = 0;
|
|
|
|
//
|
|
// Trigger Targets ...
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Trigger Based On Decision Zone's
|
|
bool CanTriggerCond0(
|
|
XCXCAEAHelper *helper,
|
|
XBoxZone &decisionZone,
|
|
XBoxZone &decisionPivots[],
|
|
ENUM_X_DIRECTION &dir,
|
|
double &sl,
|
|
XTarget &targets[],
|
|
bool allowDraws,
|
|
CArrayObj *drawns,
|
|
int barIndex = 0,
|
|
int loopback = 5,
|
|
double scorePassMultiplier = 1 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize Args ...
|
|
sl = 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;
|
|
}
|
|
|
|
//
|
|
// Define Requirements ...
|
|
|
|
//
|
|
string symbol = helper.GetSymbol();
|
|
bool isBullish = decisionZone.IsBullish();
|
|
bool isBearish = decisionZone.IsBearish();
|
|
ENUM_TIMEFRAMES period = helper.GetPeriod();
|
|
|
|
//
|
|
// 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(
|
|
symbol,
|
|
decisionZone.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);
|
|
|
|
//
|
|
// Parse Conditions ...
|
|
|
|
//
|
|
bool isBullishPassed =
|
|
isBullish &&
|
|
bullScore >= (scorePassMultiplier * bearScore) &&
|
|
bullVolume >= (scorePassMultiplier * bearVolume);
|
|
|
|
//
|
|
bool isBearishPassed =
|
|
isBearish &&
|
|
bearScore >= (scorePassMultiplier * bullScore) &&
|
|
bearVolume >= (scorePassMultiplier * bullVolume);
|
|
|
|
//
|
|
// Summarizing ...
|
|
|
|
//
|
|
bool canTriggerLong =
|
|
isBullishPassed;
|
|
|
|
//
|
|
bool canTriggerShort =
|
|
isBearishPassed;
|
|
|
|
//
|
|
result = canTriggerLong ||
|
|
canTriggerShort;
|
|
if (result)
|
|
{
|
|
//
|
|
// Trigger Direction ...
|
|
dir = canTriggerLong
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
// Trigger Stop Loss ...
|
|
sl = canTriggerLong
|
|
? decisionZone.lower
|
|
: decisionZone.upper;
|
|
|
|
//
|
|
// Trigger Targets ...
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
iBar.Clean();
|
|
Clean(bullScores);
|
|
Clean(bearScores);
|
|
Clean(bullVolumes);
|
|
Clean(bearVolumes);
|
|
iConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Trigger Based On Decision Zone's
|
|
bool CanTriggerCond1(
|
|
XCXCAEAHelper *helper,
|
|
XBoxZone &decisionZone,
|
|
XBoxZone &decisionPivots[],
|
|
ENUM_X_DIRECTION &dir,
|
|
double &sl,
|
|
XTarget &targets[],
|
|
bool allowDraws,
|
|
CArrayObj *drawns,
|
|
int barIndex = 0,
|
|
int loopback = 10 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize Args ...
|
|
sl = 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;
|
|
}
|
|
|
|
//
|
|
// Define Requirements ...
|
|
|
|
//
|
|
bool has = false;
|
|
string symbol = helper.GetSymbol();
|
|
bool isBullish = decisionZone.IsBullish();
|
|
bool isBearish = decisionZone.IsBearish();
|
|
ENUM_TIMEFRAMES period = helper.GetPeriod();
|
|
|
|
//
|
|
int toIDX = decisionZone.ToIndex();
|
|
int fromIDX = decisionZone.FromIndex();
|
|
|
|
//
|
|
// Reading Bars ...
|
|
XOHCL zBar;
|
|
XOHCL cBar;
|
|
XOHCL pBar;
|
|
XOHCL p2Bar;
|
|
result = zBar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
result =
|
|
result &&
|
|
zBar.GetPreviousBar(cBar);
|
|
result =
|
|
result &&
|
|
cBar.GetPreviousBar(pBar);
|
|
result =
|
|
result &&
|
|
pBar.GetPreviousBar(p2Bar);
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Bar's Conditions ...
|
|
XCAEAConditions iConditions;
|
|
result = helper.GetConditions(
|
|
iConditions,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
iConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Conditions Values ...
|
|
|
|
//
|
|
int zIDX = 0;
|
|
int cIDX = zIDX + 1;
|
|
int pIDX = cIDX + 1;
|
|
int p2IDX = pIDX + 1;
|
|
int p3IDX = p2IDX + 1;
|
|
|
|
//
|
|
// PEAK ...
|
|
double zPeak = iConditions.peakBuffer[zIDX];
|
|
double cPeak = iConditions.peakBuffer[cIDX];
|
|
double pPeak = iConditions.peakBuffer[pIDX];
|
|
double p2Peak = iConditions.peakBuffer[p2IDX];
|
|
double p3Peak = iConditions.peakBuffer[p3IDX];
|
|
|
|
//
|
|
// VALE ...
|
|
double zVale = iConditions.valeBuffer[zIDX];
|
|
double cVale = iConditions.valeBuffer[cIDX];
|
|
double pVale = iConditions.valeBuffer[pIDX];
|
|
double p2Vale = iConditions.valeBuffer[p2IDX];
|
|
double p3Vale = iConditions.valeBuffer[p3IDX];
|
|
|
|
//
|
|
// SWH ...
|
|
double zSWH = iConditions.swingHighBuffer[zIDX];
|
|
double cSWH = iConditions.swingHighBuffer[cIDX];
|
|
double pSWH = iConditions.swingHighBuffer[pIDX];
|
|
double p2SWH = iConditions.swingHighBuffer[p2IDX];
|
|
double p3SWH = iConditions.swingHighBuffer[p3IDX];
|
|
|
|
//
|
|
// SWL ...
|
|
double zSWL = iConditions.swingLowBuffer[zIDX];
|
|
double cSWL = iConditions.swingLowBuffer[cIDX];
|
|
double pSWL = iConditions.swingLowBuffer[pIDX];
|
|
double p2SWL = iConditions.swingLowBuffer[p2IDX];
|
|
double p3SWL = iConditions.swingLowBuffer[p3IDX];
|
|
|
|
//
|
|
// Required Conditions ...
|
|
|
|
//
|
|
bool isPeakBraked =
|
|
zPeak == cPeak &&
|
|
cPeak == pPeak &&
|
|
(pPeak > p2Peak ||
|
|
pPeak > p3Peak);
|
|
|
|
//
|
|
bool isValeBraked =
|
|
zVale == cVale &&
|
|
cVale == pVale &&
|
|
(pVale < p2Vale ||
|
|
pVale < p3Vale);
|
|
|
|
//
|
|
bool isSWHBraked =
|
|
zSWH == cSWH &&
|
|
cSWH == pSWH &&
|
|
(pSWH > p2SWH ||
|
|
pSWH > p3SWH);
|
|
|
|
//
|
|
bool isSWLBraked =
|
|
zSWL == cSWL &&
|
|
cSWL == pSWL &&
|
|
(pSWL < p2SWL ||
|
|
pSWL < p3SWL);
|
|
|
|
//
|
|
// Select Activated Pivot ...
|
|
XBoxZone selectedPivot;
|
|
bool hasPivots = HasChild(decisionPivots);
|
|
int pivotsCount = ArraySize(decisionPivots);
|
|
if (hasPivots)
|
|
{
|
|
//
|
|
for (int i = 0; i < pivotsCount; i++)
|
|
{
|
|
//
|
|
// Detect Type of Pivot ...
|
|
ENUM_XCA_PIVOTS iType = GetPivotType(decisionPivots[i]);
|
|
|
|
//
|
|
// Check Rejection of Block ...
|
|
|
|
//
|
|
bool isBullishBraked =
|
|
isBullish &&
|
|
(isSWLBraked &&
|
|
isValeBraked) &&
|
|
iType == XCA_OB_BULL &&
|
|
decisionPivots[i].IsBullish() &&
|
|
zVale < decisionPivots[i].upper &&
|
|
zVale > decisionPivots[i].lower;
|
|
|
|
//
|
|
bool isBearishBraked =
|
|
isBearish &&
|
|
(isSWHBraked &&
|
|
isPeakBraked) &&
|
|
iType == XCA_OB_BEAR &&
|
|
decisionPivots[i].IsBearish() &&
|
|
zPeak < decisionPivots[i].upper &&
|
|
zPeak > decisionPivots[i].lower;
|
|
|
|
//
|
|
has = isBullishBraked ||
|
|
isBearishBraked;
|
|
if (has)
|
|
{
|
|
//
|
|
selectedPivot = decisionPivots[i];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
bool hasSelectedPivot = selectedPivot.IsValid();
|
|
|
|
//
|
|
// Draw Selected Pivot ...
|
|
if (allowDraws &&
|
|
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);
|
|
}
|
|
|
|
//
|
|
// Parse Conditions ...
|
|
|
|
//
|
|
// Summarizing ...
|
|
|
|
//
|
|
bool canTriggerLong =
|
|
isBullish &&
|
|
hasSelectedPivot &&
|
|
selectedPivot.IsBullish();
|
|
|
|
//
|
|
bool canTriggerShort =
|
|
isBearish &&
|
|
hasSelectedPivot &&
|
|
selectedPivot.IsBearish();
|
|
|
|
//
|
|
result = canTriggerLong ||
|
|
canTriggerShort;
|
|
if (result)
|
|
{
|
|
//
|
|
// Trigger Direction ...
|
|
dir = canTriggerLong
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
// Trigger Stop Loss ...
|
|
sl = isBullish
|
|
? selectedPivot.lower
|
|
: selectedPivot.upper;
|
|
|
|
//
|
|
// Trigger Targets ...
|
|
XTarget iTarget;
|
|
if (canTriggerLong &&
|
|
zBar.close < decisionZone.upper)
|
|
{
|
|
//
|
|
iTarget.doRF = true;
|
|
iTarget.target = decisionZone.upper;
|
|
}
|
|
if (canTriggerShort &&
|
|
zBar.close > decisionZone.lower)
|
|
{
|
|
//
|
|
iTarget.doRF = true;
|
|
iTarget.target = decisionZone.lower;
|
|
}
|
|
|
|
//
|
|
if (iTarget.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
iTarget,
|
|
targets //
|
|
);
|
|
}
|
|
iTarget.Clean();
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
iConditions.Clean();
|
|
selectedPivot.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Trigger Based On Decision Zone's
|
|
bool CanTriggerCond2(
|
|
XCXCAEAHelper *helper,
|
|
XBoxZone &decisionZone,
|
|
XBoxZone &decisionPivots[],
|
|
ENUM_X_DIRECTION &dir,
|
|
double &sl,
|
|
XTarget &targets[],
|
|
bool allowDraws,
|
|
CArrayObj *drawns,
|
|
int barIndex = 0,
|
|
int loopback = 10 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize Args ...
|
|
sl = 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;
|
|
}
|
|
|
|
//
|
|
// Define Requirements ...
|
|
|
|
//
|
|
bool has = false;
|
|
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;
|
|
}
|
|
|
|
//
|
|
// Select Activated Pivot ...
|
|
XBoxZone selectedPivot;
|
|
bool hasPivots = HasChild(decisionPivots);
|
|
int pivotsCount = ArraySize(decisionPivots);
|
|
if (hasPivots)
|
|
{
|
|
//
|
|
for (int i = 0; i < pivotsCount; i++)
|
|
{
|
|
//
|
|
// Detect Type of Pivot ...
|
|
ENUM_XCA_PIVOTS iType = GetPivotType(decisionPivots[i]);
|
|
|
|
//
|
|
// Check Rejection of Block ...
|
|
has =
|
|
isBullish
|
|
? cBar.IsBullish() &&
|
|
iType == XCA_OB_BULL &&
|
|
decisionPivots[i].IsBullish() &&
|
|
cBar.low < decisionPivots[i].upper &&
|
|
cBar.low > decisionPivots[i].lower &&
|
|
cBar.close > decisionPivots[i].upper
|
|
: cBar.IsBearish() &&
|
|
iType == XCA_OB_BEAR &&
|
|
decisionPivots[i].IsBearish() &&
|
|
cBar.high > decisionPivots[i].lower &&
|
|
cBar.high < decisionPivots[i].upper &&
|
|
cBar.close < decisionPivots[i].lower;
|
|
if (has)
|
|
{
|
|
selectedPivot = decisionPivots[i];
|
|
}
|
|
}
|
|
}
|
|
bool hasSelectedPivot = selectedPivot.IsValid();
|
|
|
|
//
|
|
// Draw Selected Pivot ...
|
|
if (allowDraws &&
|
|
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)
|
|
{
|
|
//
|
|
// Trigger Direction ...
|
|
dir = canTriggerLong
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
// Trigger Stop Loss ...
|
|
sl = canTriggerLong
|
|
? selectedPivot.lower
|
|
: selectedPivot.upper;
|
|
|
|
//
|
|
// Trigger Targets ...
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
selectedPivot.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Trigger Based On Decision Zone's
|
|
// Block Based Triggering ...
|
|
bool CanTriggerCond3(
|
|
XCXCAEAHelper *helper,
|
|
XBoxZone &decisionZone,
|
|
XBoxZone &decisionPivots[],
|
|
ENUM_X_DIRECTION &dir,
|
|
double &sl,
|
|
XTarget &targets[],
|
|
bool allowDraws,
|
|
CArrayObj *drawns,
|
|
int barIndex = 0,
|
|
int loopback = 10 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize Args ...
|
|
sl = 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;
|
|
}
|
|
|
|
//
|
|
// Define Requirements ...
|
|
|
|
//
|
|
string symbol = helper.GetSymbol();
|
|
bool isBullish = decisionZone.IsBullish();
|
|
bool isBearish = decisionZone.IsBearish();
|
|
ENUM_TIMEFRAMES period = helper.GetPeriod();
|
|
|
|
//
|
|
// Parse Conditions ...
|
|
|
|
//
|
|
// Summarizing ...
|
|
|
|
//
|
|
bool canTriggerLong =
|
|
false;
|
|
|
|
//
|
|
bool canTriggerShort =
|
|
false;
|
|
|
|
//
|
|
result = canTriggerLong ||
|
|
canTriggerShort;
|
|
if (result)
|
|
{
|
|
//
|
|
// Trigger Direction ...
|
|
dir = canTriggerLong
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
// Trigger Stop Loss ...
|
|
sl = 0;
|
|
|
|
//
|
|
// Trigger Targets ...
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
// |