fix trending draw issues ...

This commit is contained in:
2025-09-24 16:25:07 +03:30
parent e2b05b6455
commit 7d00ab69cb
6 changed files with 563 additions and 82 deletions
+30 -11
View File
@@ -256,7 +256,8 @@ class XCPOIDrawer : public XCBase
color clr = clrYellow, color clr = clrYellow,
int width = 3, int width = 3,
ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM,
string name = NULL // string name = NULL,
bool ignoreBarTag = true //
) )
{ {
// //
@@ -285,7 +286,10 @@ class XCPOIDrawer : public XCBase
(IsValid(prefix) (IsValid(prefix)
? prefix + "_" ? prefix + "_"
: prefix) + : prefix) +
ToMD5(barTag); (IsSpecifiedValid(name)
? name
: "") +
(ignoreBarTag ? "" : ToMD5(barTag));
// //
object = new XCBarArrowObject(); object = new XCBarArrowObject();
@@ -404,13 +408,13 @@ class XCPOIDrawer : public XCBase
/** /**
* Draw Specified Pivot Collection ... * Draw Specified Pivot Collection ...
* *
* @param pivots: XPivot, reference Collection to Draw ... * @param pivots: XPivot, reference Collection to Draw ...
* @param draws: CArrayObj, pointer reference to Hold Drawn Objects ... * @param draws: CArrayObj, pointer reference to Hold Drawn Objects ...
* @param peakArrow: int, Specified Arrow Code for Peak Pivots ... * @param peakArrow: int, Specified Arrow Code for Peak Pivots ...
* @param valeArrow: int, Specified Arrow Code for Vale Pivots ... * @param valeArrow: int, Specified Arrow Code for Vale Pivots ...
* @param threshold: int, distance between price and arrow in Point ... * @param threshold: int, distance between price and arrow in Point ...
* *
* @return ( int ) * @return ( int )
*/ */
int DrawPivots( int DrawPivots(
@@ -787,7 +791,7 @@ class XCPOIDrawer : public XCBase
// //
// Prepare ... // Prepare ...
object = NULL; object = NULL;
// //
int count = ArraySize(swings); int count = ArraySize(swings);
result = HasChild(swings) && result = HasChild(swings) &&
@@ -801,19 +805,31 @@ class XCPOIDrawer : public XCBase
// //
bool isBullish = IsSpecifiedBullish(dir); bool isBullish = IsSpecifiedBullish(dir);
//
XOHCL _swings[];
Copy(
swings,
_swings //
);
SortBar(
_swings,
X_SORT_BY_DATE,
X_DIRECTION_BULLISH //
);
// //
double price1 = double price1 =
isBullish isBullish
? swings[0].low ? _swings[0].low
: swings[0].high; : _swings[0].high;
datetime time1 = swings[0].time; datetime time1 = _swings[0].time;
// //
double price2 = double price2 =
isBullish isBullish
? swings[count - 1].low ? _swings[count - 1].low
: swings[count - 1].high; : _swings[count - 1].high;
datetime time2 = swings[count - 1].time; datetime time2 = _swings[count - 1].time;
// //
ulong chartId = ChartIdentification(); ulong chartId = ChartIdentification();
@@ -844,6 +860,9 @@ class XCPOIDrawer : public XCBase
object.RayRight(rayRight); object.RayRight(rayRight);
} }
//
SpecifiedClean(_swings);
// //
return result; return result;
} }
+14 -4
View File
@@ -385,9 +385,11 @@ int OnInit()
// //
// Configure XFIMA POI Detector / Drawer ... // Configure XFIMA POI Detector / Drawer ...
detectorConfig.Clean(); detectorConfig.Default();
detectorConfig.detectTrueGaped = true; detectorConfig.OffDetectors();
detectorConfig.detectSwingTrend = true;
marketStructureDrawerConfig.FullDraw(); marketStructureDrawerConfig.FullDraw();
marketStructureDrawerConfig.swingTrendRayLeft = false;
// //
Print(ShortName, ": Initialized Successfully ..."); Print(ShortName, ": Initialized Successfully ...");
@@ -486,9 +488,17 @@ void OnTick()
eaDraws // eaDraws //
); );
} }
if (HasDirection(marketStructure.trueGapedDir)) if (HasDirection(marketStructure.trendDir))
{ {
Print("true gap detected ..."); Print("Detected ...");
}
if (marketStructure.ob.IsValid() && marketStructure.fvg.IsValid())
{
Print("Detected ...");
}
if (marketStructure.support.IsValid() || marketStructure.resistance.IsValid())
{
Print("Detected ...");
} }
} }
+405 -50
View File
@@ -21,6 +21,7 @@
// //
// Imports ... // Imports ...
#include "../Libraries/x-saherelm.x-ohcl.lib.mq5"
#include "../Libraries/x-saherelm.x-poi.lib.mq5" #include "../Libraries/x-saherelm.x-poi.lib.mq5"
// //
@@ -29,6 +30,51 @@
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Oldest Detection | //| Oldest Detection |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
/**
* Get Oldest Index of Specified Collection ...
*
* @param source: Specified Collection ...
*
* @return ( int )
*/
int GetOldestBar(
XOHCL &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XOHCL selected;
for (int i = 0; i < count; i++)
{
//
bool canSet =
!selected.IsValid()
? true
: selected.time > source[i].time;
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/** /**
* Get Oldest Index of Specified Collection ... * Get Oldest Index of Specified Collection ...
* *
@@ -54,23 +100,17 @@ int GetOldest(
XBoxZone selected; XBoxZone selected;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
//
XBoxZone iBox = source[i];
// //
bool canSet = bool canSet =
!selected.IsValid() !selected.IsValid()
? true ? true
: selected.from > iBox.from; : selected.from > source[i].from;
if (canSet) if (canSet)
{ {
// //
result = i; result = i;
selected = iBox; selected = source[i];
} }
//
iBox.Clean();
} }
// //
@@ -114,16 +154,9 @@ int GetOldestByBar(
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
// //
XBoxZone iBox = source[i]; bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, source[i]);
//
bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, iBox);
if (!isBoxValidForBar) if (!isBoxValidForBar)
{ {
//
iBox.Clean();
//
continue; continue;
} }
@@ -131,16 +164,13 @@ int GetOldestByBar(
bool canSet = bool canSet =
!selected.IsValid() !selected.IsValid()
? true ? true
: selected.from > iBox.from; : selected.from > source[i].from;
if (canSet) if (canSet)
{ {
// //
result = i; result = i;
selected = iBox; selected = source[i];
} }
//
iBox.Clean();
} }
// //
@@ -224,6 +254,51 @@ int GetOldest(
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Youngest Detection | //| Youngest Detection |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
/**
* Get Youngest Index of Specified Collection ...
*
* @param source: Specified Collection ...
*
* @return ( int )
*/
int GetYoungestBar(
XOHCL &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XOHCL selected;
for (int i = 0; i < count; i++)
{
//
bool canSet =
!selected.IsValid()
? true
: selected.time < source[i].time;
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/** /**
* Get Youngest Index of Specified Collection ... * Get Youngest Index of Specified Collection ...
* *
@@ -249,23 +324,17 @@ int GetYoungest(
XBoxZone selected; XBoxZone selected;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
//
XBoxZone iBox = source[i];
// //
bool canSet = bool canSet =
!selected.IsValid() !selected.IsValid()
? true ? true
: selected.from < iBox.from; : selected.from < source[i].from;
if (canSet) if (canSet)
{ {
// //
result = i; result = i;
selected = iBox; selected = source[i];
} }
//
iBox.Clean();
} }
// //
@@ -309,16 +378,9 @@ int GetYoungestByBar(
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
// //
XBoxZone iBox = source[i]; bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, source[i]);
//
bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, iBox);
if (!isBoxValidForBar) if (!isBoxValidForBar)
{ {
//
iBox.Clean();
//
continue; continue;
} }
@@ -326,16 +388,13 @@ int GetYoungestByBar(
bool canSet = bool canSet =
!selected.IsValid() !selected.IsValid()
? true ? true
: selected.from < iBox.from; : selected.from < source[i].from;
if (canSet) if (canSet)
{ {
// //
result = i; result = i;
selected = iBox; selected = source[i];
} }
//
iBox.Clean();
} }
// //
@@ -419,6 +478,65 @@ int GetYoungest(
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Highest Detection | //| Highest Detection |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
/**
* Get Highest Index of Specified Collection ...
*
* @param source: Specified Collection ...
* @param _priceType: Specified Price type ...
*
* @return ( int )
*/
int GetHighestBar(
XOHCL &source[],
ENUM_X_PRICE _priceType = X_PRICE_HIGH //
)
{
//
int result = -1;
//
if (!IsXValid(_priceType))
{
_priceType = X_PRICE_HIGH;
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XOHCL selected;
double iPrice = EMPTY_VALUE;
double selectedPrice = EMPTY_VALUE;
for (int i = 0; i < count; i++)
{
//
iPrice = source[i].GetPrice(_priceType);
selectedPrice = selected.GetPrice(_priceType);
//
bool canSet =
!selected.IsValid()
? true
: selectedPrice < iPrice;
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/** /**
* Get Highest Index of Specified Collection ... * Get Highest Index of Specified Collection ...
* *
@@ -444,23 +562,17 @@ int GetHighest(
XBoxZone selected; XBoxZone selected;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
//
XBoxZone iBox = source[i];
// //
bool canSet = bool canSet =
!selected.IsValid() !selected.IsValid()
? true ? true
: selected.upper < iBox.upper; : selected.upper < source[i].upper;
if (canSet) if (canSet)
{ {
// //
result = i; result = i;
selected = iBox; selected = source[i];
} }
//
iBox.Clean();
} }
// //
@@ -614,6 +726,64 @@ int GetHighest(
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Loest Detection | //| Loest Detection |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
/**
* Get Lowest Index of Specified Collection ...
*
* @param source: Specified Collection ...
*
* @return ( int )
*/
int GetLowestBar(
XOHCL &source[],
ENUM_X_PRICE _priceType = X_PRICE_LOW //
)
{
//
int result = -1;
//
if (!IsXValid(_priceType))
{
_priceType = X_PRICE_LOW;
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XOHCL selected;
double iPrice = EMPTY_VALUE;
double selectedPrice = EMPTY_VALUE;
for (int i = 0; i < count; i++)
{
//
iPrice = source[i].GetPrice(_priceType);
selectedPrice = selected.GetPrice(_priceType);
//
bool canSet =
!selected.IsValid()
? true
: selectedPrice > iPrice;
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/** /**
* Get Lowest Index of Specified Collection ... * Get Lowest Index of Specified Collection ...
* *
@@ -920,6 +1090,94 @@ int SelectItemForSorting(
return result; return result;
} }
/**
* Select Specified Index of a Collection by Sort Params ...
*
* @param source: Collection for Search ...
* @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ...
* @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ...
*
* @return ( int )
*/
int SelectBarForSorting(
XOHCL &source[],
ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE,
ENUM_X_DIRECTION sortDir = X_DIRECTION_BULLISH,
ENUM_X_PRICE priceType = X_PRICE_NONE //
)
{
//
int result = -1;
//
// Validate ...
if (!HasChild(source) ||
!IsXValid(sortBy) ||
!HasDirection(sortDir))
{
return result;
}
//
// Sort By Date ...
if (sortBy == X_SORT_BY_DATE)
{
//
// Select Based on Sorting Direction ...
//
// form Oldest to Youngest ...
if (sortDir == X_DIRECTION_BULLISH)
{
result = GetOldestBar(source);
}
//
// form Youngest to Oldest ...
else if (sortDir == X_DIRECTION_BEARISH)
{
result = GetYoungestBar(source);
}
//
// Not Valid ...
else
{
result = -1;
}
}
//
// Sort By Value ...
else if (sortBy == X_SORT_BY_VALUE)
{
//
// form Lowst to Highest ...
if (sortDir == X_DIRECTION_BULLISH)
{
result = GetLowestBar(source, priceType);
}
//
// form Highest to Lowest ...
else if (sortDir == X_DIRECTION_BEARISH)
{
result = GetHighestBar(source, priceType);
}
//
// Not Valid ...
else
{
result = -1;
}
}
//
// Not Valid ...
else
{
result = -1;
}
//
return result;
}
/** /**
* Apply Sort on Specified Collection ... * Apply Sort on Specified Collection ...
* *
@@ -1014,6 +1272,103 @@ void Sort(
// Cleanup Resources ... // Cleanup Resources ...
SpecifiedClean(tmps); SpecifiedClean(tmps);
} }
/**
* Apply Sort on Specified Collection ...
*
* @param source: Collection Reference to Sort ...
* @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ...
* @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ...
* @param priceType: ENUM_X_PRICE, Price Selecting Method ...
* @param maxAllowed: int, Max Allowed Collection Size ...
*/
void SortBar(
XOHCL &source[],
ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE,
ENUM_X_DIRECTION sortDir = X_DIRECTION_BULLISH,
ENUM_X_PRICE priceType = X_PRICE_NONE,
int maxAllowed = 0 //
)
{
//
int idx = -1;
bool has = false;
//
// Validate ...
has =
IsXValid(sortBy) &&
HasChild(source) &&
HasDirection(sortDir);
if (!has)
{
return;
}
//
// Copy source for Manipulating ...
XOHCL tmps[];
Copy(
source,
tmps //
);
//
// Clean Source Collection for Adding Sorted Items ...
Clean(source);
//
// Loop Through Temp Collection Has Child ...
while (HasChild(tmps))
{
//
// Select Based on Sorting Parameter ...
idx = SelectBarForSorting(
tmps,
sortBy,
sortDir,
priceType //
);
//
// Validate Detected Index ...
has = IsValidIndex(idx);
if (!has)
{
break;
}
//
// Add Detected Indexed Item to Source ...
AddRef(
tmps[idx],
source //
);
//
// Remove Item From Temp Collection ...
ArrayRemove(
tmps,
idx,
1 //
);
}
//
// Cleanup Collection if Max Items Reached ...
if (maxAllowed > 0)
{
//
CleanupArray(
source,
maxAllowed //
);
}
//
// Cleanup Resources ...
SpecifiedClean(tmps);
}
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -779,7 +779,7 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector
// //
// Detect Supports ... // Detect Supports ...
if (config.detectSupports) if (config.detectSupport)
{ {
// //
XOHCL support; XOHCL support;
@@ -33,6 +33,50 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer
public: public:
// //
//
// Constructor ...
XCXFIMAPOIDrawer() : XCPOIDrawer()
{
Default();
}
//
// Deconstructor ...
~XCXFIMAPOIDrawer()
{
}
//
// Overrides ...
/**
* Do additional Configurations for Child Classes ...
*/
void virtual Default() override
{
//
// Apply Default Props ...
//
Prefix(NULL);
ChartIdentification(0);
SubWindowIdentification(0);
//
defaultBullishStyle.width = 1;
defaultBullishStyle.clr = clrAqua;
defaultBullishStyle.style = STYLE_SOLID;
//
defaultBearishStyle.width = 1;
defaultBearishStyle.clr = clrMagenta;
defaultBearishStyle.style = STYLE_SOLID;
//
boxBullishStyle = defaultBullishStyle;
boxBearishStyle = defaultBearishStyle;
}
// //
// Get Specified Directional Arrow Anchor ... // Get Specified Directional Arrow Anchor ...
ENUM_ARROW_ANCHOR GetArrowAnchor(ENUM_X_DIRECTION forDir) ENUM_ARROW_ANCHOR GetArrowAnchor(ENUM_X_DIRECTION forDir)
@@ -155,6 +199,15 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer
} }
} }
/**
* Draw Specified Market Structure Based on Given Configs ...
*
* @param structure: XFIMAMarketStructure, reference to Provide Specifid Market Structure ...
* @param config: XFIMAMarketStructureDrawerConfig, reference to Provide Drawing Configurations ...
* @param objects: CArrayObj, pointer reference to Holds drawn Objects instances ...
*
* @return ( int )
*/
int DrawMarketStructure( int DrawMarketStructure(
XFIMAMarketStructure &structure, XFIMAMarketStructure &structure,
XFIMAMarketStructureDrawerConfig &config, XFIMAMarketStructureDrawerConfig &config,
@@ -314,9 +367,9 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer
has = DrawSwingTrend( has = DrawSwingTrend(
structure.trendSwings, structure.trendSwings,
structure.trendDir, structure.trendDir,
iObj, // iObj, //
true, // Ray Right ... config.swingTrendRayRight, // Ray Right ...
false // Ray Left ... config.swingTrendRayLeft // Ray Left ...
); );
if (has) if (has)
{ {
+57 -13
View File
@@ -41,7 +41,7 @@ struct XFIMAPatternDetectorConfig
// Flags ... // Flags ...
// //
bool detectSupports; bool detectSupport;
bool detectResistance; bool detectResistance;
// //
@@ -138,7 +138,7 @@ struct XFIMAPatternDetectorConfig
// //
detectOB = false; detectOB = false;
detectFVG = false; detectFVG = false;
detectSupports = false; detectSupport = false;
detectResistance = false; detectResistance = false;
detectSwingTrend = false; detectSwingTrend = false;
detectStarPattern = false; detectStarPattern = false;
@@ -185,14 +185,14 @@ struct XFIMAPatternDetectorConfig
{ {
// //
// OB / FVG ... // OB / FVG ...
detectOB = true; detectOB = false;
detectFVG = true; detectFVG = false;
// //
// Support and Resistances ... // Support and Resistances ...
detectSupports = true; detectSupport = false;
detectResistance = true; detectResistance = false;
detectSwingTrend = true; detectSwingTrend = false;
// //
// Patterns ... // Patterns ...
@@ -223,12 +223,12 @@ struct XFIMAPatternDetectorConfig
// //
// Trending ... // Trending ...
trendingNumberOfSwings = 3; trendingNumberOfSwings = 5;
trendingSwingShoulders = 7; trendingSwingShoulders = 7;
// //
// Support and Resistance ... // Support and Resistance ...
supportAndResistanceValidationLength = 21; supportAndResistanceValidationLength = 100;
supportAndResistanceMaxAllowedLoopback = 1500; supportAndResistanceMaxAllowedLoopback = 1500;
// //
@@ -269,9 +269,6 @@ struct XFIMAPatternDetectorConfig
*/ */
void FullDetect() void FullDetect()
{ {
//
Default();
// //
// OB / FVG ... // OB / FVG ...
detectOB = true; detectOB = true;
@@ -279,7 +276,7 @@ struct XFIMAPatternDetectorConfig
// //
// Support and Resistances ... // Support and Resistances ...
detectSupports = true; detectSupport = true;
detectResistance = true; detectResistance = true;
detectSwingTrend = true; detectSwingTrend = true;
@@ -306,6 +303,45 @@ struct XFIMAPatternDetectorConfig
analyseFIMAZigZagPivots = true; analyseFIMAZigZagPivots = true;
} }
/**
* Default Config, by turn off all detecting flags ...
*/
void OffDetectors()
{
//
// OB / FVG ...
detectOB = false;
detectFVG = false;
//
// Support and Resistances ...
detectSupport = false;
detectResistance = false;
detectSwingTrend = false;
//
// Patterns ...
detectStarPattern = false;
detectFlagPattern = false;
detectRisingPattern = false;
detectPiercingPattern = false;
detectSignalKeyBarPattern = false;
//
// Bars ...
detectPinned = false;
detectMomentum = false;
detectEngulfed = false;
detectTrueGaped = false;
//
// Analysers ...
analyseFIMAPVPivots = false;
analyseFIMAMAPivots = false;
analyseFIMASARPivots = false;
analyseFIMAZigZagPivots = false;
}
// //
}; };
@@ -418,6 +454,8 @@ struct XFIMAMarketStructureDrawerConfig
// //
bool drawSwingTrend; bool drawSwingTrend;
bool swingTrendRayLeft;
bool swingTrendRayRight;
// //
bool drawOB; bool drawOB;
@@ -479,7 +517,9 @@ struct XFIMAMarketStructureDrawerConfig
drawSwingTrend = false; drawSwingTrend = false;
drawStarPattern = false; drawStarPattern = false;
drawFlagPattern = false; drawFlagPattern = false;
swingTrendRayLeft = false;
drawRisingPattern = false; drawRisingPattern = false;
swingTrendRayRight = false;
drawPiercingPattern = false; drawPiercingPattern = false;
drawSignalKeyBarPattern = false; drawSignalKeyBarPattern = false;
drawFIMAPVPivotsAnalysis = false; drawFIMAPVPivotsAnalysis = false;
@@ -510,6 +550,8 @@ struct XFIMAMarketStructureDrawerConfig
drawFlagPattern = true; drawFlagPattern = true;
drawRisingPattern = true; drawRisingPattern = true;
drawPiercingPattern = true; drawPiercingPattern = true;
swingTrendRayLeft = false;
swingTrendRayRight = true;
drawSignalKeyBarPattern = true; drawSignalKeyBarPattern = true;
drawFIMAPVPivotsAnalysis = true; drawFIMAPVPivotsAnalysis = true;
drawFIMAMAPivotsAnalysis = true; drawFIMAMAPivotsAnalysis = true;
@@ -542,6 +584,8 @@ struct XFIMAMarketStructureDrawerConfig
drawStarPattern = true; drawStarPattern = true;
drawFlagPattern = true; drawFlagPattern = true;
drawRisingPattern = true; drawRisingPattern = true;
swingTrendRayLeft = true;
swingTrendRayRight = true;
drawPiercingPattern = true; drawPiercingPattern = true;
drawSignalKeyBarPattern = true; drawSignalKeyBarPattern = true;
drawFIMAPVPivotsAnalysis = true; drawFIMAPVPivotsAnalysis = true;