last works on FIMA Back Tester ...

This commit is contained in:
2025-09-19 15:10:55 +03:30
parent 38d741da18
commit 5872d9f29b
4 changed files with 395 additions and 48 deletions
@@ -22,6 +22,8 @@
// //
// Imports ... // Imports ...
#include "../Classes/x-saherelm.base.class.mq5" #include "../Classes/x-saherelm.base.class.mq5"
#include "../Classes/x-saherelm.x-bar.analyser.class.mq5"
#include "../Libraries/x-saherelm.x-poi.lib.mq5"
// //
// Definitions ... // Definitions ...
@@ -40,12 +42,16 @@ class XCMarketPatternDetector : public XCBase
// Constructor ... // Constructor ...
XCMarketPatternDetector() XCMarketPatternDetector()
{ {
barAnalyser = new XCBarAnalyser();
} }
// //
// Deconstructor ... // Deconstructor ...
~XCMarketPatternDetector() ~XCMarketPatternDetector()
{ {
//
delete barAnalyser;
ZeroMemory(barAnalyser);
} }
// //
@@ -999,6 +1005,114 @@ class XCMarketPatternDetector : public XCBase
return result; return result;
} }
//
// FVG ...
/**
* Check For FVG Exists in Specified Loopback Period ...
*
* @param bar: XOHCL, Specified Bar ...
* @param dir: ENUM_X_DIRECTION a reference for Direction ...
* @param fvg: XBoxZone, reference for Holding FVG ...
* @param maxLoopback: int, Max Allowed Loopback to Lookup FVG ...
*
* @return ( bool )
*/
bool HasFVG(
XOHCL &bar,
ENUM_X_DIRECTION &dir,
XBoxZone &fvg,
int maxLoopback = 5 //
)
{
//
bool result = false;
//
// Prepare ...
CleanDirection(dir);
//
// Normalize ...
maxLoopback = NormalizeInt(maxLoopback, 3);
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
XOHCL iBar;
bool has = false;
int start = bar.Index();
int end = start + maxLoopback;
for (int i = start; i < end; i++)
{
//
// Initialize iBar ...
has = iBar.Init(
bar.symbol,
bar.period,
i //
);
if (!has)
{
continue;
}
//
// Check iBar is FVG or not ...
has = barAnalyser.IsFVG(
iBar,
fvg,
true // Force Bar Type ...
);
if (!has)
{
//
fvg.Clean();
iBar.Clean();
CleanDirection(dir);
//
continue;
}
//
iBar.Clean();
dir = fvg.dir;
//
break;
}
//
// Check FVG Exists ...
result = fvg.IsValid();
//
// Check Direction Exists ...
result =
result &&
HasDirection(dir);
//
// Cleanup Resources ...
if (!result)
{
//
fvg.Clean();
CleanDirection(dir);
}
iBar.Clean();
//
return result;
}
// //
// Trending ... // Trending ...
@@ -1465,6 +1579,8 @@ class XCMarketPatternDetector : public XCBase
// Private ... // Private ...
private: private:
// //
// Props ...
XCBarAnalyser *barAnalyser;
// //
// Helpers ... // Helpers ...
+68 -3
View File
@@ -11,6 +11,7 @@
// - [] ProcessTick: Processing All Ticks // - [] ProcessTick: Processing All Ticks
// - [] ProcessNewBar: Processing All New Bars // - [] ProcessNewBar: Processing All New Bars
// - [] CheckForGuard: Check For Guards // - [] CheckForGuard: Check For Guards
// - [] NormalizeSignal: Normalizing Prepared Signal ...
// - [] CheckAdditionslSignallerValidations: Additional Class Validations // - [] CheckAdditionslSignallerValidations: Additional Class Validations
// //
// - Dont Forget to Call OnSignal Event in Process Methods when // - Dont Forget to Call OnSignal Event in Process Methods when
@@ -37,6 +38,7 @@
// Imports ... // Imports ...
#include "../Classes/x-saherelm.base.class.mq5" #include "../Classes/x-saherelm.base.class.mq5"
#include "../Libraries/x-saherelm.x-trade.lib.mq5" #include "../Libraries/x-saherelm.x-trade.lib.mq5"
#include "../Classes/x-saherelm.x-market.pattern.class.mq5"
// //
// Definitions ... // Definitions ...
@@ -57,6 +59,9 @@ class XCBaseSignaller : public XCBase
// //
TCanAnalyse canAnalyseEventListener; TCanAnalyse canAnalyseEventListener;
//
XCMarketPatternDetector *patternDetector;
// //
// Constructor ... // Constructor ...
XCBaseSignaller( XCBaseSignaller(
@@ -92,6 +97,9 @@ class XCBaseSignaller : public XCBase
// Set Dfault Values ... // Set Dfault Values ...
mProcessedTicksCount = 0; mProcessedTicksCount = 0;
mLastCheckedBarTime = NULL; mLastCheckedBarTime = NULL;
//
patternDetector = new XCMarketPatternDetector();
} }
// //
@@ -101,6 +109,10 @@ class XCBaseSignaller : public XCBase
// //
// Cleanup Event Listeners ... // Cleanup Event Listeners ...
SpecifiedClean(onSignalEventListeners); SpecifiedClean(onSignalEventListeners);
//
delete patternDetector;
ZeroMemory(patternDetector);
} }
// //
@@ -286,6 +298,15 @@ class XCBaseSignaller : public XCBase
return true; return true;
} }
/**
* Normalizing Signal by Signaller Custom Props ...
*
* @param signal: XSignal ...
*/
void virtual NormalizeSignal(XSignal &signal)
{
}
// //
// Protected ... // Protected ...
protected: protected:
@@ -381,11 +402,20 @@ class XCBaseSignaller : public XCBase
* *
* @param signal: XSignal, holding result Signal ... * @param signal: XSignal, holding result Signal ...
* @param forDir: ENUM_X_DIRECTION * @param forDir: ENUM_X_DIRECTION
* @param targets: XTarget Array, Provides Signal Targets (Price) ...
* @param r2r: double, Provides Signal (r2r), if not Provided uses Default R2R ...
* @param slPrice: double, Provides Signal SL Price, if not Provided uses riskInPoint ...
* @param riskInPoint: double, Provides Signal Risk Amount which Multiplied to Points, if not Provided uses DefaultRiskInPoint ...
*
* @return ( bool ) * @return ( bool )
*/ */
bool PrepareSignal( bool PrepareSignal(
XSignal &signal, XSignal &signal,
ENUM_X_DIRECTION forDir // ENUM_X_DIRECTION forDir,
XTarget &targets[], //
double r2r = 0,
double slPrice = 0,
double riskInPoint = 0 //
) )
{ {
// //
@@ -417,8 +447,19 @@ class XCBaseSignaller : public XCBase
double entry = GetEntry(symbol, forDir); double entry = GetEntry(symbol, forDir);
// //
double risk = (defaultSignalRiskInPoint * point); riskInPoint = riskInPoint > 0 && slPrice <= 0
double reward = (risk * defaultSignalR2R) + spread; ? riskInPoint
: defaultSignalRiskInPoint;
double risk = (riskInPoint * point);
risk = slPrice > 0
? MathAbs(entry - slPrice)
: risk;
//
r2r = r2r > 0
? r2r
: defaultSignalR2R;
double reward = (risk * r2r) + spread;
// //
double tp = double tp =
@@ -448,9 +489,33 @@ class XCBaseSignaller : public XCBase
: POSITION_TYPE_SELL; : POSITION_TYPE_SELL;
signal.mode = X_ORDER_MODE_MARKET; signal.mode = X_ORDER_MODE_MARKET;
//
// Apply Targets ...
if (HasChild(targets))
{
//
ApplyTargetsOnSignal(
forDir,
targets,
signal //
);
}
// //
// Validate Signal ... // Validate Signal ...
result = signal.IsValid(); result = signal.IsValid();
if (result)
{
//
NormalizeSignal(signal);
result = signal.IsValid();
}
//
if (!result)
{
signal.Clean();
}
// //
return result; return result;
+100 -44
View File
@@ -27,7 +27,7 @@
#include "../Classes/x-saherelm.x-backtester.expert.class.mq5" #include "../Classes/x-saherelm.x-backtester.expert.class.mq5"
#include "../Classes/x-saherelm.x-market.pattern.class.mq5" #include "../Classes/x-saherelm.x-market.pattern.class.mq5"
#include "../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../Classes/x-saherelm.x-poi.drawer.class.mq5"
#include "../Helpers/x-saherelm.xom1.helper.mq5" #include "../XFIMA/Classes/x-saherelm.xfima.signaller.class.mq5"
// //
// Definitions ... // Definitions ...
@@ -132,6 +132,7 @@ input int valeArrowCode = 159; // Vales Arrow Code
// //
string eaLogTag; // EA Log Prefix ... string eaLogTag; // EA Log Prefix ...
XCBackTesterEA *eaExpert; // EA Expert ... XCBackTesterEA *eaExpert; // EA Expert ...
XCXFIMAStrategy1Signaller *fima1Signaller; // XFIMA1 Signaller ...
XCMarketPatternDetector *eaPatternDetector; // EA Pattern Detector ... XCMarketPatternDetector *eaPatternDetector; // EA Pattern Detector ...
// //
@@ -235,50 +236,70 @@ int OnInit()
} }
// //
// Initial Indicator Handler ... // Here Instantiate Signaller Class ...
eaHandler = iCustom(
//
// Preparing Indicator Inputs ...
XFIMAInputs fimaInputs;
//
// This is Default Configuration ...
fimaInputs.Default();
fimaInputs.Hide();
fimaInputs.showZigZag = true;
//
// Here we Attach Inputs to Indicator ...
fimaInputs.scMethod = scMethod;
fimaInputs.scPeriod = scPeriod;
fimaInputs.mcMethod = mcMethod;
fimaInputs.mcPeriod = mcPeriod;
fimaInputs.lcMethod = lcMethod;
fimaInputs.lcPeriod = lcPeriod;
fimaInputs.hcMethod = hcMethod;
fimaInputs.hcPeriod = hcPeriod;
fimaInputs.upperMode = upperMode;
fimaInputs.lowerMode = lowerMode;
fimaInputs.fiboUpperZoneLevel = fiboUpperZoneLevel;
fimaInputs.fiboMiddleZoneLevel = fiboMiddleZoneLevel;
fimaInputs.fiboLowerZoneLevel = fiboLowerZoneLevel;
fimaInputs.sarStep = sarStep;
fimaInputs.sarMax = sarMax;
fimaInputs.maMethod = maMethod;
fimaInputs.maAppliedTo = maAppliedTo;
fimaInputs.maFastLength = maFastLength;
fimaInputs.maSlowLength = maSlowLength;
fimaInputs.zigzagDepth = zigzagDepth;
fimaInputs.zigzagDeviation = zigzagDeviation;
fimaInputs.zigzagBackStep = zigzagBackStep;
fimaInputs.zigzagUppersMode = zigzagUppersMode;
fimaInputs.zigzagLowersMode = zigzagLowersMode;
fimaInputs.showPV = showPV;
fimaInputs.showSAR = showSAR;
fimaInputs.showMAFast = showMAFast;
fimaInputs.showMASlow = showMASlow;
fimaInputs.showZigZag = showZigZag;
fimaInputs.showFiboZone = showFiboZone;
fimaInputs.startCalculationForLastBars = startCalculationForLastBars;
fimaInputs.sarArrowCode = sarArrowCode;
fimaInputs.peakArrowCode = peakArrowCode;
fimaInputs.valeArrowCode = valeArrowCode;
//
// Instantiate Signaller ...
fima1Signaller = new XCXFIMAStrategy1Signaller(
_Symbol, _Symbol,
_Period, _Period,
"x-saherelm.xfima", fimaInputs,
"", // Calculation ... true, // Process All Ticks ...
scMethod, 2.0, // Signaller Risk to Reward Ratio ...
scPeriod, 50, // Default Risk In Points ...
mcMethod, 0.01 // Defaul Volume ...
mcPeriod,
lcMethod,
lcPeriod,
hcMethod,
hcPeriod,
upperMode,
lowerMode,
fiboUpperZoneLevel,
fiboMiddleZoneLevel,
fiboLowerZoneLevel,
sarStep,
sarMax,
maMethod,
maAppliedTo,
maFastLength,
maSlowLength,
zigzagDepth,
zigzagDeviation,
zigzagBackStep,
zigzagUppersMode,
zigzagLowersMode,
"", // Presentation ...
showPV,
showSAR,
showMAFast,
showMASlow,
showZigZag,
showFiboZone,
startCalculationForLastBars,
sarArrowCode,
peakArrowCode,
valeArrowCode
//
); );
isInited = eaHandler != INVALID_HANDLE; fima1Signaller.AddOnSignalEventHandler(OnSignalTriggered);
//
isInited = fima1Signaller.IsValid();
if (!isInited) if (!isInited)
{ {
// //
@@ -387,6 +408,9 @@ void OnTick()
// //
DetectPatterns(); DetectPatterns();
//
fima1Signaller.OnTick();
} }
// //
@@ -526,6 +550,38 @@ void DestroyTimer()
// EventKillTimer(); // EventKillTimer();
} }
/**
* Trigger OnSignal Event ...
*
* @param signal: XSignal
*/
void OnSignalTriggered(XSignal &signal)
{
//
CChartObjectVLine *iObj = new CChartObjectVLine();
//
string iName = signal.GetTag();
color iColor = IsLong(signal.type) ? clrLime : clrRed;
//
bool has = iObj.Create(
eaDrawer.ChartIdentification(),
iName,
eaDrawer.SubWindowIdentification(),
signal.time //
);
if (has)
{
//
iObj.Width(2);
iObj.Color(iColor);
//
draws.Add(iObj);
}
}
// //
// Trade Event Handlers ... // Trade Event Handlers ...
@@ -704,8 +760,8 @@ void DetectPatterns()
bool detectSwingTrendBreakes = false; bool detectSwingTrendBreakes = false;
// //
bool detectSupports = false; bool detectSupports = true;
bool detectResistance = false; bool detectResistance = true;
// //
// Checking Momentum Bar ... // Checking Momentum Bar ...
@@ -188,6 +188,15 @@ class XCXFIMABaseSignaller : public XCBaseSignaller
return result; return result;
} }
/**
* Normalizing Signal by Signaller Custom Props ...
*
* @param signal: XSignal ...
*/
void virtual NormalizeSignal(XSignal &signal)
{
}
// //
// Protected ... // Protected ...
protected: protected:
@@ -208,6 +217,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
public: public:
// //
// Props ... // Props ...
int fvgLookupLenght; // Maximum Lenght for Looking up FVG before Crosses
// //
// Constructor ... // Constructor ...
@@ -229,6 +239,8 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
_defaultSignalVolume // _defaultSignalVolume //
) )
{ {
//
fvgLookupLenght = 5;
} }
// //
@@ -323,20 +335,95 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
// //
// Do Conditions Validating ... // Do Conditions Validating ...
//
// 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 ... // Bullish Validation ...
bool isBullish = bool isBullish =
// //
// Has Cross ...
isFastCrossedOverSlow isFastCrossedOverSlow
// //
&&
//
// Cross Places Based on Fibo ...
MathMax(iFastMa, iSlowMa) < iFiboLower
//
&&
//
(
//
// Checking FVG ...
(hasFVG &&
fvg.IsBullish())
//
||
//
// Checking Crossed Place ...
isCrossedOverHappensOnShadow
//
)
//
; ;
// //
// Bearish Validation ... // Bearish Validation ...
bool isBearish = bool isBearish =
// //
// Has Cross ...
isFastCrossedUnderSlow isFastCrossedUnderSlow
// //
&&
//
// Cross Places Based on Fibo ...
MathMin(iFastMa, iSlowMa) > iFiboUpper
//
&&
//
(
//
// Checking FVG ...
(hasFVG &&
fvg.IsBearish())
//
||
//
// Checking Crossed Place ...
isCrossedUnderHappensOnShadow
//
)
//
; ;
// //
@@ -360,9 +447,11 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
{ {
// //
// Prepare Founded Signal ... // Prepare Founded Signal ...
XTarget targets[];
has = PrepareSignal( has = PrepareSignal(
signal, signal,
signalDir // signalDir,
targets //
); );
if (has) if (has)
{ {
@@ -405,6 +494,27 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
return result; return result;
} }
//
// Private ...
private:
//
// Props ...
//
// Lookup FVG ...
bool LookupFVG(
XOHCL &bar,
ENUM_X_DIRECTION &dir,
XBoxZone &fvgBox //
)
{
//
bool result = false;
//
return result;
}
// //
}; };