2810 lines
60 KiB
Plaintext
2810 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;
|
|
string provider;
|
|
double targets[];
|
|
|
|
//
|
|
datetime time;
|
|
datetime setupTime;
|
|
datetime triggerTime;
|
|
|
|
//
|
|
XBoxZone signalBox;
|
|
ENUM_X_DIRECTION dir;
|
|
ENUM_X_POSITION_TYPES type;
|
|
XCAEAConditions conditions;
|
|
|
|
//
|
|
// Constructor ...
|
|
XCAEAStrategyConditions()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Cleaning Up ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
sl = 0;
|
|
tp = 0;
|
|
pivot = 0;
|
|
point = 0;
|
|
|
|
//
|
|
symbol = NULL;
|
|
period = NULL;
|
|
provider = NULL;
|
|
|
|
//
|
|
time = NULL;
|
|
setupTime = NULL;
|
|
triggerTime = NULL;
|
|
|
|
//
|
|
Clean(targets);
|
|
|
|
//
|
|
signalBox.Clean();
|
|
conditions.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;
|
|
}
|
|
|
|
//
|
|
bool TestDetectSignal(
|
|
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;
|
|
|
|
//
|
|
// 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];
|
|
|
|
//
|
|
// 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;
|
|
;
|
|
|
|
//
|
|
// 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 =
|
|
isCIsValePivot &&
|
|
!isFiboSectionChanged &&
|
|
isSarSwitchedToBullish;
|
|
|
|
//
|
|
bool isCond1Bearish =
|
|
isCIsPeakPivot &&
|
|
!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 ...
|
|
}
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
|
|
//
|
|
// Print("Conditions Finder ...");
|
|
}
|
|
|
|
//
|
|
// Summarise Result ...
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (result)
|
|
{
|
|
//
|
|
// Do Signal Preparing ...
|
|
|
|
//
|
|
// Check Box is Prepared or Not ...
|
|
result = box.IsValid();
|
|
}
|
|
|
|
//
|
|
// Cleaning Up ...
|
|
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
//
|
|
box.Clean();
|
|
conditions.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Cond 2 ...
|
|
// - a PV Box is Sweep Liquidity;
|
|
// - a Directional FVg Occures Exactly after Liquidity Sweep;
|
|
// - Price Action Go Inside FVG;
|
|
// - SL behind FVG;
|
|
|
|
//
|
|
bool DetectXCAEAConditions(
|
|
XCXCAEAPOIDrawer *drawer,
|
|
XBoxZone &pivots[],
|
|
XCAEAConditions &conditions,
|
|
XBoxZone &pivotBox,
|
|
XBoxZone &box,
|
|
double &targets[],
|
|
double &additionalSL,
|
|
ENUM_X_DIRECTION &dir,
|
|
XCXCAEAHelper *helper,
|
|
int barIndex = 0,
|
|
int loopback = 10 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
box.Clean();
|
|
additionalSL = 0;
|
|
conditions.Clean();
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
loopback = NormalizeInt(loopback, 5);
|
|
|
|
//
|
|
// Retrieve Some Requirements ...
|
|
string symbol = helper.GetSymbol();
|
|
ENUM_TIMEFRAMES period = helper.GetPeriod();
|
|
double points = GetPoints(symbol);
|
|
|
|
//
|
|
// Trend Parsing ...
|
|
// bool hasTrend = HasDirection(trend);
|
|
// bool hasBullishTrend = hasTrend &&
|
|
// IsBullish(trend);
|
|
// bool hasBearishTrend = hasTrend &&
|
|
// IsBearish(trend);
|
|
|
|
//
|
|
// Retrieve Previous and Current Bar Conditions ...
|
|
XCAEAConditions pConditions;
|
|
result = helper.GetConditions(
|
|
conditions,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
result = result &&
|
|
helper.GetConditions(
|
|
pConditions,
|
|
barIndex + 1,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
conditions.Clean();
|
|
pConditions.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;
|
|
|
|
//
|
|
// Reading Bars ...
|
|
|
|
//
|
|
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();
|
|
pConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Bars Conditions ...
|
|
|
|
//
|
|
// Temparory Bar Direction ...
|
|
ENUM_X_DIRECTION cBarDir;
|
|
|
|
//
|
|
// Hammer ...
|
|
bool isCBarHammer = helper
|
|
.barAnalyser
|
|
.IsHammer(
|
|
cBar,
|
|
cBarDir //
|
|
);
|
|
bool isCBarBullishHammer =
|
|
isCBarHammer &&
|
|
IsBullish(cBarDir);
|
|
bool isCBarBearishHammer =
|
|
isCBarHammer &&
|
|
IsBearish(cBarDir);
|
|
|
|
//
|
|
// Rejected ...
|
|
bool isCBarRejected = helper
|
|
.barAnalyser
|
|
.IsRejected(
|
|
cBar,
|
|
cBarDir,
|
|
false, // Force Type ...
|
|
true // Force Fibo Pressure ...
|
|
);
|
|
bool isCBarBullishRejected =
|
|
isCBarRejected &&
|
|
IsBullish(cBarDir);
|
|
bool isCBarBearishRejected =
|
|
isCBarRejected &&
|
|
IsBearish(cBarDir);
|
|
|
|
//
|
|
// Engulfed ...
|
|
bool isCBarEngulfed = helper
|
|
.barAnalyser
|
|
.IsEngulfed(
|
|
cBar,
|
|
cBarDir //
|
|
);
|
|
bool isCBarBullishEngulfed =
|
|
isCBarEngulfed &&
|
|
IsBullish(cBarDir);
|
|
bool isCBarBearishEngulfed =
|
|
isCBarEngulfed &&
|
|
IsBearish(cBarDir);
|
|
|
|
//
|
|
// Momentum ...
|
|
bool isCBarMomentum = helper
|
|
.barAnalyser
|
|
.IsMomentum(
|
|
cBar,
|
|
cBarDir,
|
|
1 //
|
|
);
|
|
bool isCBarBullishMomentum =
|
|
isCBarMomentum &&
|
|
IsBullish(cBarDir);
|
|
bool isCBarBearishMomentum =
|
|
isCBarMomentum &&
|
|
IsBearish(cBarDir);
|
|
|
|
//
|
|
// Bar Sumarise ...
|
|
|
|
//
|
|
bool isCBarValidForBullish =
|
|
(isCBarBullishHammer ||
|
|
isCBarBullishRejected ||
|
|
isCBarBullishMomentum ||
|
|
isCBarBullishEngulfed);
|
|
|
|
//
|
|
bool isCBarValidForBearish =
|
|
(isCBarBearishHammer ||
|
|
isCBarBearishRejected ||
|
|
isCBarBearishMomentum ||
|
|
isCBarBearishEngulfed);
|
|
|
|
//
|
|
// 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;
|
|
int volumeRangeLoopback = loopback;
|
|
helper.barAnalyser.CalculateRangeVolume(
|
|
cBar,
|
|
bullishVolume,
|
|
bearishVolume,
|
|
volumeRangeLoopback //
|
|
);
|
|
|
|
//
|
|
bool isVolumeNeutural = MathAbs(bullishVolume - bearishVolume) == 0;
|
|
|
|
//
|
|
double rangeVolume = bullishVolume == bearishVolume;
|
|
double rangeVolumeAvg = rangeVolume / volumeRangeLoopback;
|
|
|
|
//
|
|
bool isVolumeBullish = bullishVolume > bearishVolume;
|
|
bool isVolumeBearish = bullishVolume < bearishVolume;
|
|
bool isVolumeOverLast = cBar.volume > pBar.volume;
|
|
bool isVolumeOverAvg = cBar.volume > rangeVolumeAvg;
|
|
|
|
//
|
|
// Conditions ...
|
|
|
|
//
|
|
// SAR ...
|
|
double zSar = conditions.sarBuffer[zIDX];
|
|
double cSar = conditions.sarBuffer[cIDX];
|
|
double pSar = conditions.sarBuffer[pIDX];
|
|
double p2Sar = conditions.sarBuffer[p2IDX];
|
|
|
|
//
|
|
// PEAK ...
|
|
double zPeak = conditions.peakBuffer[zIDX];
|
|
double cPeak = conditions.peakBuffer[cIDX];
|
|
double pPeak = conditions.peakBuffer[pIDX];
|
|
double p2Peak = conditions.peakBuffer[p2IDX];
|
|
|
|
//
|
|
// VALE ...
|
|
double zVale = conditions.valeBuffer[zIDX];
|
|
double cVale = conditions.valeBuffer[cIDX];
|
|
double pVale = conditions.valeBuffer[pIDX];
|
|
double p2Vale = conditions.valeBuffer[p2IDX];
|
|
|
|
//
|
|
// PEAKGOLDEN ...
|
|
double zPeakGolden = conditions.peakGoldenBuffer[zIDX];
|
|
double cPeakGolden = conditions.peakGoldenBuffer[cIDX];
|
|
double pPeakGolden = conditions.peakGoldenBuffer[pIDX];
|
|
double p2PeakGolden = conditions.peakGoldenBuffer[p2IDX];
|
|
|
|
//
|
|
// VALEGOLDEN ...
|
|
double zValeGolden = conditions.valeGoldenBuffer[zIDX];
|
|
double cValeGolden = conditions.valeGoldenBuffer[cIDX];
|
|
double pValeGolden = conditions.valeGoldenBuffer[pIDX];
|
|
double p2ValeGolden = conditions.valeGoldenBuffer[p2IDX];
|
|
|
|
//
|
|
// SUPPORT ...
|
|
double zSupport = conditions.supportBuffer[zIDX];
|
|
double cSupport = conditions.supportBuffer[cIDX];
|
|
double pSupport = conditions.supportBuffer[pIDX];
|
|
double p2Support = conditions.supportBuffer[p2IDX];
|
|
|
|
//
|
|
// RESISTANCE ...
|
|
double zResistance = conditions.resistanceBuffer[zIDX];
|
|
double cResistance = conditions.resistanceBuffer[cIDX];
|
|
double pResistance = conditions.resistanceBuffer[pIDX];
|
|
double p2Resistance = conditions.resistanceBuffer[p2IDX];
|
|
|
|
//
|
|
// SWING LOW ...
|
|
double zSwingLow = conditions.swingLowBuffer[zIDX];
|
|
double cSwingLow = conditions.swingLowBuffer[cIDX];
|
|
double pSwingLow = conditions.swingLowBuffer[pIDX];
|
|
double p2SwingLow = conditions.swingLowBuffer[p2IDX];
|
|
|
|
//
|
|
// SWING HIGH ...
|
|
double zSwingHigh = conditions.swingHighBuffer[zIDX];
|
|
double cSwingHigh = conditions.swingHighBuffer[cIDX];
|
|
double pSwingHigh = conditions.swingHighBuffer[pIDX];
|
|
double p2SwingHigh = conditions.swingHighBuffer[p2IDX];
|
|
|
|
//
|
|
// TREND ...
|
|
double zTrend = conditions.trendBuffer[zIDX];
|
|
double cTrend = conditions.trendBuffer[cIDX];
|
|
double pTrend = conditions.trendBuffer[pIDX];
|
|
double p2Trend = conditions.trendBuffer[p2IDX];
|
|
|
|
//
|
|
// KI ...
|
|
double zKI = conditions.kiBuffer[zIDX];
|
|
double cKI = conditions.kiBuffer[cIDX];
|
|
double pKI = conditions.kiBuffer[pIDX];
|
|
double p2KI = conditions.kiBuffer[p2IDX];
|
|
|
|
//
|
|
// TKI ...
|
|
double zTKI = conditions.tkiBuffer[zIDX];
|
|
double cTKI = conditions.tkiBuffer[cIDX];
|
|
double pTKI = conditions.tkiBuffer[pIDX];
|
|
double p2TKI = conditions.tkiBuffer[p2IDX];
|
|
|
|
//
|
|
// VIDYA ...
|
|
double zVIDYA = conditions.vidyaBuffer[zIDX];
|
|
double cVIDYA = conditions.vidyaBuffer[cIDX];
|
|
double pVIDYA = conditions.vidyaBuffer[pIDX];
|
|
double p2VIDYA = conditions.vidyaBuffer[p2IDX];
|
|
|
|
//
|
|
// RSI ...
|
|
double zRSI = conditions.rsiBuffer[zIDX];
|
|
double cRSI = conditions.rsiBuffer[cIDX];
|
|
double pRSI = conditions.rsiBuffer[pIDX];
|
|
double p2RSI = conditions.rsiBuffer[p2IDX];
|
|
|
|
//
|
|
// CCI ...
|
|
double zCCI = conditions.cciBuffer[zIDX];
|
|
double cCCI = conditions.cciBuffer[cIDX];
|
|
double pCCI = conditions.cciBuffer[pIDX];
|
|
double p2CCI = conditions.cciBuffer[p2IDX];
|
|
|
|
//
|
|
// ATR ...
|
|
double zATR = conditions.atrBuffer[zIDX];
|
|
double cATR = conditions.atrBuffer[cIDX];
|
|
double pATR = conditions.atrBuffer[pIDX];
|
|
double p2ATR = conditions.atrBuffer[p2IDX];
|
|
|
|
//
|
|
// ADX ...
|
|
double zADX = conditions.adxBuffer[zIDX];
|
|
double cADX = conditions.adxBuffer[cIDX];
|
|
double pADX = conditions.adxBuffer[pIDX];
|
|
double p2ADX = conditions.adxBuffer[p2IDX];
|
|
|
|
//
|
|
// ADX P ...
|
|
double zADXP = conditions.adxpBuffer[zIDX];
|
|
double cADXP = conditions.adxpBuffer[cIDX];
|
|
double pADXP = conditions.adxpBuffer[pIDX];
|
|
double p2ADXP = conditions.adxpBuffer[p2IDX];
|
|
|
|
//
|
|
// ADX N ...
|
|
double zADXN = conditions.adxnBuffer[zIDX];
|
|
double cADXN = conditions.adxnBuffer[cIDX];
|
|
double pADXN = conditions.adxnBuffer[pIDX];
|
|
double p2ADXN = conditions.adxnBuffer[p2IDX];
|
|
|
|
//
|
|
// X3MA ...
|
|
|
|
//
|
|
// FAST ...
|
|
|
|
//
|
|
double z3MAFast = conditions.fastBuffer[zIDX];
|
|
double c3MAFast = conditions.fastBuffer[cIDX];
|
|
double p3MAFast = conditions.fastBuffer[pIDX];
|
|
double p23MAFast = conditions.fastBuffer[p2IDX];
|
|
|
|
//
|
|
double z3MAFastState = conditions.fastStateBuffer[zIDX];
|
|
double c3MAFastState = conditions.fastStateBuffer[cIDX];
|
|
double p3MAFastState = conditions.fastStateBuffer[pIDX];
|
|
double p23MAFastState = conditions.fastStateBuffer[p2IDX];
|
|
|
|
//
|
|
// MEDIUM ...
|
|
|
|
//
|
|
double z3MAMedium = conditions.mediumBuffer[zIDX];
|
|
double c3MAMedium = conditions.mediumBuffer[cIDX];
|
|
double p3MAMedium = conditions.mediumBuffer[pIDX];
|
|
double p23MAMedium = conditions.mediumBuffer[p2IDX];
|
|
|
|
//
|
|
double z3MAMediumState = conditions.mediumStateBuffer[zIDX];
|
|
double c3MAMediumState = conditions.mediumStateBuffer[cIDX];
|
|
double p3MAMediumState = conditions.mediumStateBuffer[pIDX];
|
|
double p23MAMediumState = conditions.mediumStateBuffer[p2IDX];
|
|
|
|
//
|
|
// SLOW ...
|
|
|
|
//
|
|
double z3MASlow = conditions.slowBuffer[zIDX];
|
|
double c3MASlow = conditions.slowBuffer[cIDX];
|
|
double p3MASlow = conditions.slowBuffer[pIDX];
|
|
double p23MASlow = conditions.slowBuffer[p2IDX];
|
|
|
|
//
|
|
double z3MASlowState = conditions.slowStateBuffer[zIDX];
|
|
double c3MASlowState = conditions.slowStateBuffer[cIDX];
|
|
double p3MASlowState = conditions.slowStateBuffer[pIDX];
|
|
double p23MASlowState = conditions.slowStateBuffer[p2IDX];
|
|
|
|
//
|
|
double x3maBullishGapUpper = c3MAMedium;
|
|
double x3maBullishGapLower = c3MASlow;
|
|
|
|
//
|
|
double x3maBearishGapUpper = c3MASlow;
|
|
double x3maBearishGapLower = c3MAMedium;
|
|
|
|
//
|
|
double cTrendValues[7] = {
|
|
cKI,
|
|
cTKI,
|
|
cTrend,
|
|
cVIDYA,
|
|
c3MAFast,
|
|
c3MASlow,
|
|
c3MAMedium,
|
|
};
|
|
double pTrendValues[7] = {
|
|
pKI,
|
|
pTKI,
|
|
pTrend,
|
|
pVIDYA,
|
|
p3MAFast,
|
|
p3MASlow,
|
|
p3MAMedium,
|
|
};
|
|
|
|
//
|
|
double minCTrendValue = GetMin(cTrendValues);
|
|
double maxCTrendValue = GetMax(cTrendValues);
|
|
|
|
//
|
|
double minPTrendValue = GetMin(pTrendValues);
|
|
double maxPTrendValue = GetMax(pTrendValues);
|
|
|
|
//
|
|
double cTrendValuesRange = (maxCTrendValue - minCTrendValue);
|
|
double cTrendValuesRangePoint = (cTrendValuesRange / points);
|
|
|
|
//
|
|
double pTrendValuesRange = (maxPTrendValue - minPTrendValue);
|
|
double pTrendValuesRangePoint = (pTrendValuesRange / points);
|
|
|
|
//
|
|
// Create Conditions ...
|
|
|
|
//
|
|
bool isPRSIOB =
|
|
pRSI > conditions.rsiOBLevel;
|
|
|
|
//
|
|
bool isPRSIOS =
|
|
pRSI < conditions.rsiOSLevel;
|
|
|
|
//
|
|
bool isRSIBullish =
|
|
cRSI > pRSI &&
|
|
!conditions.isRSIOB;
|
|
|
|
//
|
|
bool isRSIBearish =
|
|
cRSI < pRSI &&
|
|
!conditions.isRSIOS;
|
|
|
|
//
|
|
bool isPCCIOB =
|
|
pCCI > conditions.cciOBLevel;
|
|
|
|
//
|
|
bool isPCCIOS =
|
|
pCCI < conditions.cciOSLevel;
|
|
|
|
//
|
|
bool isCCIBullish =
|
|
cCCI > pCCI &&
|
|
!conditions.isCCIOB;
|
|
|
|
//
|
|
bool isCCIBearish =
|
|
cCCI < pCCI &&
|
|
!conditions.isCCIOS;
|
|
|
|
//
|
|
bool isADXBullish =
|
|
cADX > cADXN;
|
|
bool isADXBullishPrev =
|
|
pADX > pADXN;
|
|
|
|
//
|
|
bool isADXSwitchedToBullish = isADXBullish &&
|
|
!isADXBullishPrev;
|
|
|
|
//
|
|
bool isADXBearish =
|
|
cADX > cADXN;
|
|
bool isADXBearishPrev =
|
|
pADX > pADXN;
|
|
|
|
//
|
|
bool isADXSwitchedToBearish = isADXBearish &&
|
|
!isADXBearishPrev;
|
|
|
|
//
|
|
double barStrongAtrMult = 1.5;
|
|
|
|
//
|
|
bool isCBarRangeHasStrongATR =
|
|
cBar.GetRange() > cATR * barStrongAtrMult;
|
|
|
|
//
|
|
bool isCBarBodyHasStrongATR =
|
|
cBar.GetBody() > cATR * barStrongAtrMult;
|
|
|
|
//
|
|
bool isCBarHasStrongATR = isCBarRangeHasStrongATR &&
|
|
isCBarBodyHasStrongATR;
|
|
|
|
//
|
|
bool isCBarIsStrongBullish =
|
|
isCBarHasStrongATR &&
|
|
cBar.IsBullish();
|
|
|
|
//
|
|
bool isCBarIsStrongBearish =
|
|
isCBarHasStrongATR &&
|
|
cBar.IsBearish();
|
|
|
|
//
|
|
bool isLowOverMax = cBar.low > maxCTrendValue;
|
|
bool isHighUnderMin = cBar.high < minCTrendValue;
|
|
bool isCloseOverMax = cBar.close > maxCTrendValue;
|
|
bool isCloseUnderMin = cBar.close < minCTrendValue;
|
|
|
|
//
|
|
bool isCTrendRangeValid = cTrendValuesRangePoint <= 50;
|
|
bool isPTrendRangeValid = pTrendValuesRangePoint <= 50;
|
|
|
|
//
|
|
bool isTrendRangeSwitchedToValid = isCTrendRangeValid &&
|
|
!isPTrendRangeValid;
|
|
bool isTrendRangeFinishedFromValid = !isCTrendRangeValid &&
|
|
isPTrendRangeValid;
|
|
|
|
//
|
|
bool isPeakGoldenRejected =
|
|
cBar.high > cPeakGolden &&
|
|
cBar.GetUp() <= cPeakGolden;
|
|
|
|
//
|
|
bool isValeGoldenRejected =
|
|
cBar.low < cValeGolden &&
|
|
cBar.GetDown() >= cValeGolden;
|
|
|
|
//
|
|
bool isX3MaBullishState =
|
|
//
|
|
z3MAFast > z3MAMedium &&
|
|
c3MAFast > c3MAMedium &&
|
|
z3MAMedium > z3MASlow &&
|
|
c3MAMedium > c3MASlow
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isX3MaBearishState =
|
|
//
|
|
z3MAFast < z3MAMedium &&
|
|
c3MAFast < c3MAMedium &&
|
|
z3MAMedium < z3MASlow &&
|
|
c3MAMedium < c3MASlow
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isX3MaValidForBullishRejection =
|
|
//
|
|
c3MASlowState > 0 &&
|
|
z3MASlowState > 0 &&
|
|
z3MAMediumState > 0 &&
|
|
c3MAMediumState > 0 &&
|
|
z3MAMedium > z3MASlow &&
|
|
c3MAMedium > c3MASlow &&
|
|
conditions.isVidyaBullish
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isX3MaValidForBearishRejection =
|
|
//
|
|
c3MASlowState < 0 &&
|
|
z3MASlowState < 0 &&
|
|
z3MAMediumState < 0 &&
|
|
c3MAMediumState < 0 &&
|
|
z3MAMedium < z3MASlow &&
|
|
c3MAMedium < c3MASlow &&
|
|
conditions.isVidyaBearish
|
|
//
|
|
;
|
|
|
|
//
|
|
// Parsing Pivots ...
|
|
XBoxZone upperPivot;
|
|
XBoxZone lowerPivot;
|
|
double providedSL = 0;
|
|
XBoxZone rejectedPivot;
|
|
XBoxZone insidePivots[];
|
|
int insidePivotsCount = 0;
|
|
XBoxZone fakeBreakedPivot;
|
|
bool isRejectedOnMid = false;
|
|
bool hasInsidePivots = false;
|
|
bool hasPivots = HasChild(pivots);
|
|
if (hasPivots)
|
|
{
|
|
//
|
|
// Select Inside Boxes ...
|
|
ENUM_XCA_PIVOTS allowedInsidePivots[] = {
|
|
XCA_FVG_BULL,
|
|
XCA_FVG_BEAR,
|
|
};
|
|
insidePivotsCount = SelectInsideBoxes(
|
|
allowedInsidePivots,
|
|
insidePivots,
|
|
pivots,
|
|
zBar,
|
|
cBar,
|
|
pBar,
|
|
p2Bar //
|
|
);
|
|
Clean(allowedInsidePivots);
|
|
hasInsidePivots = IsValidSize(insidePivotsCount);
|
|
|
|
//
|
|
// Detect Rejected Pivot ...
|
|
ENUM_XCA_PIVOTS allowedRejectedPivots[] = {
|
|
XCA_FVG_BULL,
|
|
XCA_FVG_BEAR,
|
|
};
|
|
has = SelectRejectedBox(
|
|
allowedRejectedPivots,
|
|
rejectedPivot,
|
|
isRejectedOnMid,
|
|
pivots,
|
|
zBar,
|
|
cBar,
|
|
pBar,
|
|
p2Bar,
|
|
false, // Ignore Mid Rejection ...
|
|
true,
|
|
true //
|
|
);
|
|
Clean(allowedRejectedPivots);
|
|
|
|
//
|
|
// Select Fake Breakout Box ...
|
|
ENUM_XCA_PIVOTS allowedFakeBreakedPivots[] = {
|
|
XCA_PEAK,
|
|
XCA_VALE,
|
|
};
|
|
has = SelectFakeBreakedBox(
|
|
allowedFakeBreakedPivots,
|
|
fakeBreakedPivot,
|
|
pivots,
|
|
helper,
|
|
zBar,
|
|
cBar,
|
|
pBar,
|
|
p2Bar //
|
|
);
|
|
Clean(allowedFakeBreakedPivots);
|
|
|
|
//
|
|
// Select Boundary Boxes ...
|
|
ENUM_XCA_PIVOTS allowedBoundarydPivots[] = {
|
|
XCA_PEAK,
|
|
XCA_VALE,
|
|
};
|
|
has = SelectBoundaryBoxes(
|
|
allowedBoundarydPivots,
|
|
upperPivot,
|
|
lowerPivot,
|
|
pivots,
|
|
helper,
|
|
zBar,
|
|
cBar,
|
|
pBar,
|
|
p2Bar //
|
|
);
|
|
Clean(allowedBoundarydPivots);
|
|
}
|
|
|
|
//
|
|
// Signaller Summarization ...
|
|
|
|
//
|
|
// Cond1 Act Using FVG Rejections ...
|
|
|
|
//
|
|
bool isCond1Bullish =
|
|
//
|
|
false && // TODO: Remove this ...
|
|
isRSIBullish &&
|
|
isVolumeOverAvg &&
|
|
isVolumeOverLast &&
|
|
conditions.isSarBullish &&
|
|
rejectedPivot.IsValid() &&
|
|
rejectedPivot.IsBullish() &&
|
|
isX3MaValidForBullishRejection
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond1Bearish =
|
|
//
|
|
false && // TODO: Remove this ...
|
|
isRSIBearish &&
|
|
isVolumeOverAvg &&
|
|
isVolumeOverLast &&
|
|
conditions.isSarBearish &&
|
|
rejectedPivot.IsValid() &&
|
|
rejectedPivot.IsBearish() &&
|
|
isX3MaValidForBearishRejection
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond1 = isCond1Bullish ||
|
|
isCond1Bearish;
|
|
if (isCond1)
|
|
{
|
|
pivotBox = rejectedPivot;
|
|
}
|
|
|
|
//
|
|
// Cond2 Act Using OSC Box and Vydia ...
|
|
|
|
//
|
|
bool isCond2Bullish =
|
|
//
|
|
upperPivot.IsValid() &&
|
|
lowerPivot.IsValid() &&
|
|
fakeBreakedPivot.IsValid() &&
|
|
fakeBreakedPivot.IsBullish()
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond2Bearish =
|
|
//
|
|
upperPivot.IsValid() &&
|
|
lowerPivot.IsValid() &&
|
|
fakeBreakedPivot.IsValid() &&
|
|
fakeBreakedPivot.IsBearish()
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond2 = isCond2Bullish ||
|
|
isCond2Bearish;
|
|
if (isCond2)
|
|
{
|
|
Print("Cond2 ...");
|
|
}
|
|
|
|
//
|
|
// Cond3 Act Using CCi Peaks and Vales ...
|
|
|
|
//
|
|
bool isCond3Bullish =
|
|
//
|
|
false
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond3Bearish =
|
|
//
|
|
false
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond3 = isCond3Bullish ||
|
|
isCond3Bearish;
|
|
if (isCond3)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Summarise Conditions ...
|
|
|
|
//
|
|
bool isBullish =
|
|
//
|
|
isCond1Bullish ||
|
|
isCond2Bullish ||
|
|
isCond3Bullish;
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isBearish =
|
|
//
|
|
isCond1Bearish ||
|
|
isCond2Bearish ||
|
|
isCond3Bearish
|
|
//
|
|
;
|
|
|
|
//
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (result)
|
|
{
|
|
//
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
double entry = GetEntry(
|
|
conditions.symbol,
|
|
dir //
|
|
);
|
|
|
|
//
|
|
double sls[];
|
|
|
|
//
|
|
// Preparing SLs ...
|
|
|
|
//
|
|
// For Cond 1 ...
|
|
// For Cond 2 ...
|
|
if (isCond1 ||
|
|
isCond2)
|
|
{
|
|
//
|
|
if (isCond1Bullish)
|
|
{
|
|
//
|
|
// Rejected Pivot ...
|
|
Add(
|
|
rejectedPivot.lower,
|
|
sls //
|
|
);
|
|
|
|
//
|
|
if (!isRejectedOnMid)
|
|
{
|
|
//
|
|
Add(
|
|
rejectedPivot.GetMid(),
|
|
sls //
|
|
);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Rejected Pivot ...
|
|
Add(
|
|
rejectedPivot.upper,
|
|
sls //
|
|
);
|
|
|
|
//
|
|
if (!isRejectedOnMid)
|
|
{
|
|
//
|
|
Add(
|
|
rejectedPivot.GetMid(),
|
|
sls //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
providedSL =
|
|
isCond1Bullish
|
|
? GetMax(sls)
|
|
: GetMin(sls);
|
|
//
|
|
}
|
|
|
|
//
|
|
double risk = MathAbs(providedSL - entry);
|
|
double riskPoint = risk / points;
|
|
|
|
//
|
|
double sl =
|
|
providedSL > 0
|
|
? providedSL
|
|
: isBullish
|
|
? pivotBox.lower
|
|
: pivotBox.upper;
|
|
|
|
//
|
|
box.dir = dir;
|
|
box.symbol = conditions.symbol;
|
|
box.period = conditions.period;
|
|
|
|
//
|
|
box.upper =
|
|
isBullish
|
|
? entry
|
|
: sl;
|
|
|
|
//
|
|
box.lower =
|
|
isBullish
|
|
? sl
|
|
: entry;
|
|
|
|
//
|
|
box.to = zBar.time;
|
|
box.from = p4Bar.time;
|
|
|
|
//
|
|
box.type = "XCASignal";
|
|
|
|
//
|
|
// Preparing Targets ...
|
|
if (isCond1 ||
|
|
isCond2)
|
|
{
|
|
//
|
|
// Add Reward 1 ...
|
|
|
|
//
|
|
double rewardPrice = 1 * risk;
|
|
double rewardTP =
|
|
isBullish
|
|
? entry + rewardPrice
|
|
: entry - rewardPrice;
|
|
|
|
//
|
|
Add(
|
|
rewardTP,
|
|
targets //
|
|
);
|
|
}
|
|
|
|
//
|
|
Clean(sls);
|
|
}
|
|
|
|
//
|
|
result = box.IsValid() &&
|
|
HasDirection(dir);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
//
|
|
box.Clean();
|
|
pivotBox.Clean();
|
|
conditions.Clean();
|
|
}
|
|
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
upperPivot.Clean();
|
|
lowerPivot.Clean();
|
|
Clean(cTrendValues);
|
|
Clean(pTrendValues);
|
|
Clean(insidePivots);
|
|
pConditions.Clean();
|
|
rejectedPivot.Clean();
|
|
fakeBreakedPivot.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Select Inside Boxes ...
|
|
int SelectInsideBoxes(
|
|
ENUM_XCA_PIVOTS &allowedTypes[],
|
|
XBoxZone &insideBoxes[],
|
|
XBoxZone &boxes[],
|
|
XOHCL &zBar,
|
|
XOHCL &cBar,
|
|
XOHCL &pBar,
|
|
XOHCL &p2Bar //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
Clean(insideBoxes);
|
|
|
|
//
|
|
bool has =
|
|
zBar.IsValid() &&
|
|
cBar.IsValid() &&
|
|
pBar.IsValid() &&
|
|
p2Bar.IsValid() &&
|
|
HasChild(boxes);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(boxes);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XBoxZone iBox = boxes[i];
|
|
|
|
//
|
|
ENUM_XCA_PIVOTS iType = GetPivotType(iBox);
|
|
bool isAllowedType = IsValid(iType) &&
|
|
!HasChild(allowedTypes)
|
|
? true
|
|
: Contains(
|
|
iType,
|
|
allowedTypes //
|
|
);
|
|
if (!isAllowedType)
|
|
{
|
|
//
|
|
iBox.Clean();
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
bool isBullish = iBox.IsBullish();
|
|
bool isBearish = iBox.IsBearish();
|
|
|
|
//
|
|
// Check Inside Conditions ...
|
|
|
|
//
|
|
bool isBullishInside =
|
|
//
|
|
isBullish &&
|
|
//
|
|
((cBar.low < iBox.upper &&
|
|
cBar.low > iBox.lower) ||
|
|
(cBar.GetDown() < iBox.upper &&
|
|
cBar.GetDown() > iBox.lower))
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isBearishInside =
|
|
//
|
|
isBearish &&
|
|
//
|
|
((cBar.high > iBox.lower &&
|
|
cBar.high < iBox.upper) ||
|
|
(cBar.GetUp() > iBox.lower &&
|
|
cBar.GetUp() < iBox.upper))
|
|
//
|
|
;
|
|
|
|
//
|
|
has = isBullishInside ||
|
|
isBearishInside;
|
|
if (has)
|
|
{
|
|
//
|
|
AddRef(
|
|
iBox,
|
|
insideBoxes //
|
|
);
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
result = ArraySize(insideBoxes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool SelectRejectedBox(
|
|
ENUM_XCA_PIVOTS &allowedTypes[],
|
|
XBoxZone &box,
|
|
bool &rejectOnMid,
|
|
XBoxZone &boxes[],
|
|
XOHCL &zBar,
|
|
XOHCL &cBar,
|
|
XOHCL &pBar,
|
|
XOHCL &p2Bar,
|
|
bool ignoreMidRejection = true,
|
|
bool forceBarType = false,
|
|
bool forcePressure = false //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
box.Clean();
|
|
rejectOnMid = false;
|
|
|
|
//
|
|
// Validate ...
|
|
result = HasChild(boxes) &&
|
|
zBar.IsValid() &&
|
|
cBar.IsValid() &&
|
|
pBar.IsValid() &&
|
|
p2Bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(boxes);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XBoxZone iBox = boxes[i];
|
|
|
|
//
|
|
ENUM_XCA_PIVOTS iType = GetPivotType(iBox);
|
|
bool isAllowedType = IsValid(iType) &&
|
|
!HasChild(allowedTypes)
|
|
? true
|
|
: Contains(
|
|
iType,
|
|
allowedTypes //
|
|
);
|
|
if (!isAllowedType)
|
|
{
|
|
//
|
|
iBox.Clean();
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
bool isBullish = iBox.IsBullish();
|
|
bool isBearish = iBox.IsBearish();
|
|
|
|
//
|
|
double boundaryPrice = iBox.GetRejection();
|
|
|
|
//
|
|
double midPrice = iBox.GetMid();
|
|
|
|
//
|
|
bool isMidBullishRejected = cBar.IsRejected(
|
|
midPrice,
|
|
X_DIRECTION_BULLISH,
|
|
forceBarType,
|
|
forcePressure //
|
|
);
|
|
|
|
//
|
|
bool isBoundaryBullishRejected = cBar.IsRejected(
|
|
boundaryPrice,
|
|
X_DIRECTION_BULLISH,
|
|
forceBarType,
|
|
forcePressure //
|
|
);
|
|
|
|
//
|
|
bool isMidBearishRejected = cBar.IsRejected(
|
|
midPrice,
|
|
X_DIRECTION_BEARISH,
|
|
forceBarType,
|
|
forcePressure //
|
|
);
|
|
|
|
//
|
|
bool isBoundaryBearishRejected = cBar.IsRejected(
|
|
boundaryPrice,
|
|
X_DIRECTION_BEARISH,
|
|
forceBarType,
|
|
forcePressure //
|
|
);
|
|
|
|
//
|
|
if (ignoreMidRejection)
|
|
{
|
|
//
|
|
isMidBullishRejected = false;
|
|
isMidBearishRejected = false;
|
|
}
|
|
|
|
//
|
|
bool isBullishRejected =
|
|
isBullish &&
|
|
(isMidBullishRejected ||
|
|
isBoundaryBullishRejected);
|
|
|
|
//
|
|
bool isBearishRejected =
|
|
isBearish &&
|
|
(isMidBearishRejected ||
|
|
isBoundaryBearishRejected);
|
|
|
|
//
|
|
bool isRejected =
|
|
isBullishRejected ||
|
|
isBearishRejected;
|
|
if (isRejected)
|
|
{
|
|
//
|
|
box = iBox;
|
|
rejectOnMid = isBullishRejected
|
|
? isMidBullishRejected
|
|
: isMidBearishRejected;
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
result = box.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool SelectFakeBreakedBox(
|
|
ENUM_XCA_PIVOTS &allowedTypes[],
|
|
XBoxZone &box,
|
|
XBoxZone &boxes[],
|
|
XCXCAEAHelper *helper,
|
|
XOHCL &zBar,
|
|
XOHCL &cBar,
|
|
XOHCL &pBar,
|
|
XOHCL &p2Bar //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
box.Clean();
|
|
|
|
//
|
|
// Validate ...
|
|
result =
|
|
zBar.IsValid() &&
|
|
cBar.IsValid() &&
|
|
pBar.IsValid() &&
|
|
p2Bar.IsValid() &&
|
|
HasChild(boxes);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XBoxZone tmp[];
|
|
Copy(
|
|
boxes,
|
|
tmp //
|
|
);
|
|
|
|
//
|
|
int idx = -1;
|
|
XBoxZone iBox;
|
|
while (HasChild(tmp))
|
|
{
|
|
//
|
|
idx = GetYoungest(tmp);
|
|
result = IsValidIndex(idx);
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBox = tmp[idx];
|
|
ArrayRemove(
|
|
tmp,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Checking Box Type Allowed ...
|
|
ENUM_XCA_PIVOTS iType = GetPivotType(iBox);
|
|
result = IsValid(iType) &&
|
|
(!HasChild(allowedTypes)
|
|
? true
|
|
: Contains(
|
|
iType,
|
|
allowedTypes //
|
|
));
|
|
if (!result)
|
|
{
|
|
//
|
|
iBox.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Check Box Fake Breakeout ...
|
|
result = IsFakeBreakeout(
|
|
iBox,
|
|
helper,
|
|
cBar.Index() //
|
|
);
|
|
if (result)
|
|
{
|
|
//
|
|
box = iBox;
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
Clean(tmp);
|
|
iBox.Clean();
|
|
|
|
//
|
|
result = box.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool SelectBoundaryBoxes(
|
|
ENUM_XCA_PIVOTS &allowedTypes[],
|
|
XBoxZone &upperBox,
|
|
XBoxZone &lowerBox,
|
|
XBoxZone &boxes[],
|
|
XCXCAEAHelper *helper,
|
|
XOHCL &zBar,
|
|
XOHCL &cBar,
|
|
XOHCL &pBar,
|
|
XOHCL &p2Bar //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
upperBox.Clean();
|
|
lowerBox.Clean();
|
|
|
|
//
|
|
// Validate ...
|
|
result =
|
|
zBar.IsValid() &&
|
|
cBar.IsValid() &&
|
|
pBar.IsValid() &&
|
|
p2Bar.IsValid() &&
|
|
HasChild(boxes);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XBoxZone tmp[];
|
|
Copy(
|
|
boxes,
|
|
tmp //
|
|
);
|
|
|
|
//
|
|
int idx = -1;
|
|
XBoxZone iBox;
|
|
while (HasChild(tmp))
|
|
{
|
|
//
|
|
idx = GetYoungest(tmp);
|
|
result = IsValidIndex(idx);
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBox = tmp[idx];
|
|
ArrayRemove(
|
|
tmp,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Checking Box Type Allowed ...
|
|
ENUM_XCA_PIVOTS iType = GetPivotType(iBox);
|
|
result = IsValid(iType) &&
|
|
(!HasChild(allowedTypes)
|
|
? true
|
|
: Contains(
|
|
iType,
|
|
allowedTypes //
|
|
));
|
|
if (!result)
|
|
{
|
|
//
|
|
iBox.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Upper ...
|
|
bool canSetUpper =
|
|
iType == XCA_PEAK &&
|
|
(!upperBox.IsValid()
|
|
? true
|
|
: upperBox.lower > iBox.lower);
|
|
if (canSetUpper)
|
|
{
|
|
upperBox = iBox;
|
|
}
|
|
|
|
//
|
|
// Lower ...
|
|
bool canSetLower =
|
|
iType == XCA_VALE &&
|
|
(!lowerBox.IsValid()
|
|
? true
|
|
: lowerBox.upper < iBox.upper);
|
|
if (canSetLower)
|
|
{
|
|
lowerBox = iBox;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
Clean(tmp);
|
|
iBox.Clean();
|
|
|
|
//
|
|
result = upperBox.IsValid() &&
|
|
lowerBox.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int ExtractValues(
|
|
double &values[],
|
|
XBoxZone &pivots[],
|
|
bool forceClean = true //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (forceClean)
|
|
{
|
|
Clean(values);
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(pivots);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XBoxZone iPivot = pivots[i];
|
|
|
|
//
|
|
Add(
|
|
iPivot.upper,
|
|
values //
|
|
);
|
|
|
|
//
|
|
Add(
|
|
iPivot.lower,
|
|
values //
|
|
);
|
|
|
|
//
|
|
iPivot.Clean();
|
|
}
|
|
|
|
//
|
|
result = ArraySize(values);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double GetMax(XBoxZone &pivots[])
|
|
{
|
|
//
|
|
double values[];
|
|
ExtractValues(
|
|
values,
|
|
pivots //
|
|
);
|
|
|
|
//
|
|
double result = GetMax(values);
|
|
|
|
//
|
|
Clean(values);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double GetMin(XBoxZone &pivots[])
|
|
{
|
|
//
|
|
double values[];
|
|
ExtractValues(
|
|
values,
|
|
pivots //
|
|
);
|
|
|
|
//
|
|
double result = GetMin(values);
|
|
|
|
//
|
|
Clean(values);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
// |