1233 lines
23 KiB
Plaintext
1233 lines
23 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;
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
// 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 DetectXCAEAConditions(
|
|
XCXCAEAPOIDrawer *drawer,
|
|
ENUM_X_DIRECTION trend,
|
|
XBoxZone &pivots[],
|
|
XCAEAConditions &conditions,
|
|
XBoxZone &pivotBox,
|
|
XBoxZone &box,
|
|
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;
|
|
|
|
//
|
|
// Generating Conditions Summary ...
|
|
string summary =
|
|
conditions
|
|
.GenerateSummary();
|
|
|
|
//
|
|
// Conditions ...
|
|
|
|
//
|
|
// 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];
|
|
|
|
//
|
|
// 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;
|
|
|
|
//
|
|
// Create Conditions ...
|
|
|
|
//
|
|
bool isX3MABullishState =
|
|
z3MAFast > c3MAFast &&
|
|
isCBarValidForBullish &&
|
|
c3MAFast > c3MAMedium &&
|
|
isCBarBullishRejected &&
|
|
c3MAMedium > c3MASlow &&
|
|
cBar.low < x3maBullishGapLower &&
|
|
cBar.GetDown() > x3maBullishGapLower;
|
|
|
|
//
|
|
bool isX3MABearishState =
|
|
z3MAFast < c3MAFast &&
|
|
isCBarValidForBearish &&
|
|
c3MAFast < c3MAMedium &&
|
|
isCBarBearishRejected &&
|
|
c3MAMedium < c3MASlow &&
|
|
cBar.high > x3maBearishGapLower &&
|
|
cBar.GetUp() < x3maBearishGapLower;
|
|
|
|
//
|
|
// Parsing Pivots ...
|
|
|
|
//
|
|
// Select Inside Boxes ...
|
|
XBoxZone insidePivots[];
|
|
int insidePivotsCount = SelectInsideBoxes(
|
|
insidePivots,
|
|
pivots,
|
|
zBar,
|
|
cBar,
|
|
pBar,
|
|
p2Bar //
|
|
);
|
|
bool hasInsidePivots = IsValidSize(insidePivotsCount);
|
|
if (hasInsidePivots) {
|
|
//
|
|
drawer.DrawBoxes(insidePivots, TimeCurrent());
|
|
}
|
|
|
|
//
|
|
// Detect Selected Pivot ...
|
|
XBoxZone rejectedPivot;
|
|
double providedSL = 0;
|
|
bool hasPivots = HasChild(pivots);
|
|
if (hasPivots)
|
|
{
|
|
//
|
|
has = SelectRejectedBox(
|
|
rejectedPivot,
|
|
pivots,
|
|
zBar,
|
|
cBar,
|
|
pBar,
|
|
p2Bar,
|
|
true,
|
|
true //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Signaller Summarization ...
|
|
|
|
//
|
|
// Cond1 Act Using PEAK VALE Box Activation or Rejection ...
|
|
|
|
//
|
|
bool isCond1Bullish =
|
|
//
|
|
false
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond1Bearish =
|
|
//
|
|
false
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond1 = isCond1Bullish ||
|
|
isCond1Bearish;
|
|
if (isCond1)
|
|
{
|
|
//
|
|
providedSL =
|
|
isCond1Bullish
|
|
? MathMin(pBar.low, pivotBox.lower)
|
|
: MathMax(pBar.high, pivotBox.upper);
|
|
|
|
//
|
|
additionalSL = 0.5 * conditions.atrBuffer[cIDX];
|
|
|
|
//
|
|
Print("Cond1");
|
|
isCond1Bullish = false;
|
|
isCond1Bearish = false;
|
|
}
|
|
|
|
//
|
|
// Cond2 Act Using OSC Box and Vydia ...
|
|
|
|
//
|
|
bool isCond2Bullish =
|
|
//
|
|
false
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond2Bearish =
|
|
//
|
|
false
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond2 = isCond2Bullish ||
|
|
isCond2Bearish;
|
|
if (isCond2)
|
|
{
|
|
//
|
|
providedSL =
|
|
isCond2Bullish
|
|
? MathMin(pBar.low, pivotBox.lower)
|
|
: MathMax(pBar.high, pivotBox.upper);
|
|
|
|
//
|
|
Print("Cond2");
|
|
}
|
|
|
|
//
|
|
// Cond3 Act Using CCi Peaks and Vales ...
|
|
|
|
//
|
|
bool isCond3Bullish =
|
|
//
|
|
false
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond3Bearish =
|
|
//
|
|
false
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond3 = isCond3Bullish ||
|
|
isCond3Bearish;
|
|
if (isCond3)
|
|
{
|
|
//
|
|
providedSL =
|
|
isCond3Bullish
|
|
? MathMin(pBar.low, pivotBox.lower)
|
|
: MathMax(pBar.high, pivotBox.upper);
|
|
|
|
//
|
|
Print("Cond3");
|
|
}
|
|
|
|
//
|
|
// 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 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";
|
|
}
|
|
|
|
//
|
|
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();
|
|
pConditions.Clean();
|
|
rejectedPivot.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Select Inside Boxes ...
|
|
int SelectInsideBoxes(
|
|
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];
|
|
|
|
//
|
|
// Check Box Type ...
|
|
bool isTypePassed =
|
|
//
|
|
iBox.type == GetBoxType(XCA_TREND_BULL) ||
|
|
iBox.type == GetBoxType(XCA_TREND_BEAR)
|
|
//
|
|
;
|
|
if (!isTypePassed)
|
|
{
|
|
//
|
|
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(
|
|
XBoxZone &box,
|
|
XBoxZone &boxes[],
|
|
XOHCL &zBar,
|
|
XOHCL &cBar,
|
|
XOHCL &pBar,
|
|
XOHCL &p2Bar,
|
|
bool forceBarType = false,
|
|
bool forcePressure = false //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
box.Clean();
|
|
|
|
//
|
|
// 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];
|
|
|
|
//
|
|
bool isBullish = iBox.IsBullish();
|
|
bool isBearish = iBox.IsBearish();
|
|
|
|
//
|
|
double boundaryPrice =
|
|
isBullish
|
|
? iBox.upper
|
|
: iBox.lower;
|
|
|
|
//
|
|
double midPrice =
|
|
iBox.lower +
|
|
((iBox.upper - iBox.lower) / 2);
|
|
|
|
//
|
|
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 //
|
|
);
|
|
|
|
//
|
|
bool isBullishRejected =
|
|
isBullish &&
|
|
(isMidBullishRejected ||
|
|
isBoundaryBullishRejected);
|
|
|
|
//
|
|
bool isBearishRejected =
|
|
isBearish &&
|
|
(isMidBearishRejected ||
|
|
isBoundaryBearishRejected);
|
|
|
|
//
|
|
bool isRejected =
|
|
isBullishRejected ||
|
|
isBearishRejected;
|
|
if (isRejected)
|
|
{
|
|
//
|
|
box = iBox;
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
result = box.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
// |