1697 lines
44 KiB
Plaintext
1697 lines
44 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class
|
|
// -------------------------------------------------
|
|
// Name: XCXFIMASignaller ...
|
|
// Description: XFIMA Signaller Class ...
|
|
//
|
|
//
|
|
// 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 XFIMA Signaller Class"
|
|
#property strict
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../../Classes/x-saherelm.x-signaller.class.mq5"
|
|
#include "../../Helpers/x-saherelm.xfima.helper.mq5"
|
|
#include "../Classes/x-saherelm.xfima.x-poi.detector.class.mq5"
|
|
#include "../Classes/x-saherelm.xfima.x-poi.drawer.class.mq5"
|
|
|
|
//
|
|
// Implementation ...
|
|
|
|
//
|
|
// Base XFIMA base Signaller ...
|
|
class XCXFIMABaseSignaller : public XCBaseSignaller
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
XFIMAInputs fimaInputs; // XFIMA Inputs ...
|
|
XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ...
|
|
XCXFIMAPOIDrawer *poiDrawer; // XFIMA POI Drawer ...
|
|
XCXFIMAPOIDetector *poiDetector; // XFIMA POI Detector ...
|
|
|
|
//
|
|
// Constructor ...
|
|
XCXFIMABaseSignaller(
|
|
string _name, // Name ...
|
|
string _symbol, // Symbol ...
|
|
ENUM_TIMEFRAMES _period, // Period ...
|
|
XFIMAInputs &_fimaInputs, // XFIMAInputs ...
|
|
bool _processAllTicks = false, // Process All Ticks ...
|
|
double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ...
|
|
double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ...
|
|
double _defaultSignalVolume = 0.01 // Default Signal Volume ...
|
|
) : XCBaseSignaller(_name,
|
|
_symbol,
|
|
_period,
|
|
_processAllTicks,
|
|
_defaultSignalR2R,
|
|
_defaultSignalRiskInPoint,
|
|
_defaultSignalVolume //
|
|
)
|
|
{
|
|
//
|
|
// Instantiating XFIMA Indicator Helper Class ...
|
|
if (_fimaInputs.IsValid())
|
|
{
|
|
//
|
|
fimaHelper = new XCXFIMAHelper();
|
|
bool isInited = fimaHelper.Init(
|
|
_symbol,
|
|
_period,
|
|
_fimaInputs //
|
|
);
|
|
if (isInited)
|
|
{
|
|
fimaInputs = _fimaInputs;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
delete fimaHelper;
|
|
ZeroMemory(fimaHelper);
|
|
}
|
|
}
|
|
|
|
//
|
|
poiDrawer = new XCXFIMAPOIDrawer();
|
|
poiDetector = new XCXFIMAPOIDetector(fimaHelper);
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XCXFIMABaseSignaller()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
//
|
|
// Overrides ...
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Destroy ...
|
|
*/
|
|
void Destroy()
|
|
{
|
|
//
|
|
BeforeDestroy();
|
|
|
|
//
|
|
fimaInputs.Clean();
|
|
|
|
//
|
|
delete fimaHelper;
|
|
ZeroMemory(fimaHelper);
|
|
|
|
//
|
|
delete poiDrawer;
|
|
ZeroMemory(poiDrawer);
|
|
|
|
//
|
|
delete poiDetector;
|
|
ZeroMemory(poiDetector);
|
|
}
|
|
|
|
//
|
|
// Virtuals ...
|
|
|
|
/**
|
|
* Before Destroy ...
|
|
*/
|
|
void virtual BeforeDestroy()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Processing Tick ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*/
|
|
virtual void ProcessTick(int barIndex = 0)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Processing New Bar ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*/
|
|
virtual void ProcessNewBar(int barIndex = 0)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Check Guards Based on MarketConditions ...
|
|
*
|
|
* @param guards: XGuard[]
|
|
* @param barIndex: int
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int virtual CheckForGuard(
|
|
XGuard &guards[],
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
SpecifiedClean(guards);
|
|
|
|
//
|
|
result = ArraySize(guards);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Additional Validations on Childs Instances ...
|
|
*
|
|
* @return ( bool virtual )
|
|
*/
|
|
bool virtual CheckAdditionslSignallerValidations()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate Fima Helper Requirements ...
|
|
result = fimaInputs.IsValid() &&
|
|
fimaHelper != NULL &&
|
|
poiDetector != NULL;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Normalizing Signal by Signaller Custom Props ...
|
|
*
|
|
* @param signal: XSignal ...
|
|
*/
|
|
void virtual NormalizeSignal(XSignal &signal)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
|
|
//
|
|
// Protected Actions ...
|
|
|
|
/**
|
|
* Check Specified Bar has Pattern or not ...
|
|
*
|
|
* @param bar: XOHCL, reference to Specified Bar ...
|
|
* @param name: string, reference to holds Detected Patterns Name ...
|
|
* @param dir: ENUM_X_DIRECTION, reference to holds Detected Patterns Direction ...
|
|
* @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasPattern(
|
|
XOHCL &bar,
|
|
string &patternName,
|
|
ENUM_X_DIRECTION &patternDir,
|
|
XFIMAMarketStructure &structure //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
patternName = NULL;
|
|
patternDir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Validate ...
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Required Pattern Exists ...
|
|
bool hasPinnedBar = HasDirection(structure.pinnedDir);
|
|
bool hasEngulfedBar = HasDirection(structure.engulfedDir);
|
|
bool hasFlagPattern = HasDirection(structure.flagPatternDir);
|
|
bool hasStarPattern = HasDirection(structure.starPatternDir);
|
|
bool hasRisingPattern = HasDirection(structure.risingPatternDir);
|
|
bool hasPiercingPattern = HasDirection(structure.piercingPatternDir);
|
|
bool hasSignalKeyBar = HasDirection(structure.signalKeyBarPatternDir);
|
|
|
|
//
|
|
// Check Bar Pattern Exists ...
|
|
// and Select Pattern Direction and Price and Price Type ...
|
|
result = hasPinnedBar ||
|
|
hasEngulfedBar ||
|
|
hasFlagPattern ||
|
|
hasStarPattern ||
|
|
hasSignalKeyBar ||
|
|
hasRisingPattern ||
|
|
hasPiercingPattern;
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
if (hasPinnedBar)
|
|
{
|
|
//
|
|
patternDir = structure.pinnedDir;
|
|
patternName = "XPinned_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
else if (hasEngulfedBar)
|
|
{
|
|
//
|
|
patternDir = structure.engulfedDir;
|
|
patternName = "XEngulfed_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
else if (hasFlagPattern)
|
|
{
|
|
//
|
|
patternDir = structure.flagPatternDir;
|
|
patternName = "XFlag_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
else if (hasStarPattern)
|
|
{
|
|
//
|
|
patternDir = structure.starPatternDir;
|
|
patternName = "XStar_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
else if (hasSignalKeyBar)
|
|
{
|
|
//
|
|
patternDir = structure.risingPatternDir;
|
|
patternName = "XRising_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
else if (hasRisingPattern)
|
|
{
|
|
//
|
|
patternDir = structure.piercingPatternDir;
|
|
patternName = "XPiercing_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
else if (hasPiercingPattern)
|
|
{
|
|
//
|
|
patternDir = structure.signalKeyBarPatternDir;
|
|
patternName = "XSignalKey_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
}
|
|
|
|
//
|
|
result =
|
|
result &&
|
|
IsXValid(patternName) &&
|
|
HasDirection(patternDir);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Validate a Pattern based on MA Band ...
|
|
*
|
|
* @param bar: XOHCL, reference to Pattern Bar ...
|
|
* @param patternName: string, detected pattern's name ...
|
|
* @param patternDir: ENUM_X_DIRECTION, detected pattern's direction ...
|
|
* @param fimaConditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool ValidatePatternBasedOnMABand(
|
|
XOHCL &bar,
|
|
string patternName,
|
|
ENUM_X_DIRECTION patternDir,
|
|
XFIMAConditions &fimaConditions //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate ...
|
|
result = bar.IsValid() &&
|
|
IsXValid(patternName) &&
|
|
HasDirection(patternDir);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Define Requirements ...
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
double iPrice = EMPTY_VALUE;
|
|
double iPriceEdge = EMPTY_VALUE;
|
|
ENUM_X_PRICE iPriceType = X_PRICE_NONE;
|
|
ENUM_X_PRICE iPriceEdgeType = X_PRICE_NONE;
|
|
|
|
//
|
|
// Calculating Price and Price Types ...
|
|
|
|
//
|
|
isBullish = IsXBullish(patternDir);
|
|
isBearish = IsXBearish(patternDir);
|
|
|
|
//
|
|
iPriceType = isBullish
|
|
? X_PRICE_DOWN
|
|
: X_PRICE_UP;
|
|
|
|
//
|
|
iPriceEdgeType = isBullish
|
|
? X_PRICE_LOW
|
|
: X_PRICE_HIGH;
|
|
|
|
//
|
|
iPrice = bar.GetPrice(iPriceType);
|
|
iPriceEdge = bar.GetPrice(iPriceEdgeType);
|
|
|
|
//
|
|
// Validate ...
|
|
result =
|
|
NotEmptyZero(iPrice) &&
|
|
IsXValid(iPriceType) &&
|
|
NotEmptyZero(iPriceEdge) &&
|
|
IsXValid(iPriceEdgeType) &&
|
|
((isBullish && !isBearish) ||
|
|
(isBearish && !isBullish));
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Validate Pattern based on MA Band ...
|
|
|
|
//
|
|
// Retrieve MA Band for Validation ...
|
|
double iMABandUpper = fimaConditions.maBandUpperBuffer[0];
|
|
double iMABandLower = fimaConditions.maBandLowerBuffer[0];
|
|
|
|
//
|
|
// Validate by Edge Price ...
|
|
result =
|
|
NotEmptyZero(iMABandUpper) &&
|
|
NotEmptyZero(iMABandLower) &&
|
|
(isBullish
|
|
? iPriceEdge < iMABandLower
|
|
: iPriceEdge > iMABandUpper);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
};
|
|
|
|
//
|
|
// XFIMA Strategy 1 Signaller Class ...
|
|
class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Props ...
|
|
int fvgLookupLenght; // Maximum Lenght for Looking up FVG before Crosses
|
|
|
|
//
|
|
// Constructor ...
|
|
XCXFIMAStrategy1Signaller(
|
|
string _symbol, // Symbol ...
|
|
ENUM_TIMEFRAMES _period, // Period ...
|
|
XFIMAInputs &_fimaInputs, // XFIMAInputs ...
|
|
bool _processAllTicks = false, // Process All Ticks ...
|
|
double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ...
|
|
double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ...
|
|
double _defaultSignalVolume = 0.01 // Default Signal Volume ...
|
|
) : XCXFIMABaseSignaller("XFIMA1",
|
|
_symbol,
|
|
_period,
|
|
_fimaInputs,
|
|
_processAllTicks,
|
|
_defaultSignalR2R,
|
|
_defaultSignalRiskInPoint,
|
|
_defaultSignalVolume //
|
|
)
|
|
{
|
|
//
|
|
fvgLookupLenght = 5;
|
|
}
|
|
|
|
//
|
|
// Overrides ...
|
|
|
|
/**
|
|
* Processing Tick ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*/
|
|
virtual void ProcessTick(int barIndex = 0)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Processing New Bar ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*/
|
|
virtual void ProcessNewBar(int barIndex = 0)
|
|
{
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
|
|
//
|
|
XOHCL bar;
|
|
XSignal signal;
|
|
bool has = false;
|
|
int cIdx = barIndex + 1;
|
|
int pIdx = cIdx + 1;
|
|
ENUM_X_DIRECTION signalDir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Initialize Bar as CBar ...
|
|
has = bar.Init(
|
|
symbol,
|
|
period,
|
|
cIdx //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Retrieve Conditions ...
|
|
XFIMAConditions fimaConditions;
|
|
has = fimaHelper.GetConditions(
|
|
fimaConditions,
|
|
barIndex,
|
|
10 // Loopback ...
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
fimaConditions.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Analyse Conditions for Finding Signal ...
|
|
|
|
//
|
|
// TODO: Remove this ...
|
|
|
|
//
|
|
bool isFastCrossedOverSlow =
|
|
fimaConditions.maFastBuffer[cIdx] > fimaConditions.maSlowBuffer[cIdx] &&
|
|
fimaConditions.maFastBuffer[pIdx] < fimaConditions.maSlowBuffer[pIdx];
|
|
|
|
//
|
|
bool isFastCrossedUnderSlow =
|
|
fimaConditions.maFastBuffer[cIdx] < fimaConditions.maSlowBuffer[cIdx] &&
|
|
fimaConditions.maFastBuffer[pIdx] > fimaConditions.maSlowBuffer[pIdx];
|
|
|
|
//
|
|
has =
|
|
isFastCrossedOverSlow ||
|
|
isFastCrossedUnderSlow;
|
|
if (has)
|
|
{
|
|
//
|
|
// Do Conditions Validating ...
|
|
// TODO: Igmore All Validations for Testing Purposes ...
|
|
|
|
//
|
|
// Validate MA Positions ...
|
|
double iFastMa = fimaConditions.maFastBuffer[cIdx];
|
|
double iSlowMa = fimaConditions.maSlowBuffer[cIdx];
|
|
double iFiboUpper = fimaConditions.fiboUpperBuffer[cIdx];
|
|
double iFiboLower = fimaConditions.fiboLowerBuffer[cIdx];
|
|
|
|
//
|
|
// Checking Has FVG ...
|
|
XBoxZone fvg;
|
|
ENUM_X_DIRECTION fvgDir;
|
|
bool hasFVG = patternDetector.HasFVG(
|
|
bar,
|
|
fvgDir,
|
|
fvg,
|
|
fvgLookupLenght //
|
|
);
|
|
|
|
//
|
|
// Checking Crossed On Shadow ...
|
|
|
|
//
|
|
bool isCrossedOverHappensOnShadow =
|
|
isFastCrossedOverSlow &&
|
|
iFastMa <= bar.GetDown() &&
|
|
iFastMa >= bar.low;
|
|
|
|
//
|
|
bool isCrossedUnderHappensOnShadow =
|
|
isFastCrossedUnderSlow &&
|
|
iFastMa <= bar.high &&
|
|
iFastMa >= bar.GetUp();
|
|
|
|
//
|
|
// Bullish Validation ...
|
|
bool isBullish =
|
|
//
|
|
// Has Cross ...
|
|
isFastCrossedOverSlow
|
|
//
|
|
// &&
|
|
// //
|
|
// // Cross Places Based on Fibo ...
|
|
// MathMax(iFastMa, iSlowMa) < iFiboLower
|
|
// //
|
|
// &&
|
|
// //
|
|
// (
|
|
// //
|
|
// // Checking FVG ...
|
|
// (hasFVG &&
|
|
// fvg.IsBullish())
|
|
// //
|
|
// ||
|
|
// //
|
|
// // Checking Crossed Place ...
|
|
// isCrossedOverHappensOnShadow
|
|
// //
|
|
// )
|
|
// //
|
|
;
|
|
|
|
//
|
|
// Bearish Validation ...
|
|
bool isBearish =
|
|
//
|
|
// Has Cross ...
|
|
isFastCrossedUnderSlow
|
|
//
|
|
// &&
|
|
// //
|
|
// // Cross Places Based on Fibo ...
|
|
// MathMin(iFastMa, iSlowMa) > iFiboUpper
|
|
// //
|
|
// &&
|
|
// //
|
|
// (
|
|
// //
|
|
// // Checking FVG ...
|
|
// (hasFVG &&
|
|
// fvg.IsBearish())
|
|
// //
|
|
// ||
|
|
// //
|
|
// // Checking Crossed Place ...
|
|
// isCrossedUnderHappensOnShadow
|
|
// //
|
|
// )
|
|
// //
|
|
;
|
|
|
|
//
|
|
has =
|
|
(isBullish && !isBearish) ||
|
|
(isBearish && !isBullish);
|
|
if (has)
|
|
{
|
|
//
|
|
signalDir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Signal Founded ...
|
|
has = HasDirection(signalDir);
|
|
if (has)
|
|
{
|
|
//
|
|
// Prepare Founded Signal ...
|
|
XTarget targets[];
|
|
has = PrepareSignal(
|
|
signal,
|
|
signalDir,
|
|
targets //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Notify On Signal Event ...
|
|
NotifySignalEventListeners(signal);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
bar.Clean();
|
|
signal.Clean();
|
|
fimaConditions.Clean();
|
|
}
|
|
|
|
/**
|
|
* Check Guards Based on MarketConditions ...
|
|
*
|
|
* @param guards: XGuard[]
|
|
* @param barIndex: int
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int virtual CheckForGuard(
|
|
XGuard &guards[],
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
SpecifiedClean(guards);
|
|
|
|
//
|
|
result = ArraySize(guards);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Lookup FVG ...
|
|
bool LookupFVG(
|
|
XOHCL &bar,
|
|
ENUM_X_DIRECTION &dir,
|
|
XBoxZone &fvgBox //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
// XFIMA Strategy 2 Signaller Class ...
|
|
class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Props ...
|
|
XFIMAPatternDetectorConfig analyserConfig;
|
|
|
|
//
|
|
// Constructor ...
|
|
XCXFIMAStrategy2Signaller(
|
|
string _symbol, // Symbol ...
|
|
ENUM_TIMEFRAMES _period, // Period ...
|
|
XFIMAInputs &_fimaInputs, // XFIMAInputs ...
|
|
bool _processAllTicks = false, // Process All Ticks ...
|
|
double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ...
|
|
double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ...
|
|
double _defaultSignalVolume = 0.01 // Default Signal Volume ...
|
|
) : XCXFIMABaseSignaller("XFIMA2",
|
|
_symbol,
|
|
_period,
|
|
_fimaInputs,
|
|
_processAllTicks,
|
|
_defaultSignalR2R,
|
|
_defaultSignalRiskInPoint,
|
|
_defaultSignalVolume //
|
|
)
|
|
{
|
|
//
|
|
// Configure Detector ...
|
|
//
|
|
analyserConfig.Default();
|
|
analyserConfig.validMACrossDiffMultiplier = 4;
|
|
|
|
//
|
|
analyserConfig.FullDetect();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XCXFIMAStrategy2Signaller()
|
|
{
|
|
//
|
|
Destroy();
|
|
|
|
//
|
|
analyserConfig.Clean();
|
|
}
|
|
|
|
//
|
|
// Overrides ...
|
|
|
|
/**
|
|
* Processing Tick ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*/
|
|
virtual void ProcessTick(int barIndex = 0)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Processing New Bar ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*/
|
|
virtual void ProcessNewBar(int barIndex = 0)
|
|
{
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
|
|
//
|
|
XOHCL iBar;
|
|
int count = 0;
|
|
XBoxZone iZone;
|
|
XSignal iSignal;
|
|
bool has = false;
|
|
XTarget targets[];
|
|
string iName = NULL;
|
|
XBoxZone supports[];
|
|
XBoxZone resistances[];
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
int numberOfPivots = 25;
|
|
XFIMAConditions iFIMAConditions;
|
|
XFIMAMarketStructure iStructure;
|
|
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
XPivot pvPivots[];
|
|
string pvTrendName = "XXIFMA2PVTrend";
|
|
CChartObjectTrend *pvTrendLine = NULL;
|
|
ENUM_X_DIRECTION pvTrend = X_DIRECTION_NONE;
|
|
|
|
//
|
|
XPivot zgPivots[];
|
|
string zgTrendName = "XFIMA2ZGTrend";
|
|
CChartObjectTrend *zgTrendLine = NULL;
|
|
ENUM_X_DIRECTION zgTrend = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Initialize Bar as CBar ...
|
|
has = iBar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Retrieve Conditions ...
|
|
has = fimaHelper.GetConditions(
|
|
iFIMAConditions,
|
|
barIndex,
|
|
10 // Loopback ...
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
iFIMAConditions.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Analyse Market ...
|
|
poiDetector.AnalyseMarket(
|
|
iBar,
|
|
iStructure,
|
|
analyserConfig //
|
|
);
|
|
|
|
//
|
|
// Collect Support and Resistance Zones and Validate by them ...
|
|
|
|
//
|
|
// PV Trend Line ...
|
|
bool hasPVAnalysis = iStructure.pvAnalysis.IsValid();
|
|
if (hasPVAnalysis)
|
|
{
|
|
//
|
|
// Support ...
|
|
XBoxZone supportBox;
|
|
has = iStructure.pvAnalysis.HasSupportBox(supportBox);
|
|
if (has)
|
|
{
|
|
//
|
|
supportBox.to = iBar.time;
|
|
AddIfNotExists(
|
|
supportBox,
|
|
supports //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
XBoxZone resistanceBox;
|
|
has = iStructure.pvAnalysis.HasResistanceBox(resistanceBox);
|
|
if (has)
|
|
{
|
|
//
|
|
resistanceBox.to = iBar.time;
|
|
AddIfNotExists(
|
|
resistanceBox,
|
|
supports //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Pivots ...
|
|
XPivot pivots[];
|
|
count = poiDetector.ExtractPVPivots(
|
|
pivots,
|
|
barIndex,
|
|
numberOfPivots //
|
|
);
|
|
has = IsValidSize(count);
|
|
|
|
//
|
|
// Sort ...
|
|
Sort(
|
|
pivots,
|
|
X_SORT_BY_DATE,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
// Remove Newest ...
|
|
ArrayRemove(
|
|
pivots,
|
|
0,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Check Trend ...
|
|
if (has)
|
|
{
|
|
//
|
|
XPivot highs[];
|
|
int highsCount = ExtractPivots(
|
|
highs,
|
|
pivots,
|
|
X_PIVOT_TYPE_PEAK //
|
|
);
|
|
Sort(
|
|
highs,
|
|
X_SORT_BY_DATE,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
XPivot lows[];
|
|
int lowsCount = ExtractPivots(
|
|
lows,
|
|
pivots,
|
|
X_PIVOT_TYPE_VALE //
|
|
);
|
|
Sort(
|
|
lows,
|
|
X_SORT_BY_DATE,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
// Check Highs and Lows ...
|
|
has = IsValidSize(lowsCount) &&
|
|
IsValidSize(highsCount) &&
|
|
lowsCount >= 2 &&
|
|
highsCount >= 2;
|
|
if (has)
|
|
{
|
|
//
|
|
// Try to Get Market Strucutre ...
|
|
|
|
//
|
|
bool hasLowerHigh = highs[0].value < highs[1].value;
|
|
bool hasLowerLow = lows[0].value < lows[1].value;
|
|
|
|
//
|
|
bool hasHigherHigh = highs[0].value > highs[1].value;
|
|
bool hasHigherLow = lows[0].value > lows[1].value;
|
|
|
|
//
|
|
pvTrend =
|
|
(hasHigherHigh &&
|
|
hasHigherLow)
|
|
? X_DIRECTION_BULLISH
|
|
: (hasLowerHigh &&
|
|
hasLowerLow)
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
has = HasDirection(pvTrend);
|
|
if (has)
|
|
{
|
|
//
|
|
// Select Swings for Trend Line ...
|
|
XOHCL tmpBar;
|
|
int llIDX = -1;
|
|
int hhIDX = -1;
|
|
datetime toTime = NULL;
|
|
datetime fromTime = NULL;
|
|
double toPrice = EMPTY_VALUE;
|
|
color trendColor = CLR_NONE;
|
|
double fromPrice = EMPTY_VALUE;
|
|
if (IsSpecifiedBullish(pvTrend))
|
|
{
|
|
//
|
|
llIDX = GetLowest(lows);
|
|
hhIDX = GetHighest(lows);
|
|
|
|
//
|
|
trendColor = clrAqua;
|
|
|
|
//
|
|
toTime = lows[hhIDX].time;
|
|
toPrice = lows[hhIDX].value;
|
|
|
|
//
|
|
fromTime = lows[llIDX].time;
|
|
fromPrice = lows[llIDX].value;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
llIDX = GetLowest(highs);
|
|
hhIDX = GetHighest(highs);
|
|
|
|
//
|
|
trendColor = clrMagenta;
|
|
|
|
//
|
|
toTime = highs[llIDX].time;
|
|
toPrice = highs[llIDX].value;
|
|
|
|
//
|
|
fromTime = highs[hhIDX].time;
|
|
fromPrice = highs[hhIDX].value;
|
|
}
|
|
|
|
//
|
|
// Check Requirements for Trend ...
|
|
has =
|
|
NotEmptyZero(toPrice) &&
|
|
NotEmptyZero(fromPrice) &&
|
|
IsSpecifiedValid(toTime) &&
|
|
IsSpecifiedValid(fromTime);
|
|
if (has)
|
|
{
|
|
//
|
|
has = poiDrawer.DrawTrendLine(
|
|
fromPrice,
|
|
fromTime,
|
|
toPrice,
|
|
toTime,
|
|
pvTrendLine,
|
|
pvTrendName,
|
|
true // Ray Right ...
|
|
);
|
|
if (has)
|
|
{
|
|
pvTrendLine.Color(trendColor);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
tmpBar.Clean();
|
|
}
|
|
|
|
//
|
|
if (!has)
|
|
{
|
|
SpecifiedClean(pivots);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
SpecifiedClean(lows);
|
|
SpecifiedClean(highs);
|
|
}
|
|
|
|
//
|
|
has = HasChild(pivots);
|
|
if (has)
|
|
{
|
|
//
|
|
Copy(
|
|
pivots,
|
|
pvPivots //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
SpecifiedClean(pivots);
|
|
}
|
|
|
|
//
|
|
// ZigZag Trend Line ...
|
|
bool hasZGAnalysis = iStructure.zigzagAnalysis.IsValid();
|
|
if (hasZGAnalysis)
|
|
{
|
|
//
|
|
// Support ...
|
|
XBoxZone supportBox;
|
|
has = iStructure.zigzagAnalysis.HasSupportBox(supportBox);
|
|
if (has)
|
|
{
|
|
//
|
|
supportBox.to = iBar.time;
|
|
AddIfNotExists(
|
|
supportBox,
|
|
supports //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
XBoxZone resistanceBox;
|
|
has = iStructure.zigzagAnalysis.HasResistanceBox(resistanceBox);
|
|
if (has)
|
|
{
|
|
//
|
|
resistanceBox.to = iBar.time;
|
|
AddIfNotExists(
|
|
resistanceBox,
|
|
supports //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Pivots ...
|
|
XPivot pivots[];
|
|
count = poiDetector.ExtractZigZagPivots(
|
|
pivots,
|
|
barIndex,
|
|
numberOfPivots //
|
|
);
|
|
has = IsValidSize(count);
|
|
|
|
//
|
|
// Sort ...
|
|
Sort(
|
|
pivots,
|
|
X_SORT_BY_DATE,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
// Remove Newest ...
|
|
ArrayRemove(
|
|
pivots,
|
|
0,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Check Trend ...
|
|
if (has)
|
|
{
|
|
//
|
|
XPivot highs[];
|
|
int highsCount = ExtractPivots(
|
|
highs,
|
|
pivots,
|
|
X_PIVOT_TYPE_PEAK //
|
|
);
|
|
Sort(
|
|
highs,
|
|
X_SORT_BY_DATE,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
XPivot lows[];
|
|
int lowsCount = ExtractPivots(
|
|
lows,
|
|
pivots,
|
|
X_PIVOT_TYPE_VALE //
|
|
);
|
|
Sort(
|
|
lows,
|
|
X_SORT_BY_DATE,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
// Check Highs and Lows ...
|
|
has = IsValidSize(lowsCount) &&
|
|
IsValidSize(highsCount) &&
|
|
lowsCount >= 2 &&
|
|
highsCount >= 2;
|
|
if (has)
|
|
{
|
|
//
|
|
// Try to Get Market Strucutre ...
|
|
|
|
//
|
|
bool hasLowerHigh = highs[0].value < highs[1].value;
|
|
bool hasLowerLow = lows[0].value < lows[1].value;
|
|
|
|
//
|
|
bool hasHigherHigh = highs[0].value > highs[1].value;
|
|
bool hasHigherLow = lows[0].value > lows[1].value;
|
|
|
|
//
|
|
zgTrend =
|
|
(hasHigherHigh &&
|
|
hasHigherLow)
|
|
? X_DIRECTION_BULLISH
|
|
: (hasLowerHigh &&
|
|
hasLowerLow)
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
has = HasDirection(zgTrend);
|
|
if (has)
|
|
{
|
|
//
|
|
// Select Swings for Trend Line ...
|
|
XOHCL tmpBar;
|
|
int llIDX = -1;
|
|
int hhIDX = -1;
|
|
datetime toTime = NULL;
|
|
datetime fromTime = NULL;
|
|
double toPrice = EMPTY_VALUE;
|
|
color trendColor = CLR_NONE;
|
|
double fromPrice = EMPTY_VALUE;
|
|
if (IsSpecifiedBullish(zgTrend))
|
|
{
|
|
//
|
|
llIDX = GetLowest(lows);
|
|
hhIDX = GetHighest(lows);
|
|
|
|
//
|
|
trendColor = clrAqua;
|
|
|
|
//
|
|
toTime = lows[hhIDX].time;
|
|
toPrice = lows[hhIDX].value;
|
|
|
|
//
|
|
fromTime = lows[llIDX].time;
|
|
fromPrice = lows[llIDX].value;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
llIDX = GetLowest(highs);
|
|
hhIDX = GetHighest(highs);
|
|
|
|
//
|
|
trendColor = clrMagenta;
|
|
|
|
//
|
|
toTime = highs[llIDX].time;
|
|
toPrice = highs[llIDX].value;
|
|
|
|
//
|
|
fromTime = highs[hhIDX].time;
|
|
fromPrice = highs[hhIDX].value;
|
|
}
|
|
|
|
//
|
|
// Check Requirements for Trend ...
|
|
has =
|
|
NotEmptyZero(toPrice) &&
|
|
NotEmptyZero(fromPrice) &&
|
|
IsSpecifiedValid(toTime) &&
|
|
IsSpecifiedValid(fromTime);
|
|
if (has)
|
|
{
|
|
//
|
|
has = poiDrawer.DrawTrendLine(
|
|
fromPrice,
|
|
fromTime,
|
|
toPrice,
|
|
toTime,
|
|
zgTrendLine,
|
|
zgTrendName,
|
|
true // Ray Right ...
|
|
);
|
|
if (has)
|
|
{
|
|
zgTrendLine.Color(trendColor);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
tmpBar.Clean();
|
|
}
|
|
|
|
//
|
|
if (!has)
|
|
{
|
|
SpecifiedClean(pivots);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
SpecifiedClean(lows);
|
|
SpecifiedClean(highs);
|
|
}
|
|
|
|
//
|
|
has = HasChild(pivots);
|
|
if (has)
|
|
{
|
|
//
|
|
Copy(
|
|
pivots,
|
|
zgPivots //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
SpecifiedClean(pivots);
|
|
}
|
|
|
|
//
|
|
// Support ...
|
|
bool hasSupport = iStructure.support.IsValid();
|
|
if (hasSupport)
|
|
{
|
|
//
|
|
iStructure.support.to = iBar.time;
|
|
AddIfNotExists(
|
|
iStructure.support,
|
|
supports //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
bool hasResistance = iStructure.resistance.IsValid();
|
|
if (hasResistance)
|
|
{
|
|
//
|
|
iStructure.resistance.to = iBar.time;
|
|
AddIfNotExists(
|
|
iStructure.resistance,
|
|
resistances //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Disable Signallers ...
|
|
has = false;
|
|
|
|
//
|
|
// Strategy 1 ...
|
|
// Works on Support or Resistances Areas ...
|
|
// has = Strategy1HasSignal(
|
|
// iBar,
|
|
// iZone,
|
|
// supports,
|
|
// resistances,
|
|
// iDir,
|
|
// iStructure,
|
|
// iFIMAConditions //
|
|
// );
|
|
|
|
//
|
|
// Strategy 2 ...
|
|
// Works on MA Crosses ...
|
|
has = Strategy2HasSignal(
|
|
iBar,
|
|
iZone,
|
|
supports,
|
|
resistances,
|
|
iDir,
|
|
iStructure,
|
|
iFIMAConditions //
|
|
);
|
|
|
|
//
|
|
has = HasDirection(iDir);
|
|
if (has)
|
|
{
|
|
//
|
|
isBullish = IsXBullish(iDir);
|
|
isBearish = IsXBearish(iDir);
|
|
|
|
//
|
|
// TODO: Provided SL ...
|
|
double _point = GetPoints(iBar.symbol);
|
|
double slAddition = 5 * _point;
|
|
double slPrice =
|
|
isBullish
|
|
? iZone.lower - slAddition
|
|
: iZone.upper + slAddition;
|
|
|
|
//
|
|
// Prepare Founded Signal ...
|
|
has = PrepareSignal(
|
|
iSignal,
|
|
iDir,
|
|
targets,
|
|
0, // Use Default R2R ...
|
|
slPrice, // Provided Price for SL ...
|
|
0 // Specified Risk in Point ....
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Notify On Signal Event ...
|
|
NotifySignalEventListeners(iSignal);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iBar.Clean();
|
|
iZone.Clean();
|
|
iSignal.Clean();
|
|
iStructure.Clean();
|
|
iFIMAConditions.Clean();
|
|
SpecifiedClean(targets);
|
|
SpecifiedClean(pvPivots);
|
|
SpecifiedClean(zgPivots);
|
|
SpecifiedClean(supports);
|
|
SpecifiedClean(resistances);
|
|
}
|
|
|
|
/**
|
|
* Check Guards Based on MarketConditions ...
|
|
*
|
|
* @param guards: XGuard[]
|
|
* @param barIndex: int
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int virtual CheckForGuard(
|
|
XGuard &guards[],
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
SpecifiedClean(guards);
|
|
|
|
//
|
|
result = ArraySize(guards);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Implementing Strategies ...
|
|
|
|
/**
|
|
* Check Bar Has Signal Based on Strategy 1 ...
|
|
*
|
|
* @param bar: XOHCL, reference to Bar ...
|
|
* @param iZone: XBoxZone, reference to holds affected zone ...
|
|
* @param supports: XBoxZone, array reference to Provide Exists Supports ...
|
|
* @param resistances: XBoxZone, array reference to Provide Exists Resistances ...
|
|
* @param iDir: ENUM_X_DIRECTION, detected Signal's direction ...
|
|
* @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ...
|
|
* @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Strategy1HasSignal(
|
|
XOHCL &bar,
|
|
XBoxZone &iZone,
|
|
XBoxZone &supports[],
|
|
XBoxZone &resistances[],
|
|
ENUM_X_DIRECTION &iDir,
|
|
XFIMAMarketStructure &structure,
|
|
XFIMAConditions &conditions //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
iZone.Clean();
|
|
iDir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Validate ...
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Pattern Exists ...
|
|
string patternName = NULL;
|
|
ENUM_X_DIRECTION patternDir = X_DIRECTION_NONE;
|
|
result = HasPattern(
|
|
bar,
|
|
patternName,
|
|
patternDir,
|
|
structure //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Validate Pattern Based on MA Band ...
|
|
result = ValidatePatternBasedOnMABand(
|
|
bar,
|
|
patternName,
|
|
patternDir,
|
|
conditions //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Affected Zone ...
|
|
// Select a Support or Resistance ...
|
|
int insideZoneIDX = -1;
|
|
result =
|
|
(IsXBullish(patternDir)
|
|
? HasInside(
|
|
insideZoneIDX,
|
|
bar,
|
|
supports //
|
|
)
|
|
: IsXBearish(patternDir)
|
|
? HasInside(
|
|
insideZoneIDX,
|
|
bar,
|
|
resistances //
|
|
)
|
|
: false //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Filling Affected Zone ...
|
|
// and Validate it ...
|
|
if (IsXBullish(patternDir))
|
|
{
|
|
iZone = supports[insideZoneIDX];
|
|
}
|
|
else if (IsXBearish(patternDir))
|
|
{
|
|
iZone = resistances[insideZoneIDX];
|
|
}
|
|
result = iZone.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Validate affected Zone based on Pattern's Bar ...
|
|
result = IsXBullish(patternDir)
|
|
? bar.high > iZone.upper
|
|
: IsXBearish(patternDir)
|
|
? bar.low < iZone.lower
|
|
: false;
|
|
if (result)
|
|
{
|
|
iDir = patternDir;
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
if (!result)
|
|
{
|
|
iZone.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Bar Has Signal Based on Strategy 1 ...
|
|
*
|
|
* @param bar: XOHCL, reference to Bar ...
|
|
* @param iZone: XBoxZone, reference to holds affected zone ...
|
|
* @param supports: XBoxZone, array reference to Provide Exists Supports ...
|
|
* @param resistances: XBoxZone, array reference to Provide Exists Resistances ...
|
|
* @param iDir: ENUM_X_DIRECTION, detected Signal's direction ...
|
|
* @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ...
|
|
* @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Strategy2HasSignal(
|
|
XOHCL &bar,
|
|
XBoxZone &iZone,
|
|
XBoxZone &supports[],
|
|
XBoxZone &resistances[],
|
|
ENUM_X_DIRECTION &iDir,
|
|
XFIMAMarketStructure &structure,
|
|
XFIMAConditions &conditions //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
iZone.Clean();
|
|
iDir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Validate ...
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Specified MA Cross ...
|
|
result = HasDirection(structure.maCrossDir);
|
|
|
|
//
|
|
// Validate Conditions ...
|
|
|
|
//
|
|
// Prepare iZone ...
|
|
iZone.to = bar.time;
|
|
iZone.from = GetBarTime(
|
|
bar.symbol,
|
|
bar.period,
|
|
bar.Index() + 2 //
|
|
);
|
|
iZone.symbol = bar.symbol;
|
|
iZone.period = bar.period;
|
|
iZone.dir = structure.maCrossDir;
|
|
iZone.lower = bar.FindLowest(2, MODE_LOW);
|
|
iZone.upper = bar.FindHighest(2, MODE_HIGH);
|
|
iZone.type = name + "_" + ToXString(structure.maCrossDir);
|
|
|
|
//
|
|
// Check Result ...
|
|
result = iZone.IsValid();
|
|
if (result)
|
|
{
|
|
iDir = structure.maCrossDir;
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
if (!result)
|
|
{
|
|
iZone.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
// |