This commit is contained in:
2025-09-28 19:57:03 +03:30
parent aebb2a5244
commit f4067df926
2 changed files with 767 additions and 53 deletions
@@ -41,8 +41,8 @@ class XCXFIMABaseSignaller : public XCBaseSignaller
// Props ...
//
XFIMAInputs fimaInputs; // XFIMA Inputs ...
XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ...
XFIMAInputs fimaInputs; // XFIMA Inputs ...
XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ...
XCXFIMAPOIDrawer *poiDrawer; // XFIMA POI Drawer ...
XCXFIMAPOIDetector *poiDetector; // XFIMA POI Detector ...
@@ -351,7 +351,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
{
//
// Do Conditions Validating ...
// TODO: Igmore All Validations for Testing Purposes ...
// TODO: Igmore All Validations for Testing Purposes ...
//
// Validate MA Positions ...
@@ -545,6 +545,7 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller
public:
//
// Props ...
XFIMAPatternDetectorConfig analyserConfig;
//
// Constructor ...
@@ -566,6 +567,21 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller
_defaultSignalVolume //
)
{
//
// Configure Detector ...
analyserConfig.Default();
analyserConfig.FullDetect();
}
//
// Deconstructor ...
~XCXFIMAStrategy2Signaller()
{
//
Destroy();
//
analyserConfig.Clean();
}
//
@@ -611,10 +627,20 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller
//
XOHCL bar;
XSignal signal;
XBoxZone iZone;
bool has = false;
int cIdx = barIndex + 1;
int pIdx = cIdx + 1;
ENUM_X_DIRECTION signalDir = X_DIRECTION_NONE;
string iName = NULL;
bool isBullish = false;
bool isBearish = false;
double iPrice = EMPTY_VALUE;
XBoxZone supports[];
XBoxZone resistances[];
ENUM_X_PRICE iPriceType = X_PRICE_NONE;
XFIMAMarketStructure structure;
XFIMAConditions fimaConditions;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
// Initialize Bar as CBar ...
@@ -632,7 +658,6 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller
//
// Retrieve Conditions ...
XFIMAConditions fimaConditions;
has = fimaHelper.GetConditions(
fimaConditions,
barIndex,
@@ -649,12 +674,98 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller
}
//
// Analyse Conditions for Finding Signal ...
bool isBullish = false;
bool isBearish = false;
// Analyse Market ...
poiDetector.AnalyseMarket(
bar,
structure,
analyserConfig //
);
//
// Chekc Bullish or Bearish Starter Conditions ...
// 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 ...
has = hasPinnedBar ||
hasEngulfedBar ||
hasFlagPattern ||
hasStarPattern ||
hasSignalKeyBar ||
hasRisingPattern ||
hasPiercingPattern;
//
// Select Pattern Direction and Price and Price Type ...
if (has)
{
//
if (hasPinnedBar)
{
//
iDir = structure.pinnedDir;
iName = "XPinned_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasEngulfedBar)
{
//
iDir = structure.engulfedDir;
iName = "XEngulfed_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasFlagPattern)
{
//
iDir = structure.flagPatternDir;
iName = "XFlag_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasStarPattern)
{
//
iDir = structure.starPatternDir;
iName = "XStar_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasSignalKeyBar)
{
//
iDir = structure.risingPatternDir;
iName = "XRising_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasRisingPattern)
{
//
iDir = structure.piercingPatternDir;
iName = "XPiercing_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasPiercingPattern)
{
//
iDir = structure.signalKeyBarPatternDir;
iName = "XSignalKey_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
//
isBullish = IsSpecifiedBullish(iDir);
isBearish = IsSpecifiedBearish(iDir);
//
// Retrieve Price Type for Validate ...
iPriceType = isBullish
? X_PRICE_LOW
: X_PRICE_HIGH;
iPrice = bar.GetPrice(iPriceType);
//
has = HasDirection(iDir);
}
//
// Chekc Bullish or Bearish Starter Conditions Exists ...
has =
isBullish ||
isBearish;
@@ -664,57 +775,659 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller
// Do Conditions Validating ...
//
// Bullish Validation ...
isBullish =
//
isBullish
//
&&
//
// Validations ...
(
//
false
//
)
//
;
// Retrieve MA Band for Validation ...
double iMABandUpper = fimaHelper.GetMABandUpper(barIndex);
double iMABandLower = fimaHelper.GetMABandLower(barIndex);
//
// Bearish Validation ...
isBearish =
//
isBearish
//
&&
//
// Validations ...
(
//
false
//
)
//
;
//
has =
(isBullish && !isBearish) ||
(isBearish && !isBullish);
if (has)
// Validate ...
has = isBullish
? iPrice < iMABandLower
: iPrice > iMABandUpper;
if (!has)
{
//
// Specified Signal Directions ...
signalDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
iDir = X_DIRECTION_NONE;
}
}
//
// Collect Support and Resistance Zones and Validate by them ...
//
// PV Trend Line ...
string pvTrendName = "XXIFMA2PVTrend";
CChartObjectTrend *pvTrendLine = NULL;
ENUM_X_DIRECTION pvTrend = X_DIRECTION_NONE;
bool hasPVAnalysis = structure.pvAnalysis.IsValid();
if (hasPVAnalysis)
{
//
// Support ...
XBoxZone supportBox;
XCBoxObject *iSupportObj;
has = structure.pvAnalysis.HasSupportBox(supportBox);
if (has)
{
//
supportBox.to = bar.time;
AddIfNotExists(
supportBox,
supports //
);
has = poiDrawer.DrawBox(
supportBox,
iSupportObj,
true, // Ignore At ...
supportBox.type // Name ...
);
if (has)
{
//
XPOIStyle iStyle;
poiDrawer.GetBoxStyle(
iStyle,
supportBox.dir //
);
poiDrawer.ApplyBoxStyle(
iSupportObj,
iStyle //
);
iStyle.Clean();
}
}
//
// Resistance ...
XBoxZone resistanceBox;
XCBoxObject *iResistanceObj;
has = structure.pvAnalysis.HasResistanceBox(resistanceBox);
if (has)
{
//
resistanceBox.to = bar.time;
AddIfNotExists(
resistanceBox,
supports //
);
has = poiDrawer.DrawBox(
resistanceBox,
iResistanceObj,
true, // Ignore At ...
resistanceBox.type // Name ...
);
if (has)
{
//
XPOIStyle iStyle;
poiDrawer.GetBoxStyle(
iStyle,
resistanceBox.dir //
);
poiDrawer.ApplyBoxStyle(
iResistanceObj,
iStyle //
);
iStyle.Clean();
}
}
//
// Pivots ...
XPivot pivots[];
int pivotsCount = poiDetector.ExtractPVPivots(
pivots,
barIndex,
50 //
);
has = IsValidSize(pivotsCount);
//
// 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);
}
//
// Draw Pivots ...
has = HasChild(pivots);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
pivotsCount = poiDrawer.DrawPivots(
pivots,
drawnPivots //
);
}
//
// Cleanup Resources ...
SpecifiedClean(pivots);
}
//
// ZigZag Trend Line ...
string zgTrendName = "XFIMA2ZGTrend";
CChartObjectTrend *zgTrendLine = NULL;
ENUM_X_DIRECTION zgTrend = X_DIRECTION_NONE;
bool hasZGAnalysis = structure.zigzagAnalysis.IsValid();
if (hasZGAnalysis)
{
//
// Support ...
XBoxZone supportBox;
XCBoxObject *iSupportObj;
has = structure.zigzagAnalysis.HasSupportBox(supportBox);
if (has)
{
//
supportBox.to = bar.time;
AddIfNotExists(
supportBox,
supports //
);
has = poiDrawer.DrawBox(
supportBox,
iSupportObj,
true, // Ignore At ...
supportBox.type // Name ...
);
if (has)
{
//
XPOIStyle iStyle;
poiDrawer.GetBoxStyle(
iStyle,
supportBox.dir //
);
poiDrawer.ApplyBoxStyle(
iSupportObj,
iStyle //
);
iStyle.Clean();
}
}
//
// Resistance ...
XBoxZone resistanceBox;
XCBoxObject *iResistanceObj;
has = structure.zigzagAnalysis.HasResistanceBox(resistanceBox);
if (has)
{
//
resistanceBox.to = bar.time;
AddIfNotExists(
resistanceBox,
supports //
);
has = poiDrawer.DrawBox(
resistanceBox,
iResistanceObj,
true, // Ignore At ...
resistanceBox.type // Name ...
);
if (has)
{
//
XPOIStyle iStyle;
poiDrawer.GetBoxStyle(
iStyle,
resistanceBox.dir //
);
poiDrawer.ApplyBoxStyle(
iResistanceObj,
iStyle //
);
iStyle.Clean();
}
}
//
// Pivots ...
XPivot pivots[];
int pivotsCount = poiDetector.ExtractZigZagPivots(
pivots,
barIndex,
10 //
);
has = IsValidSize(pivotsCount);
//
// 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);
}
//
// Draw Pivots ...
has = HasChild(pivots);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
pivotsCount = fima2Signaller.poiDrawer.DrawPivots(
pivots,
drawnPivots //
);
}
//
// Cleanup Resources ...
SpecifiedClean(pivots);
}
//
// Support ...
bool hasSupport = structure.support.IsValid();
if (hasSupport)
{
//
AddIfNotExists(
structure.support,
supports //
);
//
XCBoxObject *iObj;
has = fima2Signaller.poiDrawer.DrawBox(
structure.support,
iObj);
if (has)
{
}
}
//
// Resistance ...
bool hasResistance = structure.resistance.IsValid();
if (hasResistance)
{
//
AddIfNotExists(
structure.resistance,
resistances //
);
//
XCBoxObject *iObj;
has = fima2Signaller.poiDrawer.DrawBox(
structure.resistance,
iObj);
if (has)
{
}
}
//
// Validate Positions Support and Resistance Zone ...
int insideZoneIDX = -1;
has = has &&
(isBullish
? HasInside(
insideZoneIDX,
bar,
supports //
)
: HasInside(
insideZoneIDX,
bar,
resistances //
));
//
// Validate Selected Inside Zone ...
// whith Bars Edge ...
has = IsValidIndex(insideZoneIDX);
if (has)
{
//
if (isBullish)
{
iZone = supports[insideZoneIDX];
}
else
{
iZone = resistances[insideZoneIDX];
}
//
has = isBullish
? bar.high > supports[insideZoneIDX].upper
: bar.low < resistances[insideZoneIDX].lower;
if (!has)
{
iDir = X_DIRECTION_NONE;
}
}
//
// Checking Liquidities ...
//
// Do all Draws Here ...
//
// Check Signal Founded ...
has = HasDirection(signalDir);
has = HasDirection(iDir);
if (has)
{
//
@@ -725,7 +1438,7 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller
XTarget targets[];
has = PrepareSignal(
signal,
signalDir,
iDir,
targets //
);
if (has)