This commit is contained in:
2025-09-28 15:28:06 +03:30
parent 8432cd369b
commit ca1b313e4c
3 changed files with 759 additions and 40 deletions
+645 -38
View File
@@ -154,7 +154,7 @@ XFIMAMarketStructureDrawerConfig marketStructureDrawerConfig; // POI Drawer Conf
//
// Drawer and eaDraws ...
// CArrayObj *eaDraws; // Drawn Objects ...
CArrayObj eaDraws; // Drawn Objects ...
CArrayObj *marketStructureObjects; // Market Structure Objects ...
//
@@ -386,7 +386,6 @@ int OnInit()
//
// Configure XFIMA POI Detector / Drawer ...
detectorConfig.Default();
// eaDraws = new CArrayObj();
detectorConfig.FullDetect();
marketStructureDrawerConfig.FullDraw();
@@ -901,35 +900,6 @@ void AnalyseMarket(int barIndex = 0)
detectorConfig //
);
//
if (marketStructureObjects == NULL)
{
marketStructureObjects = new CArrayObj();
}
//
// marketStructureObjects.Clear();
//
// Draw Only ...
//
// Draw Market Structure ...
// int marketStructureObjectsCount = fima2Signaller.poiDrawer.DrawMarketStructure(
// marketStructure,
// marketStructureDrawerConfig,
// marketStructureObjects //
// );
// if (IsValidIndex(marketStructureObjectsCount))
// {
// //
// // Add Drawn Objects if Necessary ...
// // AddObjects(
// // marketStructureObjects,
// // eaDraws //
// // );
// }
//
HandleSignalLookup(bar);
@@ -951,6 +921,8 @@ void HandleSignalLookup(XOHCL &bar)
//
string iName = NULL;
XBoxZone supports[];
XBoxZone resistances[];
bool isBullish = false;
int barIndex = bar.Index();
double iPrice = EMPTY_VALUE;
@@ -959,27 +931,584 @@ void HandleSignalLookup(XOHCL &bar)
//
// Check Required Pattern Exists ...
bool hasPinnedBar = HasDirection(marketStructure.pinnedDir);
bool hasEngulfedBar = HasDirection(marketStructure.engulfedDir);
bool hasSignalKeyBar = HasDirection(marketStructure.signalKeyBarPatternDir);
//
// PV Trend Line ...
string pvTrendName = "XPVTrend";
CChartObjectTrend *pvTrendLine = NULL;
ENUM_X_DIRECTION pvTrend = X_DIRECTION_NONE;
//
// ZigZag Trend Line ...
string zgTrendName = "XZGTrend";
CChartObjectTrend *zgTrendLine = NULL;
ENUM_X_DIRECTION zgTrend = X_DIRECTION_NONE;
//
// Check PV Analysis ...
bool hasPVAnalysis = marketStructure.pvAnalysis.IsValid();
if (hasPVAnalysis)
{
//
// Support ...
XBoxZone supportBox;
XCBoxObject *iSupportObj;
has = marketStructure.pvAnalysis.HasSupportBox(supportBox);
if (has)
{
//
supportBox.to = bar.time;
AddIfNotExists(
supportBox,
supports //
);
has = fima2Signaller.poiDrawer.DrawBox(
supportBox,
iSupportObj,
true, // Ignore At ...
supportBox.type // Name ...
);
if (has)
{
//
XPOIStyle iStyle;
fima2Signaller.poiDrawer.GetBoxStyle(
iStyle,
supportBox.dir //
);
fima2Signaller.poiDrawer.ApplyBoxStyle(
iSupportObj,
iStyle //
);
iStyle.Clean();
}
}
//
// Resistance ...
XBoxZone resistanceBox;
XCBoxObject *iResistanceObj;
has = marketStructure.pvAnalysis.HasResistanceBox(resistanceBox);
if (has)
{
//
resistanceBox.to = bar.time;
AddIfNotExists(
resistanceBox,
supports //
);
has = fima2Signaller.poiDrawer.DrawBox(
resistanceBox,
iResistanceObj,
true, // Ignore At ...
resistanceBox.type // Name ...
);
if (has)
{
//
XPOIStyle iStyle;
fima2Signaller.poiDrawer.GetBoxStyle(
iStyle,
resistanceBox.dir //
);
fima2Signaller.poiDrawer.ApplyBoxStyle(
iResistanceObj,
iStyle //
);
iStyle.Clean();
}
}
//
// Pivots ...
XPivot pivots[];
int pivotsCount = fima2Signaller.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 = fima2Signaller.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 = fima2Signaller.poiDrawer.DrawPivots(
pivots,
drawnPivots //
);
}
//
// Cleanup Resources ...
SpecifiedClean(pivots);
}
//
// Check ZigZag Analysis ...
bool hasZGAnalysis = marketStructure.zigzagAnalysis.IsValid();
if (hasZGAnalysis)
{
//
// Support ...
// XBoxZone supportBox;
// XCBoxObject *iSupportObj;
// has = marketStructure.zigzagAnalysis.HasSupportBox(supportBox);
// if (has)
// {
// //
// supportBox.to = bar.time;
// AddIfNotExists(
// supportBox,
// supports //
// );
// has = fima2Signaller.poiDrawer.DrawBox(
// supportBox,
// iSupportObj,
// true, // Ignore At ...
// supportBox.type // Name ...
// );
// if (has)
// {
// //
// XPOIStyle iStyle;
// fima2Signaller.poiDrawer.GetBoxStyle(
// iStyle,
// supportBox.dir //
// );
// fima2Signaller.poiDrawer.ApplyBoxStyle(
// iSupportObj,
// iStyle //
// );
// iStyle.Clean();
// }
// }
//
// Resistance ...
// XBoxZone resistanceBox;
// XCBoxObject *iResistanceObj;
// has = marketStructure.zigzagAnalysis.HasResistanceBox(resistanceBox);
// if (has)
// {
// //
// resistanceBox.to = bar.time;
// AddIfNotExists(
// resistanceBox,
// supports //
// );
// has = fima2Signaller.poiDrawer.DrawBox(
// resistanceBox,
// iResistanceObj,
// true, // Ignore At ...
// resistanceBox.type // Name ...
// );
// if (has)
// {
// //
// XPOIStyle iStyle;
// fima2Signaller.poiDrawer.GetBoxStyle(
// iStyle,
// resistanceBox.dir //
// );
// fima2Signaller.poiDrawer.ApplyBoxStyle(
// iResistanceObj,
// iStyle //
// );
// iStyle.Clean();
// }
// }
//
// Pivots ...
XPivot pivots[];
int pivotsCount = fima2Signaller.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 = fima2Signaller.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);
}
//
// Selecting Price Type of Bar based on Dir ...
has = hasEngulfedBar ||
has = hasPinnedBar ||
hasEngulfedBar ||
hasSignalKeyBar;
if (has)
{
//
// Retrieve Direction ...
if (hasEngulfedBar)
if (hasPinnedBar)
{
//
iDir = marketStructure.pinnedDir;
iName = "XPin_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasEngulfedBar)
{
//
iDir = marketStructure.engulfedDir;
iName = "XEngulf_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else
else if (hasSignalKeyBar)
{
//
iDir = marketStructure.signalKeyBarPatternDir;
iName = "XEngulf_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
iName = "SignalKey_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
//
@@ -1002,6 +1531,70 @@ void HandleSignalLookup(XOHCL &bar)
has = isBullish
? iPrice < iMABandLower
: iPrice > iMABandUpper;
//
// Check Support and Resistance ...
//
// Support ...
bool hasSupport = marketStructure.support.IsValid();
if (hasSupport)
{
//
AddIfNotExists(
marketStructure.support,
supports //
);
//
XCBoxObject *iObj;
has = fima2Signaller.poiDrawer.DrawBox(
marketStructure.support,
iObj);
if (has)
{
}
}
//
// Resistance ...
bool hasResistance = marketStructure.resistance.IsValid();
if (hasResistance)
{
//
AddIfNotExists(
marketStructure.resistance,
resistances //
);
//
XCBoxObject *iObj;
has = fima2Signaller.poiDrawer.DrawBox(
marketStructure.resistance,
iObj);
if (has)
{
}
}
//
// Validate Happens in Zone ...
int insideZoneIDX = -1;
has = has &&
(isBullish
? HasInside(
insideZoneIDX,
bar,
supports //
)
: HasInside(
insideZoneIDX,
bar,
resistances //
)) &&
IsValidIndex(insideZoneIDX);
//
if (has)
{
//
@@ -1026,11 +1619,25 @@ void HandleSignalLookup(XOHCL &bar)
true, // Ignore Bar Tag ...
10 // Threshold ...
);
//
Print("Detect a Potential Place for Price Movement: ", ToXString(iDir), ", Time: ", bar.time);
if (has)
{
}
}
}
//
// Checking Liquidities ...
//
if (has)
{
Print("Detect a Potential Place for Price Movement: ", ToXString(iDir), ", Time: ", bar.time);
}
//
// Cleanup Resources ...
SpecifiedClean(supports);
SpecifiedClean(resistances);
}
//