also i have to implement it's usage on XCExpert Class ... extends XTarget approaches and add support to Distances ...
1097 lines
27 KiB
Plaintext
1097 lines
27 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 2 Signaller Class ...
|
|
class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Props ...
|
|
XFIMAPatternDetectorConfig analyserConfig;
|
|
|
|
//
|
|
// 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 //
|
|
)
|
|
{
|
|
//
|
|
// Configure Detector ...
|
|
//
|
|
analyserConfig.Default();
|
|
analyserConfig.validMACrossDiffMultiplier = 4;
|
|
|
|
//
|
|
analyserConfig.FullDetect();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XCXFIMAStrategy1Signaller()
|
|
{
|
|
//
|
|
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 iTargets[];
|
|
string iName = NULL;
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
XFIMAConditions iFIMAConditions;
|
|
XFIMAMarketStructure iStructure;
|
|
ENUM_X_DIRECTION iDir = 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 //
|
|
);
|
|
|
|
//
|
|
// Disable Signallers ...
|
|
has = false;
|
|
|
|
//
|
|
// Strategy 1 ...
|
|
// Works on Support or Resistances Areas ...
|
|
has = Strategy1HasSignal(
|
|
iBar,
|
|
iZone,
|
|
iTargets,
|
|
iDir,
|
|
iFIMAConditions,
|
|
iStructure //
|
|
);
|
|
|
|
//
|
|
// Strategy 2 ...
|
|
// Works on MA Crosses ...
|
|
if (!has)
|
|
{
|
|
//
|
|
// has = Strategy2HasSignal(
|
|
// iBar,
|
|
// iZone,
|
|
// iTargets,
|
|
// iDir,
|
|
// iFIMAConditions,
|
|
// iStructure //
|
|
// );
|
|
}
|
|
|
|
//
|
|
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,
|
|
iTargets,
|
|
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(iTargets);
|
|
}
|
|
|
|
/**
|
|
* 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 zone: XBoxZone, reference to holds affected zone ...
|
|
* @param targets: XTarget, reference to detected Signal's Targets collections ...
|
|
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
|
|
* @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
|
|
* @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Strategy1HasSignal(
|
|
XOHCL &bar,
|
|
XBoxZone &zone,
|
|
XTarget &targets[],
|
|
ENUM_X_DIRECTION &dir,
|
|
XFIMAConditions &conditions,
|
|
XFIMAMarketStructure &structure //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
zone.Clean();
|
|
XClean(targets);
|
|
dir = 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;
|
|
}
|
|
|
|
//
|
|
// Here i Use Specified Supports and Resistances ...
|
|
XBoxZone tmpBox;
|
|
bool has = false;
|
|
XBoxZone supports[];
|
|
XBoxZone resistances[];
|
|
|
|
//
|
|
has = structure.pvAnalysis.IsValid() &&
|
|
structure.pvAnalysis.HasSupportBox(tmpBox);
|
|
if (has)
|
|
{
|
|
//
|
|
tmpBox.to = bar.time;
|
|
AddIfNotExists(
|
|
tmpBox,
|
|
supports //
|
|
);
|
|
}
|
|
|
|
//
|
|
has = structure.zigzagAnalysis.IsValid() &&
|
|
structure.zigzagAnalysis.HasSupportBox(tmpBox);
|
|
if (has)
|
|
{
|
|
//
|
|
tmpBox.to = bar.time;
|
|
AddIfNotExists(
|
|
tmpBox,
|
|
supports //
|
|
);
|
|
}
|
|
|
|
//
|
|
has = structure.pvAnalysis.IsValid() &&
|
|
structure.pvAnalysis.HasResistanceBox(tmpBox);
|
|
if (has)
|
|
{
|
|
//
|
|
tmpBox.to = bar.time;
|
|
AddIfNotExists(
|
|
tmpBox,
|
|
resistances //
|
|
);
|
|
}
|
|
|
|
//
|
|
has = structure.zigzagAnalysis.IsValid() &&
|
|
structure.zigzagAnalysis.HasResistanceBox(tmpBox);
|
|
if (has)
|
|
{
|
|
//
|
|
tmpBox.to = bar.time;
|
|
AddIfNotExists(
|
|
tmpBox,
|
|
resistances //
|
|
);
|
|
}
|
|
|
|
//
|
|
// 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))
|
|
{
|
|
zone = supports[insideZoneIDX];
|
|
}
|
|
else if (IsXBearish(patternDir))
|
|
{
|
|
zone = resistances[insideZoneIDX];
|
|
}
|
|
result = zone.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Validate affected Zone based on Pattern's Bar ...
|
|
result = IsXBullish(patternDir)
|
|
? bar.high > zone.upper
|
|
: IsXBearish(patternDir)
|
|
? bar.low < zone.lower
|
|
: false;
|
|
if (result)
|
|
{
|
|
//
|
|
dir = patternDir;
|
|
|
|
//
|
|
// Handle Targets Detection ...
|
|
|
|
//
|
|
// Check Reversal FVGS ...
|
|
int idx = -1;
|
|
XTarget target;
|
|
XBoxZone targetZones[];
|
|
int numberOfTargets = 3;
|
|
double actingDistance = 20;
|
|
double iValue = EMPTY_VALUE;
|
|
bool ignoreFirstTarget = true;
|
|
ENUM_X_DIRECTION targetsDir = Opposit(dir);
|
|
int count = ExtractByDirection(
|
|
targetZones,
|
|
structure.fvgs,
|
|
targetsDir //
|
|
);
|
|
bool has = IsValidSize(count);
|
|
if (has)
|
|
{
|
|
//
|
|
// Calculate Value ...
|
|
double points = GetPoints(zone.symbol);
|
|
double zoneRange = zone.upper - zone.lower;
|
|
iValue = IsXBullish(dir)
|
|
? (zone.upper + (zoneRange * defaultSignalR2R))
|
|
: (zone.lower + (zoneRange * defaultSignalR2R));
|
|
double defaultTarget = iValue;
|
|
|
|
//
|
|
// Looping Back ...
|
|
for (int i = 0; i < numberOfTargets; i++)
|
|
{
|
|
//
|
|
// Detect Lowest Above Zone ...
|
|
if (IsXBullish(dir))
|
|
{
|
|
//
|
|
idx = GetLowestAbove(iValue, targetZones);
|
|
has = IsValidIndex(idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
iValue = targetZones[idx].lower;
|
|
}
|
|
//
|
|
// Detect Highest below Zone ...
|
|
else if (IsXBearish(dir))
|
|
{
|
|
//
|
|
idx = GetHighestBelow(iValue, targetZones);
|
|
has = IsValidIndex(idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
iValue = targetZones[idx].upper;
|
|
}
|
|
|
|
//
|
|
// Validate Target Value ...
|
|
has = NotEmptyZero(iValue) &&
|
|
iValue != defaultTarget;
|
|
if (has)
|
|
{
|
|
//
|
|
// Init Target ...
|
|
target.Clean();
|
|
target.doRF = true;
|
|
target.target = iValue;
|
|
target.actingDistance = actingDistance;
|
|
has = target.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
// Add Target to Targets ...
|
|
AddRef(
|
|
target,
|
|
targets //
|
|
);
|
|
}
|
|
target.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Remove Nearest ...
|
|
has = ignoreFirstTarget &&
|
|
HasChild(targets);
|
|
if (has)
|
|
{
|
|
//
|
|
ArrayRemove(
|
|
targets,
|
|
0,
|
|
1 //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
target.Clean();
|
|
XClean(targetZones);
|
|
}
|
|
|
|
//
|
|
// TODO: Remove this ...
|
|
if (result)
|
|
{
|
|
//
|
|
CArrayObj *zoneObjs;
|
|
poiDrawer.DrawBoxes(
|
|
supports,
|
|
zoneObjs //
|
|
);
|
|
poiDrawer.DrawBoxes(
|
|
resistances,
|
|
zoneObjs //
|
|
);
|
|
poiDrawer.DrawBoxes(
|
|
structure.fvgs,
|
|
zoneObjs,
|
|
false //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
if (!result)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
XClean(targets);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Bar Has Signal Based on Strategy 1 ...
|
|
*
|
|
* @param bar: XOHCL, reference to Bar ...
|
|
* @param zone: XBoxZone, reference to holds affected zone ...
|
|
* @param targets: XTarget, reference to detected Signal's Targets collections ...
|
|
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
|
|
* @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
|
|
* @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Strategy2HasSignal(
|
|
XOHCL &bar,
|
|
XBoxZone &zone,
|
|
XTarget &targets[],
|
|
ENUM_X_DIRECTION &dir,
|
|
XFIMAConditions &conditions,
|
|
XFIMAMarketStructure &structure //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
zone.Clean();
|
|
XClean(targets);
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Validate ...
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Specified MA Cross ...
|
|
result = HasDirection(structure.maCrossDir);
|
|
|
|
//
|
|
// Prepare zone ...
|
|
if (result)
|
|
{
|
|
//
|
|
zone.to = bar.time;
|
|
zone.from = GetBarTime(
|
|
bar.symbol,
|
|
bar.period,
|
|
bar.Index() + 2 //
|
|
);
|
|
zone.symbol = bar.symbol;
|
|
zone.period = bar.period;
|
|
zone.dir = structure.maCrossDir;
|
|
zone.lower = bar.FindLowest(2, MODE_LOW);
|
|
zone.upper = bar.FindHighest(2, MODE_HIGH);
|
|
zone.type = name + "_" + ToXString(structure.maCrossDir);
|
|
|
|
//
|
|
result = zone.IsValid();
|
|
}
|
|
|
|
//
|
|
// Check Result ...
|
|
if (result)
|
|
{
|
|
//
|
|
dir = structure.maCrossDir;
|
|
|
|
//
|
|
// Handle Targets Detection ...
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
if (!result)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
XClean(targets);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
// |