Files
MQL5Data/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5
T

1834 lines
46 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.parser.class.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 ...
//
CArrayObj drawnObjects; // Drawing Objects Holder ...
XFIMAInputs fimaInputs; // XFIMA Inputs ...
XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ...
XCXFIMAPOIDrawer *poiDrawer; // XFIMA POI Drawer ...
XCXFIMAHelperParser *fimaParser; // XFIMA Helper Parser ...
XCXFIMAPOIDetector *poiDetector; // XFIMA POI Detector ...
XFIMAMarketStructureConfig structureConfig; // XFIMA Market Structure Detector Config ...
XFIMAMarketStructureDrawerConfig structureDrawConfig; // XFIMA Market Structure Draw Config ...
//
// 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);
}
}
//
// Instantiate XFIMA Helper Parser ...
fimaParser = new XCXFIMAHelperParser(fimaHelper);
//
poiDrawer = new XCXFIMAPOIDrawer();
poiDetector = new XCXFIMAPOIDetector(fimaHelper, fimaParser);
//
// Configure ...
structureConfig.Default();
structureDrawConfig.Default();
}
//
// Deconstructor ...
~XCXFIMABaseSignaller()
{
Destroy();
}
//
// Overrides ...
//
// Actions ...
/**
* Destroy ...
*/
void Destroy()
{
//
BeforeDestroy();
//
fimaInputs.Clean();
//
delete fimaHelper;
ZeroMemory(fimaHelper);
//
delete poiDrawer;
ZeroMemory(poiDrawer);
//
delete poiDetector;
ZeroMemory(poiDetector);
//
structureConfig.Clean();
structureDrawConfig.Clean();
}
//
// 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, reference collection to holds result ...
* @param positions: XPosition, reference collection to provides positions ...
* @param barIndex: int
*
* @return ( int )
*/
int virtual CheckForGuard(
XGuard &guards[],
XPosition &positions[],
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;
if (!result)
{
return result;
}
//
return result;
}
/**
* Normalizing Signal by Signaller Custom Props ...
*
* @param signal: XSignal ...
*/
void virtual NormalizeSignal(XSignal &signal)
{
}
//
// Protected ...
protected:
//
//
// Protected Actions ...
//
// Private ...
private:
//
};
//
// XFIMA Strategy 2 Signaller Class ...
class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
{
//
// Public ...
public:
//
// Props ...
//
// 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 ...
structureConfig.Default();
structureDrawConfig.Default();
}
//
// Deconstructor ...
~XCXFIMAStrategy1Signaller()
{
//
Destroy();
}
//
// 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;
XBoxZone iZone;
XSignal iSignal;
bool has = false;
XTarget iTargets[];
bool isBullish = false;
bool isBearish = false;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
// Initialize Bar as CBar ...
has = iBar.Init(
symbol,
period,
barIndex //
);
if (!has)
{
//
iBar.Clean();
return;
}
//
// Strategy X ...
has = HasSignal(
iBar,
iZone,
iTargets,
iDir //
);
//
// Handle Resting Signals ...
has = HasDirection(iDir) &&
iZone.IsValid();
//
// Prepare Signal ...
if (has)
{
//
isBullish = IsXBullish(iDir);
isBearish = IsXBearish(iDir);
//
// Provided SL ...
double points = GetPoints(symbol);
double spread = GetSpread(symbol);
double entry = GetEntry(symbol, iDir);
//
// Calculate SL Addition ...
double slAddition =
slAdditionDistance <= 0
? 0
: slAdditionDistance * points;
//
// Calculate SL Price ...
double sl =
isBullish
? iZone.lower - slAddition
: iZone.upper + slAddition;
//
// Prepare Signal ...
has = PrepareSignal(
iSignal,
iDir,
iTargets,
0, // Use Default R2R ...
sl, // Provided Price for SL ...
0 // Specified Risk in Point ....
);
}
//
// Notify On Signal Event ...
if (has)
{
NotifySignalEventListeners(iSignal);
}
//
// Cleanup ...
iBar.Clean();
iZone.Clean();
iSignal.Clean();
XClean(iTargets);
}
/**
* Check Guards Based on MarketConditions ...
*
* @param guards: XGuard, reference collection to holds result ...
* @param positions: XPosition, reference collection to provides positions ...
* @param barIndex: int
*
* @return ( int )
*/
int virtual CheckForGuard(
XGuard &guards[],
XPosition &positions[],
int barIndex = 0 //
)
{
//
int result = 0;
//
XClean(guards);
//
int positionsCount = ArraySize(positions);
if (!IsValidSize(positionsCount))
{
return result;
}
//
// Requirements ...
XGuard iGuard;
bool has = false;
//
// Force Hedging ...
// bool forceHedging = (positionsCount >= 2);
// if (forceHedging)
// {
// //
// // Minimum Required Reward ...
// double minRequiredReward = 1.5;
// //
// // Summarizing Risk and Reward of Collections ...
// // double risk = 0;
// // double volume = 0;
// // double reward = 0;
// // for (int i = 0; i < positionsCount; i++)
// // {
// // //
// // risk += positions[i].GetRisk() + positions[i].commission + (-1 * positions[i].swap);
// // reward += positions[i].profit;
// // volume += positions[i].volume;
// // }
// // //
// // risk *= volume;
// // reward *= volume;
// // //
// // // Calculating Can Hedge rops ...
// // has = reward >= (risk * minRequiredReward);
// // if (has)
// // {
// // //
// // iGuard.Clean();
// // iGuard.force = true;
// // iGuard.symbol = symbol;
// // iGuard.period = period;
// // iGuard.provider = name;
// // iGuard.time = TimeCurrent();
// // iGuard.action = X_GUARD_ACTION_HEDGE;
// // //
// // // Validate Guard ...
// // has = iGuard.IsValid();
// // if (has)
// // {
// // //
// // AddRef(
// // iGuard,
// // guards //
// // );
// // }
// // }
// }
//
result = ArraySize(guards);
//
// Cleanup ...
iGuard.Clean();
//
return result;
}
//
// Private ...
private:
//
// Props ...
//
// Implementing Strategies ...
/**
* Check Bar Has Signal Based on Strategy X ...
*
* @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 ...
*
* @return ( bool )
*/
bool HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Configuration Flags ...
//
// Signaller Flags ...
bool useSignaller1 = false;
bool useSignaller2 = false;
bool useSignaller3 = false;
bool useSignaller4 = true;
//
// Validator Flags ...
string provider = NULL;
bool validateByOrderFlow = false;
//
// Target Flags ...
bool hasPartialCloseOnTp1 = true;
//
// Draw Flags ...
bool draw = true;
bool drawZone = true;
bool drawMarketStructurePivots = true;
bool drawMarketStructureAnalysis = true;
bool drawMarketStructureOrderFlow = true;
XPOIDrawConfig iDrawConfig;
//
// Signal Checking ...
//
// Analyse Market Strucutre ...
XFIMAMarketStructure marketStructure;
//
// Signaller 1 ...
if (!result && useSignaller1)
{
//
result = Strategy1HasSignal(
bar,
zone,
targets,
dir //
);
//
if (result)
{
provider = "1";
}
}
//
// Signaller 2 ...
if (!result && useSignaller2)
{
//
result = Strategy2HasSignal(
bar,
zone,
targets,
dir //
);
//
if (result)
{
provider = "2";
}
}
//
// Signaller 3 ...
if (!result && useSignaller3)
{
//
result = Strategy3HasSignal(
bar,
zone,
targets,
dir //
);
//
if (result)
{
provider = "3";
}
}
//
// Signaller 4 ...
if (!result && useSignaller4)
{
//
result = Strategy4HasSignal(
bar,
zone,
targets,
dir //
);
//
if (result)
{
provider = "4";
}
}
//
// Signal Validating ...
//
// Validate Signals by Order Flow ...
if (result && validateByOrderFlow)
{
//
// Analyse Market Structure if Required ...
if (!marketStructure.IsValid())
{
//
poiDetector.AnalyseMarket(
marketStructure,
structureConfig,
bar.Index() //
);
}
//
bool isBullish = IsXBullish(dir) &&
marketStructure.HasBullishOrderFlow();
//
bool isBearish = IsXBearish(dir) &&
marketStructure.HasBearishOrderFlow();
//
// Summarizing result ...
result = isBullish ||
isBearish;
}
//
// Targets, Restrictions and Risk Management ...
if (result)
{
//
// Requirements ...
XTarget iTarget;
//
// Checking Direction of Signal ...
bool isBullish = IsXBullish(dir);
bool isBearish = IsXBearish(dir);
//
// Provided SL ...
double points = GetPoints(symbol);
double spread = GetSpread(symbol);
double entry = GetEntry(symbol, dir);
//
// Calculate SL Addition ...
double slAddition =
slAdditionDistance <= 0
? 0
: slAdditionDistance * points;
//
// Calculate SL Price ...
double sl =
isBullish
? zone.lower - slAddition
: zone.upper + slAddition;
//
// Calculate Risk ...
double risk = MathAbs(entry - sl);
//
// Calculate Reward ...
double reward = defaultSignalR2R * risk;
//
// Calculate TP1 ...
double tp1 = isBullish
? entry + risk
: entry - risk;
double tp2 = isBullish
? entry + (2 * risk)
: entry - (2 * risk);
//
// Calculate TP ...
double tp = isBullish
? entry + reward
: entry - reward;
//
// Check Max Allowed Risk ...
bool hasTooMuchRisk = maxAllowedRiskDistance <= 0
? false
: risk >= (maxAllowedRiskDistance * points);
if (hasTooMuchRisk)
{
//
// Clean Signal if Too much Risk ...
zone.Clean();
dir = X_DIRECTION_NONE;
}
//
// Common Targets ...
//
// Partial Close on TP 1 ...
if (hasPartialCloseOnTp1)
{
//
iTarget.Clean();
iTarget.target = tp1;
iTarget.doRFOnEntry = true;
iTarget.actingDistance = 5;
iTarget.volumeMultiplier = 0.8;
//
AddRef(iTarget, targets);
}
//
// Custom Signaller Targets ...
//
// Restrictions Handling ...
if (risk > 0 && HasRestrictions())
{
//
// Reset Restricitons if necessary ...
ResetRestrictions();
//
// Handle Custom Restrictions Senario ...
}
//
// Ignore Targets ...
if (ignoreTargets)
{
XClean(targets);
}
//
// Summarize Result ...
result = zone.IsValid() &&
HasDirection(dir);
//
// Cleanup ...
iTarget.Clean();
}
//
// Draws ...
if (result && draw)
{
//
// Prepare Draw Config ...
iDrawConfig = structureDrawConfig.drawConfig;
iDrawConfig.zonesWidth = 3;
iDrawConfig.zonesStyle = STYLE_DASH;
iDrawConfig.bullishColor = clrYellow;
iDrawConfig.bearishColor = clrDarkOrange;
//
// Draw Zone ...
if (drawZone)
{
poiDrawer.DrawZone(zone, iDrawConfig);
}
//
// Draw Market Structure ...
//
// Analyse Market Structure if Required ...
if (!marketStructure.IsValid())
{
//
poiDetector.AnalyseMarket(
marketStructure,
structureConfig,
bar.Index() //
);
}
if (marketStructure.IsValid())
{
//
// Order Flow ...
if (drawMarketStructureOrderFlow && marketStructure.HasOrderFlow())
{
poiDrawer.DrawZones(marketStructure.orderFlow, iDrawConfig);
}
//
// Pivots ...
if (drawMarketStructurePivots)
{
//
XPivot pivots[];
int pivotsCount = marketStructure.CollectPivots(
pivots,
true // Contains Patterns ...
);
if (IsValidSize(pivotsCount))
{
poiDrawer.DrawPivots(pivots, iDrawConfig);
}
//
XClean(pivots);
}
//
// Analysis ...
if (drawMarketStructureAnalysis)
{
//
}
}
//
// Other Drawing Materials ...
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
//
// Debug Breake ...
if (result)
{
DebugBreak();
}
//
// Cleanup ...
iDrawConfig.Clean();
marketStructure.Clean();
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 3 ...
*
* @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 ...
*
* @return ( bool )
*/
bool Strategy1HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Define Requirements ...
//
XOHCL pBar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
if (!result)
{
//
pBar.Clean();
return result;
}
//
// Reading Conditions ...
int pullBackStartBar = -1;
bool isPullBack = result &&
poiDetector.IsPullbackPattern(
pBar,
zone,
dir,
2,
false // Force Break ...
);
bool isPullbackBullish = isPullBack &&
IsXBullish(dir);
bool isPullbackBearish = isPullBack &&
IsXBearish(dir);
if (isPullBack)
{
pullBackStartBar = zone.FromIndex();
}
//
// Reading HK Band ...
//
double pHKBandUpper = fimaHelper.GetHKBandUpper(pBar.Index());
double pHKBandLower = fimaHelper.GetHKBandLower(pBar.Index());
int overHKBandUpperCount = fimaParser.CountOverHKBandUpper(pullBackStartBar, X_PRICE_LOW);
int underHKBandLowerCount = fimaParser.CountUnderHKBandLower(pullBackStartBar, X_PRICE_HIGH);
//
// Reading PV Requirements ...
//
int lastPeakOverLastIDX = -1;
int lastValeUnderLastIDX = -1;
double pPeak = fimaHelper.GetPeak(pBar.Index());
double pVale = fimaHelper.GetVale(pBar.Index());
int samePeaks = fimaParser.CountSamePeaks(pBar.Index());
int sameVales = fimaParser.CountSameVales(pBar.Index());
fimaParser.FindLastPeakOverLast(lastPeakOverLastIDX, pBar.Index());
fimaParser.FindLastValeUnderLast(lastValeUnderLastIDX, pBar.Index());
//
// Reading pBar Patterns ...
XPatternAnalysis pBarAnalysis;
poiDetector.AnalyseBarPatterns(
pBar,
pBarAnalysis,
structureConfig.barsAnalysisConfig //
);
//
// Check Bar Patterns ...
bool isPBarHasBullishPatterns =
(bar.close > pBar.low ||
bar.open > pBar.low) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
//
);
bool isPBarHasBearishPatterns =
(bar.close < pBar.high ||
bar.open < pBar.high) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
// Check PBar Close Over Under Fast Ma ...
bool isPBarCloseOverFast = pBar.close > fimaHelper.GetMAFast(pBar.Index());
bool isPBarCloseUnderFast = pBar.close < fimaHelper.GetMAFast(pBar.Index());
//
// Try To Find Affected Zone ...
//
// Collecting Zones ...
XBoxZone zones[];
XBoxZone affectedZones[];
XBoxZone affectedZonesBullish[];
XBoxZone affectedZonesBearish[];
int zonesCount = poiDetector.CollectZones(
pBar,
zones, //
5, // Zones Loopback ...
3 // Zones Validation Length ...
// Required Zones ...
// Loopback ...
);
int affectedZonesCount = ExtractAffectedZones(
pBar,
zones,
affectedZones //
);
int affectedZonesBullishCount = ExtractByDirection(
affectedZonesBullish,
affectedZones,
X_DIRECTION_BULLISH //
);
int affectedZonesBearishCount = ExtractByDirection(
affectedZonesBearish,
affectedZones,
X_DIRECTION_BEARISH //
);
//
int insideBullishIDX = -1;
int insideBearishIDX = -1;
bool hasBullishInside =
pBar.IsBullish() &&
HasInside(
insideBullishIDX,
pBar,
affectedZonesBullish //
);
bool hasBearishInside =
pBar.IsBearish() &&
HasInside(
insideBearishIDX,
pBar,
affectedZonesBearish //
);
//
// Do ...
//
isBullish =
//
hasBullishInside &&
isPullbackBullish &&
isPBarHasBullishPatterns &&
fimaParser.IsSARBullish(pBar.Index()) &&
(pVale >= affectedZonesBullish[insideBullishIDX].lower &&
pVale <= affectedZonesBullish[insideBullishIDX].upper)
//
;
//
isBearish =
//
hasBearishInside &&
isPullbackBearish &&
isPBarHasBearishPatterns &&
fimaParser.IsSARBearish(pBar.Index()) &&
(pPeak >= affectedZonesBearish[insideBearishIDX].lower &&
pPeak <= affectedZonesBearish[insideBearishIDX].upper)
//
;
//
// Validate ...
result = isBullish ||
isBearish;
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
zone.Clean();
if (isBullish)
{
zone = affectedZonesBullish[insideBullishIDX];
}
else
{
zone = affectedZonesBearish[insideBearishIDX];
}
//
result = zone.IsValid();
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
XClean(zones);
pBarAnalysis.Clean();
XClean(affectedZones);
XClean(affectedZonesBullish);
XClean(affectedZonesBearish);
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 3 ...
*
* @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 ...
*
* @return ( bool )
*/
bool Strategy2HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
//
return result;
}
//
// Reading pBar Patterns ...
XPatternAnalysis pBarAnalysis;
poiDetector.AnalyseBarPatterns(
pBar,
pBarAnalysis,
structureConfig.barsAnalysisConfig //
);
//
// Check Bar Patterns ...
bool isPBarHasBullishPatterns =
(bar.close > pBar.low ||
bar.open > pBar.low) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
//
);
bool isPBarHasBearishPatterns =
(bar.close < pBar.high ||
bar.open < pBar.high) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
double peak = fimaHelper.GetPeak(bar.Index());
double vale = fimaHelper.GetVale(bar.Index());
double pPeak = fimaHelper.GetPeak(pBar.Index());
double pVale = fimaHelper.GetVale(pBar.Index());
double p2Peak = fimaHelper.GetPeak(p2Bar.Index());
double p2Vale = fimaHelper.GetVale(p2Bar.Index());
bool isPPeakOverLast = fimaParser.IsPeakOverLast(pBar.Index());
bool isPValeUnderLast = fimaParser.IsValeUnderLast(pBar.Index());
bool isP2PeakOverLast = fimaParser.IsPeakOverLast(p2Bar.Index());
bool isP2ValeUnderLast = fimaParser.IsValeUnderLast(p2Bar.Index());
bool isPeakOverLast = isPPeakOverLast ||
isP2PeakOverLast;
bool isValeUnderLast = isPValeUnderLast ||
isP2ValeUnderLast;
bool isP2ValeOverLast = pVale > p2Vale;
bool isP2PeakUnderLast = pPeak < p2Peak;
//
// Check PBar Close Over Under Fast Ma ...
bool isPBarCloseOverFast = pBar.close > fimaHelper.GetMAFast(pBar.Index());
bool isPBarCloseUnderFast = pBar.close < fimaHelper.GetMAFast(pBar.Index());
bool isFastOverLast = fimaHelper.GetMAFast(pBar.Index()) > fimaHelper.GetMAFast(p2Bar.Index());
bool isFastUnderLast = fimaHelper.GetMAFast(pBar.Index()) < fimaHelper.GetMAFast(p2Bar.Index());
//
// Force P2Bar is Pin Bar ...
ENUM_X_DIRECTION p2Dir;
bool isP2BarPinned = poiDetector.IsPinnedBar(
p2Bar,
p2Dir //
);
bool isP2BarBullishPinned =
isP2BarPinned &&
IsXBullish(p2Dir);
bool isP2BarBearishPinned =
isP2BarPinned &&
IsXBearish(p2Dir);
//
// Do ...
//
isBullish =
//
isFastOverLast &&
isValeUnderLast &&
!isP2PeakUnderLast &&
isPBarCloseOverFast &&
isP2BarBullishPinned &&
isPBarHasBullishPatterns
//
;
//
isBearish =
//
isPeakOverLast &&
isFastUnderLast &&
!isP2ValeOverLast &&
isPBarCloseUnderFast &&
isP2BarBearishPinned &&
isPBarHasBearishPatterns
//
;
//
// Validate ...
result = isBullish ||
isBearish;
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
zone.Clean();
result = ToBox(
p2Bar,
zone,
dir,
X_BAR_PATTERN_PINNED //
);
//
// Manage Stops ...
if (result)
{
//
double entry = GetEntry(zone.symbol, zone.dir);
double riskSide = zone.IsBullish() ? zone.lower : zone.upper;
double risk = MathAbs(entry - riskSide);
//
// Collecting Affected Zones ...
XBoxZone tmps[];
XBoxZone zones[];
XBoxZone actedZones[];
XBoxZone insideZones[];
XBoxZone breakedZones[];
XBoxZone affectedZones[];
//
// Support and Resistances ...
poiDetector.CollectZones(bar, tmps);
Copy(tmps, zones, false);
//
// OBS ...
poiDetector.CollectOBs(bar, tmps);
Copy(tmps, zones, false);
//
// FVGs ...
poiDetector.CollectFVGs(bar, tmps);
Copy(tmps, zones, false);
//
ExtractAffectedZones(bar, zones, affectedZones);
//
// Acteds Zones ...
ExtractActeds(bar, actedZones, affectedZones);
//
// Inside Zones ...
ExtractInsides(bar, insideZones, affectedZones);
//
// Breaked Zones ...
ExtractBreakeds(bar, breakedZones, affectedZones);
//
// Cleanup ...
XClean(tmps);
XClean(zones);
XClean(actedZones);
XClean(insideZones);
XClean(breakedZones);
XClean(affectedZones);
}
//
result = zone.IsValid();
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 4 ...
*
* @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 ...
*
* @return ( bool )
*/
bool Strategy3HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
//
return result;
}
//
// Do ...
// XFIMA Consolidation ...
//
bool isConsolidation = poiDetector.DetectPVConsolidationZone(
zone,
pBar.Index(),
true, // Force PV Break ...
true // Force Has Sar Switch ...
);
//
isBullish =
isConsolidation &&
zone.IsBullish();
//
isBearish =
isConsolidation &&
zone.IsBearish();
//
// Validate based on Bars Patterns ...
bool validateByBarPatterns = true;
if (validateByBarPatterns)
{
//
// Reading pBar Patterns ...
XPatternAnalysis pBarAnalysis;
poiDetector.AnalyseBarPatterns(
pBar,
pBarAnalysis,
structureConfig.barsAnalysisConfig //
);
//
// Bullish ...
bool isPBarHasBullishPatterns =
(bar.close > pBar.low ||
bar.open > pBar.low) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
//
);
//
// Bearish ...
bool isPBarHasBearishPatterns =
(bar.close < pBar.high ||
bar.open < pBar.high) &&
(
//
pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
isBullish =
isBullish &&
isPBarHasBullishPatterns &&
!isPBarHasBearishPatterns;
//
isBearish =
isBearish &&
isPBarHasBearishPatterns &&
!isPBarHasBullishPatterns;
//
// Summarize Result ...
result = isBullish ||
isBearish;
}
//
// Checking PullBack ...
bool validateByPullback = false;
if (validateByPullback)
{
//
XBoxZone pullback;
ENUM_X_DIRECTION pullbackDir;
bool isPullBack = result &&
poiDetector.IsPullbackPattern(
pBar,
pullback,
pullbackDir,
2,
false // Force Break ...
);
bool isPullbackBullish = isPullBack &&
IsXBullish(pullbackDir);
bool isPullbackBearish = isPullBack &&
IsXBearish(pullbackDir);
//
isBullish =
isBullish &&
isPullbackBullish;
//
isBearish =
isBearish &&
isPullbackBearish;
//
// Summarize Result ...
result = isBullish ||
isBearish;
}
//
// Validate ...
result = isBullish ||
isBearish;
//
// Prepare Zone ...
if (result)
{
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 4 ...
*
* @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 ...
*
* @return ( bool )
*/
bool Strategy4HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
//
return result;
}
//
// Do ...
//
// Detecting OrderFlow ...
XBoxZone orderFlow[];
bool hasOrderFlow = poiDetector.HasOrderFlow(
pBar,
dir,
orderFlow,
structureConfig.orderFlowValidation,
structureConfig.orderFlowUseOB,
structureConfig.orderFlowUseFVG,
structureConfig.orderFlowUseSupportAndResistance,
structureConfig.barsAnalysisConfig.supportAndResistanceLoopbackLength,
structureConfig.barsAnalysisConfig.supportAndResistanceValidationLength,
structureConfig.loopback //
);
//
isBullish = hasOrderFlow &&
IsXBullish(dir);
//
isBearish = hasOrderFlow &&
IsXBearish(dir);
//
result = isBullish ||
isBearish;
if (result) {
//
poiDrawer.DrawZones(orderFlow, structureDrawConfig.drawConfig);
Print("OrderFlow ...");
}
//
isBullish =
//
false
//
;
//
isBearish =
//
false
//
;
//
// Validate ...
result = isBullish ||
isBearish;
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
zone.Clean();
result = ToBox(
p2Bar,
zone,
dir,
X_BAR_PATTERN_PINNED //
);
//
// Manage Stops ...
if (result)
{
}
//
result = zone.IsValid();
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
//
return result;
}
//
};
//