This commit is contained in:
2025-10-01 12:06:18 +03:30
parent c5a1e326b2
commit 684d3028c4
11 changed files with 4472 additions and 2379 deletions
@@ -520,29 +520,14 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
XBoxZone iZone;
XSignal iSignal;
bool has = false;
XTarget targets[];
XTarget iTargets[];
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(
@@ -582,486 +567,6 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
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 //
);
}
//
// Collect Bar Support and Resistance (s) ...
//
// Disable Signallers ...
has = false;
@@ -1069,28 +574,30 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
//
// Strategy 1 ...
// Works on Support or Resistances Areas ...
// has = Strategy1HasSignal(
// iBar,
// iZone,
// supports,
// resistances,
// iDir,
// iStructure,
// iFIMAConditions //
// );
has = Strategy1HasSignal(
iBar,
iZone,
iTargets,
iDir,
iFIMAConditions,
iStructure //
);
//
// Strategy 2 ...
// Works on MA Crosses ...
has = Strategy2HasSignal(
iBar,
iZone,
supports,
resistances,
iDir,
iStructure,
iFIMAConditions //
);
if (!has)
{
//
// has = Strategy2HasSignal(
// iBar,
// iZone,
// iTargets,
// iDir,
// iFIMAConditions,
// iStructure //
// );
}
//
has = HasDirection(iDir);
@@ -1114,7 +621,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
has = PrepareSignal(
iSignal,
iDir,
targets,
iTargets,
0, // Use Default R2R ...
slPrice, // Provided Price for SL ...
0 // Specified Risk in Point ....
@@ -1134,11 +641,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
iSignal.Clean();
iStructure.Clean();
iFIMAConditions.Clean();
SpecifiedClean(targets);
SpecifiedClean(pvPivots);
SpecifiedClean(zgPivots);
SpecifiedClean(supports);
SpecifiedClean(resistances);
SpecifiedClean(iTargets);
}
/**
@@ -1180,23 +683,21 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
* 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 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 &iZone,
XBoxZone &supports[],
XBoxZone &resistances[],
ENUM_X_DIRECTION &iDir,
XFIMAMarketStructure &structure,
XFIMAConditions &conditions //
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir,
XFIMAConditions &conditions,
XFIMAMarketStructure &structure //
)
{
//
@@ -1204,8 +705,9 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
//
// Prepare ...
iZone.Clean();
iDir = X_DIRECTION_NONE;
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
@@ -1243,6 +745,81 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
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 //
);
}
//
CArrayObj *zoneObjs;
poiDrawer.DrawBoxes(
supports,
zoneObjs //
);
poiDrawer.DrawBoxes(
resistances,
zoneObjs //
);
poiDrawer.DrawBoxes(
structure.fvgs,
zoneObjs,
false //
);
//
// Check Affected Zone ...
// Select a Support or Resistance ...
@@ -1272,13 +849,13 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
// and Validate it ...
if (IsXBullish(patternDir))
{
iZone = supports[insideZoneIDX];
zone = supports[insideZoneIDX];
}
else if (IsXBearish(patternDir))
{
iZone = resistances[insideZoneIDX];
zone = resistances[insideZoneIDX];
}
result = iZone.IsValid();
result = zone.IsValid();
if (!result)
{
return result;
@@ -1287,20 +864,29 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
//
// Validate affected Zone based on Pattern's Bar ...
result = IsXBullish(patternDir)
? bar.high > iZone.upper
? bar.high > zone.upper
: IsXBearish(patternDir)
? bar.low < iZone.lower
? bar.low < zone.lower
: false;
if (result)
{
iDir = patternDir;
//
dir = patternDir;
//
// Handle Targets Detection ...
//
// Check Reversal FVGS ...
}
//
// Cleanup Resources ...
if (!result)
{
iZone.Clean();
//
zone.Clean();
XClean(targets);
}
//
@@ -1311,23 +897,21 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
* 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 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 &iZone,
XBoxZone &supports[],
XBoxZone &resistances[],
ENUM_X_DIRECTION &iDir,
XFIMAMarketStructure &structure,
XFIMAConditions &conditions //
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir,
XFIMAConditions &conditions,
XFIMAMarketStructure &structure //
)
{
//
@@ -1335,8 +919,9 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
//
// Prepare ...
iZone.Clean();
iDir = X_DIRECTION_NONE;
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
@@ -1351,109 +936,46 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
result = HasDirection(structure.maCrossDir);
//
// Collecting Bar Support and Resistances ...
XBoxZone barZones[];
int count = fimaHelper.ExtractBarZones(
barZones,
bar.Index(),
analyserConfig.recentlyPatternsMaxAllowedCollecting, // Number of Zones ...
analyserConfig.supportAndResistanceBreakeValidationLength, // Break Validation Length ...
analyserConfig.supportAndResistanceBreakeValidationLength > 0, // Validate Fake Breaked Zones ...
4, // Shadow Multiplier ...
analyserConfig.minAllowdSupportAndResistanceStrength, // Validation Strength ...
7, // Validation Length ...
analyserConfig.supportAndResistanceMaxAllowedLoopback // Max Allowed Loopback ...
);
Copy(
supports,
barZones,
false // Force Clean ...
);
Copy(
resistances,
barZones,
false // Force Clean ...
);
//
// Validate Conditions ...
XBoxZone fvg;
ENUM_X_DIRECTION tmpDir;
bool hasFVG = poiDetector.HasFVG(
bar,
tmpDir,
fvg,
3 // Max Loopback ...
);
//
// Validate result by FVG ...
// result =
// result &&
// hasFVG &&
// fvg.dir == structure.maCrossDir;
//
// Prepare zone ...
if (result)
{
//
XCBoxObject *iFVGObj;
poiDrawer.DrawBox(
fvg,
iFVGObj //
);
//
// Draw Support or Resistances based on Direction of Cross ...
CArrayObj *iZones;
count = poiDrawer.DrawBoxes(
barZones,
iZones //
);
//
Print("Cross Happens ...");
}
//
// Prepare iZone ...
if (result)
{
//
iZone.to = bar.time;
iZone.from = GetBarTime(
zone.to = bar.time;
zone.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);
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 = iZone.IsValid();
result = zone.IsValid();
}
//
// Check Result ...
if (result)
{
iDir = structure.maCrossDir;
//
dir = structure.maCrossDir;
//
// Handle Targets Detection ...
}
//
// Cleanup Resources ...
if (!result)
{
iZone.Clean();
//
zone.Clean();
XClean(targets);
}
//
fvg.Clean();
XClean(barZones);
//
return result;