last works ...

This commit is contained in:
2025-10-09 12:34:26 +03:30
parent fc318b5c19
commit e97b44b938
7 changed files with 642 additions and 33 deletions
@@ -66,6 +66,16 @@ class XCBackTesterEA : public XCBase
string symbol; // Symbol
ENUM_TIMEFRAMES period; // Period
//
// Volume ...
ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect; // Volume Applying Type
double eaStaticVoluem; // Static Volume
double eaDynamicVolumeStepBalance; // Step of Balance for Increase Volume
double eaDynamicVolumeStepVolume; // Step of Volume Increasing
double eaConstantRiskBalance; // Constant Risk Balance per Trade
double eaConstantPercent; // Constant Percent of Balance Per Trade
double eaConstantBalance; // Constant Balance for Calculations
//
// Alert ...
bool eaEnableAlerts; // Enable Alerts
@@ -86,11 +96,10 @@ class XCBackTesterEA : public XCBase
XCAlert *eaAlert; // EA Scope Alert Handler ...
XCTrade *eaTrader; // EA Scope Trade Handler ...
XCTarget *eaTarget; // EA Scope Target Manager ...
XCVolume *eaVolume; // EA Scope Volume Manager ...
XCChartHelper *eaChartHelper; // EA Chart Helper ...
XCPositionDrawer *eaPositionDrawer; // EA Scope Position Drawer ...
//
XCChartHelper *eaChartHelper; // Chart Helper Class ...
//
// Constructor ...
XCBackTesterEA()
@@ -140,6 +149,10 @@ class XCBackTesterEA : public XCBase
int count = 0;
bool has = false;
//
// Chart Helper ...
eaChartHelper = new XCChartHelper();
//
// Initialize Alert Handler ...
eaAlert = new XCAlert();
@@ -297,6 +310,22 @@ class XCBackTesterEA : public XCBase
// Init Target Managers ...
eaTarget = new XCTarget(eaTrader, eaAlert);
//
eaVolume = new XCVolume();
result = eaVolume.Init(
eaVolumeSelect,
eaStaticVoluem,
eaDynamicVolumeStepBalance,
eaDynamicVolumeStepVolume,
eaConstantRiskBalance,
eaConstantPercent,
eaConstantBalance //
);
if (!result)
{
return result;
}
//
// Init Position Drawer ...
eaPositionDrawer = new XCPositionDrawer(eaTrader);
@@ -332,6 +361,10 @@ class XCBackTesterEA : public XCBase
delete eaPositionDrawer;
ZeroMemory(eaPositionDrawer);
//
delete eaVolume;
ZeroMemory(eaVolume);
//
delete eaTrader;
ZeroMemory(eaTrader);
@@ -588,6 +621,15 @@ class XCBackTesterEA : public XCBase
*/
void HandleOnSignalTriggered(XSignal &signal)
{
//
// Handle Volume ...
double iVolume = eaVolume.CalculateVolume(signal);
if (!signal.ignoreEAVolume &&
iVolume != signal.volume)
{
signal.volume = iVolume;
}
//
ENUM_X_SIGNAL_EXECUTION_RESULT result;
bool isExcuted = eaTrader.ExecuteSignal(
@@ -854,10 +896,6 @@ class XCBackTesterEA : public XCBase
ulong chartId = ChartID();
objSuffix = eaLogSuffix + "_";
//
// Initial Chart Class Instance ...
eaChartHelper = new XCChartHelper(chartId);
//
int startX = 5;
int startY = 25;
@@ -40,6 +40,17 @@ input long eaMagicNumber = 78692110; // Magic Number
input int eaSlippage = 10; // Slippgae
input string eaLogSuffix = ""; // Log Suffix
//
// Volume ...
input group "Volume";
input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_CONSTANT; // Volume Applying Type
input double eaStaticVoluem = 0.0; // Static Volume
input double eaDynamicVolumeStepBalance = 0.0; // Step of Balance for Increase Volume
input double eaDynamicVolumeStepVolume = X_MIN_VOLUME; // Step of Volume Increasing
input double eaConstantRiskBalance = 0.0; // Constant Risk Balance per Trade
input double eaConstantPercent = 1; // Constant Percent of Balance Per Trade
input double eaConstantBalance = 1000.0; // Constant Balance for Calculations
//
// Alert ...
// Here we Provider All Requirements for
@@ -232,6 +243,16 @@ int OnInit()
eaExpert.eaSlippage = eaSlippage;
eaExpert.eaLogSuffix = eaTag;
//
// Volume ...
eaExpert.eaVolumeSelect = eaVolumeSelect;
eaExpert.eaStaticVoluem = eaStaticVoluem;
eaExpert.eaDynamicVolumeStepBalance = eaDynamicVolumeStepBalance;
eaExpert.eaDynamicVolumeStepVolume = eaDynamicVolumeStepVolume;
eaExpert.eaConstantRiskBalance = eaConstantRiskBalance;
eaExpert.eaConstantPercent = eaConstantPercent;
eaExpert.eaConstantBalance = eaConstantBalance;
//
// Alert ...
eaExpert.eaEnableAlerts = eaEnableAlerts;
+33
View File
@@ -758,6 +758,39 @@ struct XOHCL
return result;
}
//
bool BarAt(
datetime _time,
XOHCL &bar //
)
{
//
bool result = false;
//
bar.Clean();
//
result = IsValid();
if (!result)
{
return result;
}
//
_time = NormalizeTime(_time);
//
result = bar.Init(
symbol,
period,
_time //
);
//
return result;
}
//
bool BarIn(
ENUM_TIMEFRAMES _period,
@@ -1378,7 +1378,7 @@ struct XPatternAnalysis
for (int i = 0; i < count; i++)
{
//
has = forDir = patternsDir[i];
has = forDir == patternsDir[i];
if (has)
{
result++;
@@ -4955,6 +4955,86 @@ bool HasInside(
return result;
}
/**
* Extract Affected Zones for Specified Bar ...
*
* @param bar: XOHCL, reference to Specified Bar ...
* @param source: XBoxZone, reference collection to Provide Data Source ...
* @param dest: XBoxZone, reference collection to holds result ...
* @param forDir: ENUM_X_DIRECTION, Specified Zones Direction to Lookup ...
*
* @return ( int )
*/
int ExtractAffectedZones(
XOHCL &bar,
XBoxZone &source[],
XBoxZone &dest[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Validate ...
bool has = bar.IsValid() &&
HasChild(source);
if (!has)
{
return result;
}
//
bool isActed;
bool isTested;
bool isInside;
bool isFakeBreaked;
for (int i = 0; i < ArraySize(source); i++)
{
//
// Validate Direction ...
has =
!HasDirection(forDir) ||
forDir == source[i].dir;
if (!has)
{
continue;
}
//
// Check Affected ...
isActed = IsActed(bar, source[i]);
isTested = IsTested(bar, source[i]);
isInside = IsInside(bar, source[i]);
isFakeBreaked = IsFakeBreaked(bar, source[i]);
//
has =
isActed ||
isTested ||
isInside ||
isFakeBreaked;
if (has)
{
//
AddIfNotExists(
source[i],
dest //
);
}
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Extract all Items which Specified Bar is inside them ...
*
@@ -284,7 +284,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
//
// Ignore Signal Targets ...
ignoreTargets = true;
ignoreTargets = false;
}
//
@@ -331,9 +331,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
string iName = NULL;
bool isBullish = false;
bool isBearish = false;
XPatternAnalysis iBarAnalysis;
XFIMAConditions iFIMAConditions;
XFIMAMarketStructure iStructure;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
@@ -380,22 +378,35 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
structureDrawConfig //
);
// //
// // Testing Porposes ...
// has = fimaHelper.IsBoundaryFakeBreaked(
// iDir,
// barIndex,
// X_PRICE_CLOSE,
// X_PRICE_CLOSE //
// );
// if (has)
// {
// Print("Faked Break ...");
// }
//
// Disable Signallers ...
has = false;
iDir = X_DIRECTION_NONE;
// has = false;
// iDir = X_DIRECTION_NONE;
//
// Strategy 1 ...
// Works on Support or Resistances Areas ...
// has = Strategy1HasSignal(
// iBar,
// iZone,
// iTargets,
// iDir,
// iFIMAConditions,
// iStructure //
// );
has = Strategy1HasSignal(
iBar,
iZone,
iTargets,
iDir,
iFIMAConditions,
structure //
);
//
// Strategy 2 ...
@@ -409,7 +420,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
// iTargets,
// iDir,
// iFIMAConditions,
// iStructure //
// structure //
// );
}
@@ -462,8 +473,6 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
iBar.Clean();
iZone.Clean();
iSignal.Clean();
iStructure.Clean();
iBarAnalysis.Clean();
iFIMAConditions.Clean();
SpecifiedClean(iTargets);
}
@@ -543,6 +552,180 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
return result;
}
//
// Testing Porposes ...
result = fimaHelper.IsBoundaryFakeBreaked(
dir,
bar.Index(),
X_PRICE_CLOSE,
X_PRICE_CLOSE //
);
//
// Nearest Noisy ZG Pivot Must has Same Direction
// by Boundary Faked Break ...
result =
result &&
HasDirection(dir) &&
_structure.zgAnalysis.IsValid() &&
_structure.zgAnalysis.HasPivots() &&
_structure.zgAnalysis.pivots[0].dir == dir;
//
// We Have to Detect a Zone which Nearest ZG Pivot Reject or goes inside it ...
//
int idx = -1;
XOHCL tmpBar;
XPivot pivot;
XPivot pivots[];
XBoxZone zones[];
bool has = false;
int zonesCount = 0;
int pivotIndex = -1;
XBoxZone affectedZone;
double bullishScore = 0;
double bearishScore = 0;
int prevPivotIndex = -1;
XBoxZone affectedZones[];
int affectedZonesCount = 0;
//
Copy(
_structure.zgAnalysis.pivots,
pivots //
);
pivot = pivots[0];
ArrayRemove(pivots, 0, 1);
//
bool isBullish = IsXBullish(dir);
bool isBearish = IsXBearish(dir);
//
zonesCount = _structure.CollectZones(
zones,
dir //
);
result = result &&
IsValidSize(zonesCount);
//
// Noisey ZG Pivot must inside atleast one of Zones ...
//
// Initial Pivots Bar ...
result =
result &&
bar.BarAt(pivot.time, tmpBar);
//
// Extract Affected Zones ...
if (result)
{
//
affectedZonesCount = ExtractAffectedZones(
tmpBar,
zones,
affectedZones,
dir //
);
}
//
// Validate Affected Zones ...
result =
result &&
HasChild(affectedZones) &&
affectedZonesCount >= 1;
if (result)
{
affectedZone = affectedZones[0];
}
result =
result &&
affectedZone.IsValid() &&
(isBullish
? bar.close > affectedZone.upper
: bar.close < affectedZone.lower);
//
// There Must another Same Directional ZG Pivot Exists
// which is Affect another Zone ...
idx = GetYoungest(pivots, pivot.type);
result =
result &&
IsValidIndex(idx) &&
affectedZone.IsValid() &&
(isBullish
? pivots[idx].value < pivot.value
: pivots[idx].value > pivot.value);
if (result)
{
//
pivot.Clean();
tmpBar.Clean();
pivot = pivots[idx];
XClean(affectedZones);
ArrayRemove(pivots, idx, 1);
//
result = bar.BarAt(pivot.time, tmpBar);
}
//
// Extract Affected Zones ...
XClean(affectedZones);
affectedZonesCount = 0;
if (result)
{
//
affectedZonesCount = ExtractAffectedZones(
tmpBar,
zones,
affectedZones,
dir //
);
}
result =
result &&
HasChild(affectedZones) &&
affectedZonesCount >= 1;
//
// Handling Scores ...
if (result)
{
//
for (int i = 0; i < ArraySize(_structure.barsAnalysis); i++)
{
//
bullishScore += _structure.barsAnalysis[i].Count(X_DIRECTION_BULLISH);
bearishScore += _structure.barsAnalysis[i].Count(X_DIRECTION_BEARISH);
}
}
result =
isBullish
? bullishScore > bearishScore
: bearishScore > bullishScore;
if (!result)
{
//
dir = X_DIRECTION_NONE;
//
return result;
}
//
// Validating ...
// Print("Validate ZG ...");
// //
// dir = X_DIRECTION_NONE;
// result = false;
//
// Prepare zone ...
if (result)
@@ -554,12 +737,43 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
bar.period,
bar.Index() + 2 //
);
zone.dir = dir;
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);
zone.type = name + "_" + ToXString(dir);
// zone.lower = bar.FindLowest(2, MODE_LOW);
// zone.upper = bar.FindHighest(2, MODE_HIGH);
double entry = GetEntry(bar.symbol, dir);
double points = GetPoints(bar.symbol);
zone.lower = entry - (100 * points);
zone.upper = entry + (100 * points);
//
double tp1 = isBullish
? entry + (100 * points)
: entry - (100 * points);
XTarget target1;
target1.target = tp1;
target1.doRF = true;
target1.actingDistance = 10;
double tp2 = isBullish
? entry + (200 * points)
: entry - (200 * points);
XTarget target2;
target2.target = tp2;
target2.doRF = true;
target2.actingDistance = 10;
//
// AddRef(
// target1,
// targets //
// );
AddRef(
target2,
targets //
);
//
result = zone.IsValid();
@@ -577,7 +791,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
}
//
// Cleanup Resources ...
// Cleanup ...
if (!result)
{
//
@@ -585,6 +799,14 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
XClean(targets);
}
//
pivot.Clean();
XClean(zones);
tmpBar.Clean();
XClean(pivots);
affectedZone.Clean();
XClean(affectedZones);
//
return result;
}
+219 -4
View File
@@ -89,6 +89,223 @@ struct XFIMAMarketStructure
return result;
}
//
// Collectors ...
/**
* Collect Required Zones from Structure ...
*
* @param dest: XBoxZone, reference collection to holds result ...
* @param forDir: ENUM_X_DIRECTION, Specified Collectiong ones Direction ...
* @param containsOB: bool, Contains OB Zones ...
* @param containsFVG: bool, Contains FVG Zones ...
*
* @return ( int )
*/
int CollectZones(
XBoxZone &dest[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
bool containsOB = false,
bool containsFVG = false //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Validate ...
bool has = IsValid();
if (!has)
{
return result;
}
//
bool canCollectBullish =
IsXBullish(forDir) ||
!HasDirection(forDir);
//
bool canCollectBearish =
IsXBearish(forDir) ||
!HasDirection(forDir);
//
int count = 0;
XBoxZone tmpBox;
//
// Check Analysis ...
//
// XPV ...
has = pvAnalysis.IsValid();
if (has)
{
//
// Support ...
tmpBox.Clean();
has = pvAnalysis.HasSupportBox(tmpBox);
if (has && canCollectBullish)
{
//
AddIfNotExists(
tmpBox,
dest //
);
}
//
// Resistance ...
tmpBox.Clean();
has = pvAnalysis.HasResistanceBox(tmpBox);
if (has && canCollectBearish)
{
//
AddIfNotExists(
tmpBox,
dest //
);
}
}
//
// XZG ...
has = zgAnalysis.IsValid();
if (has)
{
//
// Support ...
tmpBox.Clean();
has = zgAnalysis.HasSupportBox(tmpBox);
if (has && canCollectBullish)
{
//
AddIfNotExists(
tmpBox,
dest //
);
}
//
// Resistance ...
tmpBox.Clean();
has = zgAnalysis.HasResistanceBox(tmpBox);
if (has && canCollectBearish)
{
//
AddIfNotExists(
tmpBox,
dest //
);
}
}
//
// Bar Patterns ...
has = HasChild(barsAnalysis);
if (has)
{
//
count = ArraySize(barsAnalysis);
for (int i = 0; i < count; i++)
{
//
// Support ...
has = barsAnalysis[i].IsSupport();
if (has && canCollectBullish)
{
//
AddIfNotExists(
barsAnalysis[i].support,
dest //
);
}
//
// Resistance ...
has = barsAnalysis[i].IsResistance();
if (has && canCollectBearish)
{
//
AddIfNotExists(
barsAnalysis[i].resistance,
dest //
);
}
//
// OB ...
if (containsOB)
{
//
has = barsAnalysis[i].IsOB();
if (has)
{
//
has = (canCollectBullish && barsAnalysis[i].ob.IsBullish()) ||
(canCollectBearish && barsAnalysis[i].ob.IsBearish());
if (has)
{
//
AddIfNotExists(
barsAnalysis[i].ob,
dest //
);
}
}
}
//
// FVG ...
if (containsFVG)
{
has = barsAnalysis[i].IsFVG();
if (has)
{
//
has = (canCollectBullish && barsAnalysis[i].fvg.IsBullish()) ||
(canCollectBearish && barsAnalysis[i].fvg.IsBearish());
if (has)
{
//
AddIfNotExists(
barsAnalysis[i].fvg,
dest //
);
}
}
}
}
}
//
result = ArraySize(dest);
has = IsValidSize(result);
if (has)
{
//
// Update To Time ...
// and also we Can Validate Zones Here ...
datetime cTime = TimeCurrent();
for (int i = 0; i < result; i++)
{
dest[i].to = cTime;
}
}
//
// Cleanup ...
tmpBox.Clean();
//
return result;
}
//
};
@@ -281,12 +498,10 @@ struct XFIMAMarketStructureDrawerConfig
XClean(barAnalysisDrawConfig.allowedDrawZones);
Add(
X_BAR_PATTERN_SUPPORT,
barAnalysisDrawConfig.allowedDrawZones
);
barAnalysisDrawConfig.allowedDrawZones);
Add(
X_BAR_PATTERN_RESISTANCE,
barAnalysisDrawConfig.allowedDrawZones
);
barAnalysisDrawConfig.allowedDrawZones);
}
/**