From 430d822d3e09c01879f27d2e4f537315df10305a Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 9 Oct 2025 02:06:30 +0330 Subject: [PATCH] last works on XFIMA ... --- Classes/x-saherelm.x-cobject.class.mq5 | 1140 +---- Classes/x-saherelm.x-poi.drawer.class.mq5 | 1352 +++++- .../BKP/x-saherelm.x-cobject.class copy.mq5 | 3787 +++++++++++++++++ .../x-saherelm.xfima.x-poi.drawer.class.mq5 | 174 + Documents/BKP/xfima-zone-detector.bkp.mq5 | 1219 ++++++ Helpers/x-saherelm.xfima.helper.mq5 | 2316 ++++------ Libraries/x-saherelm.x-pivot.analysis.lib.mq5 | 163 +- Libraries/x-saherelm.x-poi.lib.mq5 | 88 +- .../x-saherelm.xfima.signaller.class.mq5 | 1170 +---- .../x-saherelm.xfima.x-poi.detector.class.mq5 | 4 +- XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 | 98 +- compile.cmd | 4 +- 12 files changed, 7605 insertions(+), 3910 deletions(-) create mode 100644 Documents/BKP/x-saherelm.x-cobject.class copy.mq5 create mode 100644 Documents/BKP/xfima-zone-detector.bkp.mq5 diff --git a/Classes/x-saherelm.x-cobject.class.mq5 b/Classes/x-saherelm.x-cobject.class.mq5 index e2e7bc1b..df976315 100644 --- a/Classes/x-saherelm.x-cobject.class.mq5 +++ b/Classes/x-saherelm.x-cobject.class.mq5 @@ -45,8 +45,7 @@ enum ENUM_XCHARTOBJECTS X_SIGNAL_OBJ = 8860, // XSignal X_OHCL_OBJ = 8863, // XBar X_RR_OBJ = 8864, // XRR - X_PIVOT_OBJ = 8865, // XPivot - X_POSITION_OBJ = 8866, // XPosition + X_POSITION_OBJ = 8865, // XPosition // // 9860 Custom Object ... }; @@ -2532,855 +2531,6 @@ class XCPositionObject : public XCBaseObject // }; -/** - * XPivotAnalysis Chart Object ... - **/ -class XCPivotAnalysisObject : public XCBaseObject -{ - // - public: - // - - /** - * Create Object ... - * - * @param chart_id: Long, Specified Chart ID ... - * @param window: Integer, Specified Chart Window ID ... - * @param model: XPivotAnalysis, reference model ... - * @param drawTrends: Specified to Draw Trends or not ... - * @param drawZones: Specified to Draw Support and Resistance Zones or not ... - * @param drawPivots: Specified to Draw Pivots or not ... - * @param peakArrow: int, Specified Arrow Code for Peak Pivots ... - * @param valeArrow: int, Specified Arrow Code for Vale Pivots ... - * @param threshold: int, distance between price and arrow in Point ... - * - * @return ( bool ) - */ - bool Create( - long chart_id, - int window, - XPivotAnalysis &model, - bool drawTrends = true, - bool drawZones = true, - bool drawPivots = true, - int peakArrow = 159, - int valeArrow = 159, - int threshold = 5 // - ) - { - // - bool result = false; - - // - bool has = false; - - // - // Validate ... - result = model.IsValid(); - if (!result) - { - return result; - } - - // - // Generate Object ID ... - string objID = model.GetObjectID(); - - // - // Draw Trend Lines ... - mUpper = NULL; - mLower = NULL; - if (drawTrends) - { - // - string upperName = model.GetUpperObjectID(); - string lowerName = model.GetLowerObjectID(); - - // - RemoveObjects(upperName, chart_id, window); - RemoveObjects(lowerName, chart_id, window); - - // - // Creating Upper ... - mUpper = new CChartObjectTrend(); - result = mUpper.Create( - chart_id, - upperName, - window, - model.fromTime, - model.peakFrom, - model.toTime, - model.peakTo // - ); - if (!result) - { - // - // Destroy Trending Objects ... - DestroyObject(mUpper); - DestroyObject(mLower); - - // - return result; - } - - // - // Create Lower ... - mLower = new CChartObjectTrend(); - result = mLower.Create( - chart_id, - lowerName, - window, - model.fromTime, - model.valeFrom, - model.toTime, - model.valeTo // - ); - if (!result) - { - // - // Destroy Trending Objects ... - DestroyObject(mUpper); - DestroyObject(mLower); - - // - return result; - } - } - - // - // Draw Zones ... - mSupportBox = NULL; - mResistanceBox = NULL; - if (drawZones) - { - // - // Support ... - XBoxZone tmpBox; - has = model.HasSupportBox(tmpBox); - if (has) - { - // - datetime to = TimeCurrent(); - string name = model.GetSupportBoxObjectID(); - RemoveObjects(name, chart_id, window); - mSupportBox = new XCBoxObject(); - result = mSupportBox.Create( - chart_id, - window, - name, - tmpBox.upper, - tmpBox.lower, - tmpBox.from, - to // - ); - if (!result) - { - // - DestroyObject(mUpper); - DestroyObject(mLower); - DestroyObject(mSupportBox); - - // - return result; - } - } - - // - // Resistance ... - tmpBox.Clean(); - has = model.HasResistanceBox(tmpBox); - if (has) - { - // - datetime to = TimeCurrent(); - string name = model.GetResistanceBoxObjectID(); - RemoveObjects(name, chart_id, window); - mResistanceBox = new XCBoxObject(); - result = mResistanceBox.Create( - chart_id, - window, - name, - tmpBox.upper, - tmpBox.lower, - tmpBox.from, - to // - ); - if (!result) - { - // - DestroyObject(mUpper); - DestroyObject(mLower); - DestroyObject(mSupportBox); - DestroyObject(mResistanceBox); - - // - return result; - } - } - } - - // - // Draw Pivots ... - if (drawPivots && - model.HasPivots()) - { - // - XOHCL iBar; - int arrow = 0; - string name = NULL; - XCBarArrowObject *iObj; - ENUM_X_PRICE type = X_PRICE_NONE; - int pivotsCount = ArraySize(model.pivots); - for (int i = 0; i < pivotsCount; i++) - { - // - has = model.pivots[i].GetBar(iBar); - if (!has) - { - continue; - } - - // - arrow = model.pivots[i].IsPeak() - ? peakArrow - : valeArrow; - name = model.pivots[i].GetObjectID(); - RemoveObjects(name, chart_id, window); - type = model.pivots[i].IsPeak() - ? X_PRICE_HIGH - : X_PRICE_LOW; - iObj = new XCBarArrowObject(); - has = iObj.CreateByBar( - chart_id, - name, - window, - arrow, - iBar, - type, - threshold // - ); - if (has) - { - // - if (model.pivots[i].IsPeak()) - { - // - if (mPeaks == NULL) - { - mPeaks = new CArrayObj(); - } - - // - mPeaks.Add(iObj); - } - else - { - // - if (mVales == NULL) - { - mVales = new CArrayObj(); - } - - // - mVales.Add(iObj); - } - } - - // - iBar.Clean(); - ZeroMemory(iObj); - } - - // - // Cleanup Resources ... - iBar.Clean(); - ZeroMemory(iObj); - } - - // - // Setting Object Name ... - if (result) - { - ObjName(objID); - } - - // - return result; - } - - // - // Virtuals ... - - /** - * Retrieve Object Type ... - * - * @return ( ENUM_XCHARTOBJECTS ) - */ - virtual int Type(void) - { - return (int)X_PIVOT_OBJ; - } - - /** - * Type as String ... - **/ - string TypeString() override - { - return ToXString(X_PIVOT_OBJ); - } - - /** - * Destroy ... - */ - void virtual Destroy() - { - // - DestroyObjects(mPeaks); - DestroyObjects(mVales); - - // - DestroyObject(mUpper); - DestroyObject(mLower); - DestroyObject(mSupportBox); - DestroyObject(mResistanceBox); - - // - delete mPeaks; - delete mVales; - delete mUpper; - delete mLower; - delete mSupportBox; - delete mResistanceBox; - - // - ZeroMemory(mPeaks); - ZeroMemory(mVales); - ZeroMemory(mUpper); - ZeroMemory(mLower); - ZeroMemory(mSupportBox); - ZeroMemory(mResistanceBox); - - // - Detach(); - Delete(); - } - - // - // Styling ... - - /** - * Set Width ... - * - * @param value: Integer ... - */ - void UpperWidth(int value) - { - // - if (value < 1) - { - value = 1; - } - - // - if (mUpper == NULL) - { - return; - } - - // - mUpper.Width(value); - } - - /** - * Set Color ... - * - * @param value: Color ... - */ - void UpperColor(color value) - { - // - if (mUpper == NULL) - { - return; - } - - // - mUpper.Color(value); - } - - /** - * Set Style ... - * - * @param value: ENUM_LINE_STYLE member ... - */ - void UpperStyle(ENUM_LINE_STYLE value) - { - // - if (mUpper == NULL) - { - return; - } - - // - mUpper.Style(value); - } - - /** - * Specified Upper Ray to Left or not ... - * - * @param value: bool - */ - void UpperRayLeft(bool value) - { - // - if (mUpper == NULL) - { - return; - } - - // - mUpper.RayLeft(value); - } - - /** - * Specified Upper Ray to Right or not ... - * - * @param value: bool - */ - void UpperRayRight(bool value) - { - // - if (mUpper == NULL) - { - return; - } - - // - mUpper.RayRight(value); - } - - /** - * Set Width ... - * - * @param value: Integer ... - */ - void LowerWidth(int value) - { - // - if (value < 1) - { - value = 1; - } - - // - if (mLower == NULL) - { - return; - } - - // - mLower.Width(value); - } - - /** - * Set Color ... - * - * @param value: Color ... - */ - void LowerColor(color value) - { - // - if (mLower == NULL) - { - return; - } - - // - mLower.Color(value); - } - - /** - * Set Style ... - * - * @param value: ENUM_LINE_STYLE member ... - */ - void LowerStyle(ENUM_LINE_STYLE value) - { - // - if (mLower == NULL) - { - return; - } - - // - mLower.Style(value); - } - - /** - * Specified Lower Ray to Left or not ... - * - * @param value: bool - */ - void LowerRayLeft(bool value) - { - // - if (mLower == NULL) - { - return; - } - - // - mLower.RayLeft(value); - } - - /** - * Specified Lower Ray to Right or not ... - * - * @param value: bool - */ - void LowerRayRight(bool value) - { - // - if (mLower == NULL) - { - return; - } - - // - mLower.RayRight(value); - } - - /** - * Set Width ... - * - * @param value: Integer ... - */ - void SupportWidth(int value) - { - // - if (value < 1) - { - value = 1; - } - - // - if (mSupportBox == NULL) - { - return; - } - - // - mSupportBox.BoxWidth(value); - } - - /** - * Set Color ... - * - * @param value: Color ... - */ - void SupportColor(color value) - { - // - if (mSupportBox == NULL) - { - return; - } - - // - mSupportBox.BoxColor(value); - } - - /** - * Set Style ... - * - * @param value: ENUM_LINE_STYLE member ... - */ - void SupportStyle(ENUM_LINE_STYLE value) - { - // - if (mSupportBox == NULL) - { - return; - } - - // - mSupportBox.BoxStyle(value); - } - - /** - * Set Width ... - * - * @param value: Integer ... - */ - void ResistanceWidth(int value) - { - // - if (value < 1) - { - value = 1; - } - - // - if (mResistanceBox == NULL) - { - return; - } - - // - mResistanceBox.BoxWidth(value); - } - - /** - * Set Color ... - * - * @param value: Color ... - */ - void ResistanceColor(color value) - { - // - if (mResistanceBox == NULL) - { - return; - } - - // - mResistanceBox.BoxColor(value); - } - - /** - * Set Style ... - * - * @param value: ENUM_LINE_STYLE member ... - */ - void ResistanceStyle(ENUM_LINE_STYLE value) - { - // - if (mResistanceBox == NULL) - { - return; - } - - // - mResistanceBox.BoxStyle(value); - } - - /** - * Set Width ... - * - * @param value: Integer ... - */ - void PeaksWidth(int value) - { - // - if (mPeaks == NULL) - { - return; - } - - // - // Normalize ... - value = NormalizeInt(value, 1); - - // - // Validate ... - int count = mPeaks.Total(); - bool has = IsValidSize(count); - if (!has) - { - return; - } - - // - XCBarArrowObject *iPeak; - for (int i = 0; i < count; i++) - { - // - iPeak = (XCBarArrowObject *)mPeaks.At(i); - iPeak.ArrowWidth(value); - ZeroMemory(iPeak); - } - } - - /** - * Set Color ... - * - * @param value: Color ... - */ - void PeaksColor(color value) - { - // - if (mPeaks == NULL) - { - return; - } - - // - // Validate ... - int count = mPeaks.Total(); - bool has = IsValidSize(count); - if (!has) - { - return; - } - - // - XCBarArrowObject *iPeak; - for (int i = 0; i < count; i++) - { - // - iPeak = (XCBarArrowObject *)mPeaks.At(i); - iPeak.ArrowColor(value); - ZeroMemory(iPeak); - } - } - - /** - * Set Arrow Anchor ... - * - * @param value: ENUM_ARROW_ANCHOR member ... - */ - void PeaksAnchor(ENUM_ARROW_ANCHOR value) - { - // - if (mPeaks == NULL) - { - return; - } - - // - // Validate ... - int count = mPeaks.Total(); - bool has = IsValidSize(count); - if (!has) - { - return; - } - - // - XCBarArrowObject *iPeak; - for (int i = 0; i < count; i++) - { - // - iPeak = (XCBarArrowObject *)mPeaks.At(i); - iPeak.ArrowAnchor(value); - ZeroMemory(iPeak); - } - } - - /** - * Set Width ... - * - * @param value: Integer ... - */ - void ValesWidth(int value) - { - // - if (mVales == NULL) - { - return; - } - - // - // Normalize ... - value = NormalizeInt(value, 1); - - // - // Validate ... - int count = mVales.Total(); - bool has = IsValidSize(count); - if (!has) - { - return; - } - - // - XCBarArrowObject *iVale; - for (int i = 0; i < count; i++) - { - // - iVale = (XCBarArrowObject *)mVales.At(i); - iVale.ArrowWidth(value); - ZeroMemory(iVale); - } - } - - /** - * Set Color ... - * - * @param value: Color ... - */ - void ValesColor(color value) - { - // - if (mVales == NULL) - { - return; - } - - // - // Validate ... - int count = mVales.Total(); - bool has = IsValidSize(count); - if (!has) - { - return; - } - - // - XCBarArrowObject *iVale; - for (int i = 0; i < count; i++) - { - // - iVale = (XCBarArrowObject *)mVales.At(i); - iVale.ArrowColor(value); - ZeroMemory(iVale); - } - } - - /** - * Set Arrow Anchor ... - * - * @param value: ENUM_ARROW_ANCHOR member ... - */ - void ValesAnchor(ENUM_ARROW_ANCHOR value) - { - // - if (mVales == NULL) - { - return; - } - - // - // Validate ... - int count = mVales.Total(); - bool has = IsValidSize(count); - if (!has) - { - return; - } - - // - XCBarArrowObject *iVale; - for (int i = 0; i < count; i++) - { - // - iVale = (XCBarArrowObject *)mVales.At(i); - iVale.ArrowAnchor(value); - ZeroMemory(iVale); - } - } - - // - private: - // - CArrayObj *mPeaks; - CArrayObj *mVales; - CChartObjectTrend *mUpper; - CChartObjectTrend *mLower; - XCBoxObject *mSupportBox; - XCBoxObject *mResistanceBox; -}; - // // Extensions ... @@ -3410,293 +2560,6 @@ void AddObjects( } } -/** - * Destroy Object if Exists ... - * - * @param object: pointer refrence to Destroy ... - */ -void DestroyObject(XCBoxObject *&object) -{ - // - // Validate ... - bool has = object != NULL; - if (!has) - { - return; - } - - // - object.Destroy(); - - // - object.Detach(); - object.Delete(); - - // - delete object; - ZeroMemory(object); -} - -/** - * Destroy Object if Exists ... - * - * @param object: pointer refrence to Destroy ... - */ -void DestroyObject(XCPivotAnalysisObject *&object) -{ - // - // Validate ... - bool has = object != NULL; - if (!has) - { - return; - } - - // - object.Destroy(); - - // - object.Detach(); - object.Delete(); - - // - delete object; - ZeroMemory(object); -} - -/** - * Destroy Object if Exists ... - * - * @param object: pointer refrence to Destroy ... - */ -void DestroyObject(CChartObjectTrend *&object) -{ - // - // Validate ... - bool has = object != NULL; - if (!has) - { - return; - } - - // - object.Detach(); - object.Delete(); - - // - delete object; - ZeroMemory(object); -} - -/** - * Completely Destroy all Chart Objects ... - * - * @param objects: CArrayObj, pointer refrence Specified Data Source ... - */ -void DestroyObjects(CArrayObj *&objects) -{ - // - // Validate Exists ... - if (objects == NULL) - { - return; - } - - // - // Count Childs ... - int count = objects.Total(); - if (!IsValidSize(count)) - { - return; - } - - // - // Destroy all Childs ... - for (int i = 0; i < count; i++) - { - // - // Checking Types ... - int iType = ((CChartObject *)objects.At(i)).Type(); - - // - string iTypeStr = NULL; - if (iType == X_EMPTY_OBJ) - { - // - XCBaseObject *iObj = (XCBaseObject *)objects.At(i); - iTypeStr = iObj.TypeString(); - - // - if (iTypeStr == ToXString(X_BOX_OBJ)) - { - iType = X_BOX_OBJ; - } - else if (iTypeStr == ToXString(X_BAR_ARROW_OBJ)) - { - iType = X_BAR_ARROW_OBJ; - } - else if (iTypeStr == ToXString(X_SIGNAL_OBJ)) - { - iType = X_SIGNAL_OBJ; - } - else if (iTypeStr == ToXString(X_OHCL_OBJ)) - { - iType = X_OHCL_OBJ; - } - else if (iTypeStr == ToXString(X_RR_OBJ)) - { - iType = X_RR_OBJ; - } - else if (iTypeStr == ToXString(X_PIVOT_OBJ)) - { - iType = X_PIVOT_OBJ; - } - } - - // - string iName = ((CChartObject *)objects.At(i)).Name(); - if (!IsSpecifiedValid(iName)) - { - iName = ((XCBaseObject *)objects.At(i)).ObjName(); - } - - // - switch (iType) - { - // - case X_RR_OBJ: { - // - XCRRObject *iObj = (XCRRObject *)objects.At(i); - iObj.Destroy(); - - // - delete iObj; - ZeroMemory(iObj); - } - break; - case X_BOX_OBJ: { - // - XCBoxObject *iObj = (XCBoxObject *)objects.At(i); - iObj.Destroy(); - iObj.Detach(); - iObj.Delete(); - - // - delete iObj; - ZeroMemory(iObj); - } - break; - case X_OHCL_OBJ: { - // - XCOHCLObject *iObj = (XCOHCLObject *)objects.At(i); - iObj.Destroy(); - - // - delete iObj; - ZeroMemory(iObj); - } - break; - case X_PIVOT_OBJ: { - // - XCPivotAnalysisObject *iObj = (XCPivotAnalysisObject *)objects.At(i); - iObj.Destroy(); - - // - delete iObj; - ZeroMemory(iObj); - } - break; - case X_SIGNAL_OBJ: { - // - XCSignalObject *iObj = (XCSignalObject *)objects.At(i); - iObj.Destroy(); - - // - delete iObj; - ZeroMemory(iObj); - } - break; - case X_BAR_ARROW_OBJ: { - // - XCBarArrowObject *iObj = (XCBarArrowObject *)objects.At(i); - iObj.Destroy(); - - // - delete iObj; - ZeroMemory(iObj); - } - break; - // - // Default Object Types ... - case OBJ_VLINE: - case OBJ_HLINE: - case OBJ_TREND: - case OBJ_TRENDBYANGLE: - case OBJ_CYCLES: - case OBJ_ARROWED_LINE: - case OBJ_CHANNEL: - case OBJ_STDDEVCHANNEL: - case OBJ_REGRESSION: - case OBJ_PITCHFORK: - case OBJ_GANNLINE: - case OBJ_GANNFAN: - case OBJ_GANNGRID: - case OBJ_FIBO: - case OBJ_FIBOTIMES: - case OBJ_FIBOFAN: - case OBJ_FIBOARC: - case OBJ_FIBOCHANNEL: - case OBJ_EXPANSION: - case OBJ_ELLIOTWAVE5: - case OBJ_ELLIOTWAVE3: - case OBJ_RECTANGLE: - case OBJ_TRIANGLE: - case OBJ_ELLIPSE: - case OBJ_ARROW_THUMB_UP: - case OBJ_ARROW_THUMB_DOWN: - case OBJ_ARROW_UP: - case OBJ_ARROW_DOWN: - case OBJ_ARROW_STOP: - case OBJ_ARROW_CHECK: - case OBJ_ARROW_LEFT_PRICE: - case OBJ_ARROW_RIGHT_PRICE: - case OBJ_ARROW_BUY: - case OBJ_ARROW_SELL: - case OBJ_ARROW: - case OBJ_TEXT: - case OBJ_LABEL: - case OBJ_BUTTON: - case OBJ_CHART: - case OBJ_BITMAP: - case OBJ_BITMAP_LABEL: - case OBJ_EDIT: - case OBJ_EVENT: - case OBJ_RECTANGLE_LABEL: { - // - CChartObject *iObj = (CChartObject *)objects.At(i); - - // - iObj.Detach(); - iObj.Delete(); - - // - delete iObj; - ZeroMemory(iObj); - } - break; - } - - // - RemoveObjects(iName); - } - - // - // Destroy itSelf ... - objects.Clear(); - delete objects; - ZeroMemory(objects); -} - /** * Remove Drawn Objects from Chart ... * @@ -3784,4 +2647,5 @@ color ApplyAlpha( // return result; } + // \ No newline at end of file diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index a3802e88..6524537b 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -46,6 +46,9 @@ class XCPOIDrawer : public XCBase XPOIStyle boxBullishStyle; XPOIStyle boxBearishStyle; + // + CArrayObj drawnObjects; + // // Constructor ... void XCPOIDrawer() @@ -659,12 +662,13 @@ class XCPOIDrawer : public XCBase // bool has = false; XCBoxObject *iObj; - string name = NULL; + string name = NULL; int count = ArraySize(boxes); for (int i = 0; i < count; i++) { // - if (useTypeName) { + if (useTypeName) + { name = boxes[i].type; } @@ -942,76 +946,6 @@ class XCPOIDrawer : public XCBase return result; } - /** - * Draw Pivot Analysis ... - * - * @param analysis: XPivotAnalysis, referece Specified Pivot Analysis ... - * @param object: XCPivotAnalysisObject, pointer reference for Drawn Object ... - * @param drawTrends: Specified to Draw Trends or not ... - * @param drawZones: Specified to Draw Support and Resistance Zones or not ... - * @param drawPivots: Specified to Draw Pivots or not ... - * @param peakArrow: int, Specified Arrow Code for Peak Pivots ... - * @param valeArrow: int, Specified Arrow Code for Vale Pivots ... - * @param threshold: int, distance between price and arrow in Point ... - * - * @return ( bool ) - */ - bool DrawPivotAnalysis( - XPivotAnalysis &analysis, - XCPivotAnalysisObject *&object, - bool drawTrends = true, - bool drawZones = true, - bool drawPivots = true, - int peakArrow = 159, - int valeArrow = 159, - int threshold = 5 // - ) - { - // - bool result = false; - - // - // Prepare ... - object = NULL; - - // - // Normalize ... - - // - // Validate ... - result = analysis.IsValid() && - analysis.IsAnalysed(); - if (!result) - { - return result; - } - - // - object = new XCPivotAnalysisObject(); - result = object.Create( - ChartIdentification(), - SubWindowIdentification(), - analysis, - drawTrends, - drawZones, - drawPivots, - peakArrow, - valeArrow, - threshold // - ); - if (result) - { - // - ApplyPivotAnalysisStyle( - object, - analysis // - ); - } - - // - return result; - } - // // Stylers ... @@ -1362,111 +1296,1257 @@ class XCPOIDrawer : public XCBase style.Clean(); } + + // + // SPecial Draws Functions ... + /** - * Apply Specified Style to Specified Object ... + * Draw Specified Pattern Pivot ... * - * @param object: CChartObject, pointer reference of Object ... - * @param model: XPivotAnalysis, referece to access requirements ... + * @param _pivot: XPivot, reference to Specified Pivot ... + * @param config: XPOIDrawConfig, Darwing Configuration ... + * @param thresholdMultiplier: int, pivot point threshold ... */ - void ApplyPivotAnalysisStyle( - XCPivotAnalysisObject *&object, - XPivotAnalysis &model // + void DrawPivot( + XPivot &_pivot, + XPOIDrawConfig &config, + int thresholdMultiplier = 0 // ) { + // + // Normalize ... + thresholdMultiplier = NormalizeInt(thresholdMultiplier, 1); + + // + int arrowThreshold = config.arrowsThreshold * thresholdMultiplier; + arrowThreshold = NormalizeInt(arrowThreshold, 1); + // // Validate ... - bool has = model.IsValid() && - model.IsAnalysed() && - object != NULL; + bool has = _pivot.IsValid(); if (!has) { return; } // - XPOIStyle style; + XOHCL _bar; + has = _pivot.GetBar(_bar); + if (!has) + { + // + _bar.Clean(); + return; + } + + // + XCBarArrowObject *iObj; + has = DrawBarArrow( + _bar, + iObj, + _pivot.IsPeak() + ? config.arrowsPeakPriceType + : config.arrowsValePriceType, + _pivot.IsBullish() + ? config.bullishArrow + : config.bearishArrow, + _pivot.IsBullish() + ? config.bullishColor + : config.bearishColor, + config.arrowsWidth, + _pivot.IsBullish() + ? ANCHOR_TOP + : ANCHOR_BOTTOM, + _pivot.prefix + "_Pivot_" + ToXString(TimeToSeconds(_pivot.time)), + true, // Ignore Bar Tag ... + arrowThreshold // Threshold ... + ); + if (has) + { + drawnObjects.Add(iObj); + } + + // + ZeroMemory(iObj); + } + + /** + * Draw Specified Pattern Zone ... + * + * @param _zone: XBozxZone, reference to Specified Zone ... + * @param config: XPOIDrawConfig, Darwing Configuration ... + */ + void DrawZone( + XBoxZone &_zone, + XPOIDrawConfig &config // + ) + { + // + // Validate ... + bool has = _zone.IsValid(); + if (!has) + { + return; + } + + // + XCBoxObject *iObj; + has = DrawBox( + _zone, + iObj, + config.ignoreZonesAt, + _zone.type + "_Zone_" + ToXString(TimeToSeconds(_zone.from)) // + ); + if (has) + { + // + XPOIStyle iStyle; + GetBoxStyle( + iStyle, + _zone.dir // + ); + + // + iStyle.clr = + _zone.IsBullish() + ? config.bullishColor + : config.bearishColor; + iStyle.width = config.zonesWidth; + iStyle.style = config.zonesStyle; + + // + ApplyBoxStyle( + iObj, + iStyle // + ); + + // + drawnObjects.Add(iObj); + + // + iStyle.Clean(); + } + + // + ZeroMemory(iObj); + } + + /** + * Draw Specified Pattern info ... + * + * @param _bar: XOHCL, reference to Pattern's Bar ... + * @param _pivot: XPivot, reference to Pattern's Pivot ... + * @param _zone: XBoxZone, reference to Pattern's Zone ... + * @param _pattern: ENUM_X_BAR_PATTERN, Specified Bar Pattern ... + * @param _patternDir: ENUM_X_DIRECTION, Specified Bar Pattern's Direction ... + * @param thresholdMultiplier: int, pivot point threshold ... + * @param config: XPOIDrawConfig, Darwing Configuration ... + */ + void DrawPattern( + XOHCL &_bar, + XPivot &_pivot, + XBoxZone &_zone, + ENUM_X_BAR_PATTERN _pattern, + ENUM_X_DIRECTION _patternDir, + XPOIDrawConfig &config, + int thresholdMultiplier = 0 // + ) + { + // + // Validate ... + bool has = + _bar.IsValid() && + IsXValid(_pattern) && + HasDirection(_patternDir); + if (!has) + { + return; + } + + // + // Handle Draws ... + + // + // Draw OHCL Bar ... + + // + // Draw Pivot ... + DrawPivot(_pivot, config, thresholdMultiplier); + + // + // Draw Zone ... + DrawZone(_zone, config); + } + + /** + * Draw Specified Bar Pattern Analysis ... + * + * @param analysis: XPatternAnalysis, reference to Specified Bar Pattern Analysis ... + * @param config: XPatternAnalysisDrawConfig, reference to Provide Drawing Configuration ... + */ + void DrawPatternAnalysis( + XPatternAnalysis &analysis, + XPatternAnalysisDrawConfig &config // + ) + { + // + bool has = analysis.IsValid(); + if (!has) + { + return; + } + + // + bool canDraw; + bool isBullish; + bool isBearish; + XOHCL patternBar; + bool canDrawZone; + bool canDrawPivot; + XPivot patternPivot; + XBoxZone patternBox; + ENUM_X_BAR_PATTERN pattern; + ENUM_X_DIRECTION patternDir; + + // + int patternsPivotThresholdMultiplier = 0; + + // + // Support and Resistance ... // // Support ... - style = defaultBullishStyle; - object.SupportColor(style.clr); - object.SupportWidth(style.width); - object.SupportStyle(style.style); + isBearish = false; + isBullish = analysis.IsSupport(); + has = isBullish; + if (has) + { + // + pattern = X_BAR_PATTERN_SUPPORT; + patternDir = X_DIRECTION_BULLISH; + canDraw = config.CanDraw(pattern); + if (canDraw) + { + // + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } + + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } + } // // Resistance ... - style = defaultBearishStyle; - object.ResistanceColor(style.clr); - object.ResistanceWidth(style.width); - object.ResistanceStyle(style.style); - - // - // Upper ... - if (model.IsPeakAnalysed()) + isBullish = false; + isBearish = analysis.IsResistance(); + has = isBearish; + if (has) { // - GetStyle( - style, - model.peakDir // - ); - if (!HasDirection(model.peakDir)) + pattern = X_BAR_PATTERN_RESISTANCE; + patternDir = X_DIRECTION_BEARISH; + canDraw = config.CanDraw(pattern); + if (canDraw) { // - style.Default(); - style.clr = clrGray; - } + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } - // - object.UpperColor(style.clr); - object.UpperWidth(style.width); - object.UpperStyle(style.style); - object.UpperRayLeft(false); - object.UpperRayRight(true); + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } } // - // Lower ... - if (model.IsValeAnalysed()) + // PV: High and Low ... + + // + // Low ... + isBearish = false; + isBullish = analysis.IsLow(); + has = isBullish; + if (has) { // - GetStyle( - style, - model.valeDir // - ); - if (!HasDirection(model.valeDir)) + pattern = X_BAR_PATTERN_LOW; + patternDir = X_DIRECTION_BULLISH; + canDraw = config.CanDraw(pattern); + if (canDraw) { // - style.Default(); - style.clr = clrGray; - } + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } - // - object.LowerColor(style.clr); - object.LowerWidth(style.width); - object.LowerStyle(style.style); - object.UpperRayLeft(false); - object.LowerRayRight(true); + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } } // - // Peak Pivots ... - style = defaultBearishStyle; - object.PeaksColor(style.clr); - object.PeaksWidth(style.width); - object.PeaksAnchor(ANCHOR_BOTTOM); + // High ... + isBullish = false; + isBearish = analysis.IsHigh(); + has = isBearish; + if (has) + { + // + pattern = X_BAR_PATTERN_HIGH; + patternDir = X_DIRECTION_BEARISH; + canDraw = config.CanDraw(pattern); + if (canDraw) + { + // + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } + + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } + } // - // Vale Pivots ... - style = defaultBullishStyle; - object.ValesColor(style.clr); - object.ValesWidth(style.width); - object.ValesAnchor(ANCHOR_TOP); + // OB ... + isBullish = analysis.IsOB(X_DIRECTION_BULLISH); + isBearish = analysis.IsOB(X_DIRECTION_BEARISH); + has = isBullish || isBearish; + if (has) + { + // + pattern = X_BAR_PATTERN_OB; + patternDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + canDraw = config.CanDraw(pattern); + if (canDraw) + { + // + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } + + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } + } + + // + // FVG ... + isBullish = analysis.IsFVG(X_DIRECTION_BULLISH); + isBearish = analysis.IsFVG(X_DIRECTION_BEARISH); + has = isBullish || isBearish; + if (has) + { + // + pattern = X_BAR_PATTERN_FVG; + patternDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + canDraw = config.CanDraw(pattern); + if (canDraw) + { + // + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } + + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } + } + + // + // Momentum ... + isBullish = analysis.IsMomentum(X_DIRECTION_BULLISH); + isBearish = analysis.IsMomentum(X_DIRECTION_BEARISH); + has = isBullish || isBearish; + if (has) + { + // + pattern = X_BAR_PATTERN_MOMENTUM; + patternDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + canDraw = config.CanDraw(pattern); + if (canDraw) + { + // + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } + + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } + } + + // + // Engulfed ... + isBullish = analysis.IsEngulfed(X_DIRECTION_BULLISH); + isBearish = analysis.IsEngulfed(X_DIRECTION_BEARISH); + has = isBullish || isBearish; + if (has) + { + // + pattern = X_BAR_PATTERN_ENGULFED; + patternDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + canDraw = config.CanDraw(pattern); + if (canDraw) + { + // + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } + + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } + } + + // + // Pinned ... + isBullish = analysis.IsPinned(X_DIRECTION_BULLISH); + isBearish = analysis.IsPinned(X_DIRECTION_BEARISH); + has = isBullish || isBearish; + if (has) + { + // + pattern = X_BAR_PATTERN_PINNED; + patternDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + canDraw = config.CanDraw(pattern); + if (canDraw) + { + // + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } + + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } + } + + // + // TrueGaped ... + isBullish = analysis.IsTrueGaped(X_DIRECTION_BULLISH); + isBearish = analysis.IsTrueGaped(X_DIRECTION_BEARISH); + has = isBullish || isBearish; + if (has) + { + // + pattern = X_BAR_PATTERN_TRUE_GAPED; + patternDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + canDraw = config.CanDraw(pattern); + if (canDraw) + { + // + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } + + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } + } + + // + // Star ... + isBullish = analysis.IsStar(X_DIRECTION_BULLISH); + isBearish = analysis.IsStar(X_DIRECTION_BEARISH); + has = isBullish || isBearish; + if (has) + { + // + pattern = X_BAR_PATTERN_STAR; + patternDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + canDraw = config.CanDraw(pattern); + if (canDraw) + { + // + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } + + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } + } + + // + // Piercing ... + isBullish = analysis.IsPiercing(X_DIRECTION_BULLISH); + isBearish = analysis.IsPiercing(X_DIRECTION_BEARISH); + has = isBullish || isBearish; + if (has) + { + // + pattern = X_BAR_PATTERN_PIERCING; + patternDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + canDraw = config.CanDraw(pattern); + if (canDraw) + { + // + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } + + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } + } + + // + // Rising ... + isBullish = analysis.IsRising(X_DIRECTION_BULLISH); + isBearish = analysis.IsRising(X_DIRECTION_BEARISH); + has = isBullish || isBearish; + if (has) + { + // + pattern = X_BAR_PATTERN_RISING; + patternDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + canDraw = config.CanDraw(pattern); + if (canDraw) + { + // + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } + + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } + } + + // + // Flag ... + isBullish = analysis.IsFlag(X_DIRECTION_BULLISH); + isBearish = analysis.IsFlag(X_DIRECTION_BEARISH); + has = isBullish || isBearish; + if (has) + { + // + pattern = X_BAR_PATTERN_FLAG; + patternDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + canDraw = config.CanDraw(pattern); + if (canDraw) + { + // + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } + + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } + } + + // + // SignalKey ... + isBullish = analysis.IsSignalKey(X_DIRECTION_BULLISH); + isBearish = analysis.IsSignalKey(X_DIRECTION_BEARISH); + has = isBullish || isBearish; + if (has) + { + // + pattern = X_BAR_PATTERN_SIGNALKEY; + patternDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + canDraw = config.CanDraw(pattern); + if (canDraw) + { + // + has = analysis.GetPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir // + ); + if (has) + { + // + canDrawZone = config.CanDrawZone(pattern); + if (!canDrawZone) + { + patternBox.Clean(); + } + + // + canDrawPivot = config.CanDrawPivot(pattern); + if (!canDrawPivot) + { + patternPivot.Clean(); + } + else + { + patternsPivotThresholdMultiplier++; + } + + // + DrawPattern( + patternBar, + patternPivot, + patternBox, + pattern, + patternDir, + config.drawConfig, + patternsPivotThresholdMultiplier // + ); + } + } + } + + // + // Cleanup Resources ... + patternBar.Clean(); + patternBox.Clean(); + patternPivot.Clean(); + } + + /** + * Draw Specified Pivots Analysis ... + * + * @param analysis: XPivotAnalysis, reference to Specified Pivot Analysis ... + * @param config: XPivotAnalysisDrawConfig, reference to Provide Drawing Configuration ... + */ + void DrawPivotAnalysis( + XPivotAnalysis &analysis, + XPivotAnalysisDrawConfig &config // + ) + { + // + bool has = analysis.IsValid(); + if (!has) + { + return; + } + + // + int count = 0; + XBoxZone tmpBox; + datetime cTime = TimeCurrent(); + + // + // Pivots ... + if (config.drawPivots) + { + // + has = analysis.HasPivots(); + if (has) + { + // + count = ArraySize(analysis.pivots); + for (int i = 0; i < count; i++) + { + // + DrawPivot( + analysis.pivots[i], + config.drawConfig // + ); + } + } + } + + // + // Support ... + if (config.drawSupport) + { + // + tmpBox.Clean(); + has = analysis.HasSupportBox(tmpBox); + if (has) + { + // + tmpBox.to = cTime; + DrawZone( + tmpBox, + config.drawConfig // + ); + } + } + + // + // Resistance ... + if (config.drawResistance) + { + // + tmpBox.Clean(); + has = analysis.HasResistanceBox(tmpBox); + if (has) + { + // + tmpBox.to = cTime; + DrawZone( + tmpBox, + config.drawConfig // + ); + } + } + + // + // Peak Trend ... + if (config.drawPeakTrend) + { + // + has = analysis.IsPeakAnalysed(); + if (has) + { + // + string iUpperName = analysis.GetUpperObjectID(); + CChartObjectTrend *iObj = new CChartObjectTrend(); + has = iObj.Create( + ChartIdentification(), + iUpperName, + SubWindowIdentification(), + analysis.fromTime, + analysis.peakFrom, + analysis.toTime, + analysis.peakTo // + ); + if (has) + { + // + // Styling ... + iObj.RayLeft(config.rayLeftTrends); + iObj.RayRight(config.rayRightTrends); + iObj.Width(config.drawConfig.zonesWidth); + iObj.Style(config.drawConfig.zonesStyle); + iObj.Color(IsXBullish(analysis.peakDir) + ? config.drawConfig.bullishColor + : config.drawConfig.bearishColor); + + // + // Storing ... + drawnObjects.Add(iObj); + } + } + } + + // + // Vale Trend ... + if (config.drawValeTrend) + { + // + has = analysis.IsValeAnalysed(); + if (has) + { + // + string iLowerName = analysis.GetLowerObjectID(); + CChartObjectTrend *iObj = new CChartObjectTrend(); + has = iObj.Create( + ChartIdentification(), + iLowerName, + SubWindowIdentification(), + analysis.fromTime, + analysis.valeFrom, + analysis.toTime, + analysis.valeTo // + ); + if (has) + { + // + // Styling ... + iObj.RayLeft(config.rayLeftTrends); + iObj.RayRight(config.rayRightTrends); + iObj.Width(config.drawConfig.zonesWidth); + iObj.Style(config.drawConfig.zonesStyle); + iObj.Color(IsXBullish(analysis.valeDir) + ? config.drawConfig.bullishColor + : config.drawConfig.bearishColor); + + // + // Storing ... + drawnObjects.Add(iObj); + } + } + } + + // + // Cleanup ... + tmpBox.Clean(); // - style.Clean(); } - // protected: // diff --git a/Documents/BKP/x-saherelm.x-cobject.class copy.mq5 b/Documents/BKP/x-saherelm.x-cobject.class copy.mq5 new file mode 100644 index 00000000..e2e7bc1b --- /dev/null +++ b/Documents/BKP/x-saherelm.x-cobject.class copy.mq5 @@ -0,0 +1,3787 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XChartObjects +// Description: provides all require Chart Objects ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.x-pivot.analysis.lib.mq5" +#include "../Libraries/x-saherelm.x-poi.lib.mq5" +#include "../Libraries/x-saherelm.x-trade.lib.mq5" + +// +#include +#include +#include +#include +#include +#include + +// +// Definitions ... + +enum ENUM_XCHARTOBJECTS +{ + // + // Global ... + X_EMPTY_OBJ = 7860, // Empty + X_BOX_OBJ = 7861, // XBox + X_BAR_ARROW_OBJ = 7862, // XBarArrow + X_SIGNAL_OBJ = 8860, // XSignal + X_OHCL_OBJ = 8863, // XBar + X_RR_OBJ = 8864, // XRR + X_PIVOT_OBJ = 8865, // XPivot + X_POSITION_OBJ = 8866, // XPosition + // + // 9860 Custom Object ... +}; + +enum ENUM_X_CHART_IDS +{ + X_AT, // AT + X_TO, // TO + X_FROM, // FROM + X_UPPER, // UPPER + X_LOWER, // LOWER + X_ENTRY, // ENTRY + X_TARGET, // TARGET + X_SL, // SL + X_TP, // TP + X_BAR_H_SHW, // HSHW + X_BAR_BDY, // BODY + X_BAR_L_SHW, // LSHW +}; + +string ToString(ENUM_X_CHART_IDS value) +{ + // + string result = NULL; + + // + result = EnumToString(value); + + // + return result; +} + +string ToXString(ENUM_XCHARTOBJECTS value) +{ + // + return EnumToString(value); +} + +struct XPOIStyle +{ + // + // Properties ... + int width; // Width ... + color clr; // Color ... + bool fill; // Fill, Use in Rectangles ... + ENUM_LINE_STYLE style; // Line Style ... + + // + // Constructor ... + XPOIStyle() + { + Default(); + } + + // + // Tools ... + + // + // Cleanup Model ... + void Clean() + { + // + width = 1; + fill = false; + clr = CLR_NONE; + style = STYLE_SOLID; + + // + ZeroMemory(this); + } + + // + // Default Props ... + void Default() + { + // + width = 1; + fill = false; + clr = CLR_NONE; + style = STYLE_SOLID; + } +}; + +// +// Extensions ... + +/** + * Converts a XBoxZone struct to XSignal instance ... + * + * @param box: XBoxZone instance reference, provide source info ... + * @param signal: XSignal instance reference, holds prepared converted signal ... + * + * @return ( bool ) + */ +bool ToXSignal( + XBoxZone &box, + XSignal &signal, + double &rewardRatios[], + double additionalSL = 0 // +) +{ + // + bool result = false; + + // + signal.Clean(); + + // + result = box.IsValid() && + HasChild(rewardRatios); + if (!result) + { + return result; + } + + // + XOHCL entryBar; + int entryIDX = box.ToIndex(); + if (entryIDX > 0) + { + entryIDX--; + } + result = entryBar.Init( + box.symbol, + box.period, + entryIDX // + ); + if (!result) + { + // + entryBar.Clean(); + + // + return result; + } + + // + bool isBullish = box.IsBullish(); + bool isBearish = box.IsBearish(); + + // + ENUM_POSITION_TYPE iType = + isBullish + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + ENUM_X_POSITION_TYPES iXType = + isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + double points = GetPoints(box.symbol); + + // + double entry = + isBullish + ? box.upper + : box.lower; + entry = entryBar.open; + + // + double sl = + isBullish + ? box.lower + : box.upper; + if (additionalSL > 0) + { + // + sl = + isBullish + ? sl - additionalSL + : sl + additionalSL; + } + + // + double risk = MathAbs(entry - sl); + + // + double tp = 0; + + // + // Calculate Target ... + XTarget targets[]; + + // + double tmp[]; + int idx = -1; + XTarget iTarget; + bool has = false; + double iRatio = 0; + double iReward = 0; + double iRewardPrice = 0; + Copy( + rewardRatios, + tmp // + ); + while (HasChild(tmp)) + { + // + idx = -1; + iRatio = GetMaxWidthIndex( + tmp, + idx // + ); + + // + has = IsValidIndex(idx); + if (!has) + { + break; + } + + // + has = iRatio > 0; + + // + ArrayRemove( + tmp, + idx, + 1 // + ); + + // + bool canSetTP = tp <= 0; + + // + iReward = iRatio * risk; + + // + iRewardPrice = + isBullish + ? entry + iReward + : entry - iReward; + if (canSetTP) + { + tp = iRewardPrice; + } + else + { + // + iTarget.target = iRewardPrice; + AddRef( + iTarget, + targets // + ); + + // + iTarget.Clean(); + } + } + Clean(tmp); + + // + // Filling Signal ... + signal.tp = tp; + signal.sl = sl; + signal.type = iType; + signal.comment = ""; + signal.entry = entry; + signal.time = box.to; + signal.volume = 0.01; + signal.provider = box.type; + signal.symbol = box.symbol; + signal.period = box.period; + signal.mode = X_ORDER_MODE_MARKET; + + // + if (HasChild(targets)) + { + // + Copy( + targets, + signal.targets // + ); + } + + // + result = signal.IsValid(); + + // + // Cleanup Resources ... + + // + if (!result) + { + signal.Clean(); + } + + // + Clean(tmp); + Clean(targets); + iTarget.Clean(); + entryBar.Clean(); + + // + return result; +} + +/** + * Converts a Signal to Position ... + * + * @param signal: XSignal, reference to Specified Signal ... + * @param position: XPosition, reference to Generated Position ... + * @param magic: ulong, Specified Magic Number ... + * @param ticket: ulong, Specified Position Ticket ... + * + * @return ( bool ) + */ +bool ToXPosition( + XSignal &signal, + XPosition &position, + ulong magic = 0, + ulong ticket = 0 // +) +{ + // + bool result = false; + + // + // Prepare ... + position.Clean(); + + // + // Validate ... + result = signal.IsValid(); + if (!result) + { + return result; + } + + // + // Normalize ... + + // + if (ticket <= 0) + { + // + if (signal.positionId > 0) + { + ticket = signal.positionId; + } + else + { + // + ticket = MathRand(); + signal.positionId = ticket; + } + } + signal.positionId = ticket; + + // + if (magic <= 0) + { + magic = MathRand(); + } + + // + // Filling Position ... + position.swap = 0; + position.profit = 0; + position.magic = magic; + position.commission = 0; + position.tp = signal.tp; + position.sl = signal.sl; + position.ticket = ticket; + position.type = signal.type; + position.price = signal.entry; + position.entry = signal.entry; + position.openAt = signal.time; + position.volume = signal.volume; + position.symbol = signal.symbol; + position.period = signal.period; + position.comment = signal.comment; + position.provider = signal.provider; + + // + result = position.IsValid(); + + // + // Cleanup Resources ... + if (!result) + { + position.Clean(); + } + + // + return result; +} + +/** + * Update Specified Position by Bar ... + * + * @param position: XPosition, reference to Specified Position ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ +bool XUpdatePosition( + XPosition &position, + int barIndex = 0 // +) +{ + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + + // + // Validate ... + result = position.IsValid(); + if (!result) + { + return result; + } + + // + XOHCL bar; + result = bar.Init( + position.symbol, + position.period, + barIndex // + ); + if (!result) + { + return result; + } + + // + double entryDiff = MathAbs(position.entry - position.price); + bool isLong = IsLong(position.type); + bool isInProfit = isLong + ? position.price > position.entry + : position.price < position.entry; + bool isTargeted = + isLong + ? position.price >= position.tp + : position.price <= position.tp; + bool isStoped = + isLong + ? position.price <= position.sl + : position.price >= position.sl; + result = !isTargeted && !isStoped; + if (!result) + { + return result; + } + + // + double spread = GetSpread(position.symbol); + position.price = bar.close + + (isLong + ? spread + : (-1 * spread)); + entryDiff = MathAbs(position.entry - position.price); + isInProfit = isLong + ? position.price > position.entry + : position.price < position.entry; + result = position.IsValid(); + + // + // Cleanup Resources ... + bar.Clean(); + + // + return result; +} + +// +// Implementation ... + +// +// Global Chart Objects ... + +/** + * Base Chart Object ... + **/ +class XCBaseObject : public CChartObject +{ + // + public: + // + + // + // Getter(s) / Setter(s) ... + + /** + * Get Object Specified Name ... + * + * @return ( string ) + */ + string ObjName() + { + return mObjName; + } + + /** + * Set Object Specified Name ... + * + * @param value: String ... + */ + void ObjName(string value) + { + // + Name(value); + mObjName = value; + } + + virtual string TypeString() + { + return ToXString(X_EMPTY_OBJ); + } + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + virtual int Type(void) const + { + return ((int)X_EMPTY_OBJ); + } + + /** + * Destroy ... + */ + void virtual Destroy() + { + // + Detach(); + Delete(); + } + + // + private: + // + + // + // Props ... + string mObjName; // Object Specified Name ... + + // +}; + +/** + * Bar Arrow Object ... + **/ +class XCBarArrowObject : public XCBaseObject +{ + // + public: + // + + /** + * Creator ... + * + * @param chart_id: Long, Specified Chart ID ... + * @param name: String, Specified Object ID ... + * @param window: Integer, Specified Chart Window ID ... + * @param swing: XCSwing instance ... + * + * @return ( bool ) + */ + bool CreateByBar( + long chart_id, + string name, + int window, + int arrow, + XOHCL &bar, + ENUM_X_PRICE priceType, + double threshold = 5 // + ) + { + // + bool result = false; + + // + result = + // + bar.IsValid() && + IsValid(name) + // + ; + if (!result) + { + return result; + } + + // + datetime time = bar.time; + double price = bar.GetPrice(priceType); + + // + if (threshold > 0) + { + // + double thresholdPrice = threshold * GetPoints(bar.symbol); + if (priceType == X_PRICE_HIGH) + { + price += thresholdPrice; + } + else if (priceType == X_PRICE_LOW) + { + price -= thresholdPrice; + } + } + + // + result = mArrow.Create( + chart_id, + name, + window, + time, + price, + (char)arrow // + ); + + // + if (result) + { + ObjName(name); + } + + // + return result; + } + + // + // Virtual ... + + /** + * Destroy ... + */ + void virtual Destroy() + { + // + mArrow.Detach(); + mArrow.Delete(); + + // + Detach(); + Delete(); + } + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + virtual int Type(void) + { + return (int)X_BAR_ARROW_OBJ; + } + + /** + * Type as String ... + **/ + string TypeString() override + { + return ToXString(X_BAR_ARROW_OBJ); + } + + // + // Setter(s) ... + + /** + * Set Arrow Anchor ... + * + * @param value: ENUM_ARROW_ANCHOR member ... + */ + void ArrowAnchor(ENUM_ARROW_ANCHOR value) + { + mArrow.Anchor(value); + } + + /** + * Set Arrow Color ... + * + * @param value: Color ... + */ + void ArrowColor(color value) + { + mArrow.Color(value); + } + + /** + * Set Arrow Width ... + * + * @param value: Integer ... + */ + void ArrowWidth(int value) + { + mArrow.Width(value); + } + + // + private: + // + CChartObjectArrow mArrow; + + // +}; + +/** + * Signal Object ... + **/ +class XCSignalObject : public XCBaseObject +{ + // + public: + // + + // + // Constructor ... + void XCSignalObject() + { + } + + // + // Deconstructor ... + void ~XCSignalObject() + { + } + + /** + * Create a Signal Object on Chart ... + * + * @param chart_id: Long ... + * @param name: String ... + * @param window: Integer ... + * @param signal: XSignal instance ... + * @param length: int, Specified Length of Signal ... + * + * @return ( bool ) + */ + bool Create( + long chart_id, + const int window, + XSignal &signal, + int length = 3, + string prefix = NULL // + ) + { + // + bool result = false; + + // + length = NormalizeInt(length, 3); + + // + result = signal.IsValid(); + if (!result) + { + return result; + } + + // + string name = signal.GetTag(); + if (IsValid(prefix)) + { + name = prefix + "_" + name; + } + string nameMD5 = ToMD5(name); + + // + int delay = (PeriodSeconds(signal.period) * length); + datetime time1 = (datetime)((int)signal.time - delay); + datetime time2 = (datetime)((int)signal.time + delay); + + // + // TP ... + string tpName = ToString(X_TP) + "_" + nameMD5; + result = mTPTrend.Create( + chart_id, + tpName, + window, + time1, + signal.tp, + time2, + signal.tp // + ); + if (!result) + { + return result; + } + + // + // SL ... + string slName = ToString(X_SL) + "_" + nameMD5; + result = mSLTrend.Create( + chart_id, + slName, + window, + time1, + signal.sl, + time2, + signal.sl // + ); + if (!result) + { + // + mTPTrend.Delete(); + return result; + } + + // + // TARGET ... + bool hasTargets = HasChild(signal.targets); + if (hasTargets) + { + // + int targetsCount = ArraySize(signal.targets); + for (int i = 0; i < targetsCount; i++) + { + // + string targetName = ToString(X_TARGET) + "_" + ToXString(i) + "_" + nameMD5; + CChartObjectTrend *mTargetTrend; + mTargetTrend = new CChartObjectTrend(); + result = mTargetTrend.Create( + chart_id, + targetName, + window, + time1, + signal.targets[i].target, + time2, + signal.targets[i].target // + ); + if (!result) + { + // + mTPTrend.Delete(); + mSLTrend.Delete(); + break; + } + + // + mTargetTrends.Add(mTargetTrend); + } + } + + // + // ENTRY ... + string entrName = ToString(X_ENTRY) + "_" + nameMD5; + result = mEntryTrend.Create( + chart_id, + entrName, + window, + time1, + signal.entry, + time2, + signal.entry // + ); + if (!result) + { + // + mTPTrend.Delete(); + mSLTrend.Delete(); + mTargetTrends.Clear(); + return result; + } + + // + // Set Object Name ... + ObjName(name); + + // + return result; + } + + // + // Virtual ... + + /** + * Destroy ... + */ + void virtual Destroy() + { + // + mTPTrend.Detach(); + mTPTrend.Delete(); + mSLTrend.Detach(); + mSLTrend.Delete(); + mEntryTrend.Detach(); + mEntryTrend.Delete(); + + // + mTargetTrends.Clear(); + + // + Detach(); + Delete(); + } + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + virtual int Type(void) + { + return (int)X_SIGNAL_OBJ; + } + + /** + * Type as String ... + **/ + string TypeString() override + { + return ToXString(X_SIGNAL_OBJ); + } + + // + // Setter(s) ... + + // + // TP ... + + /** + * Set TP Width ... + * + * @param value: Integer ... + */ + void TPWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mTPTrend.Width(value); + } + + /** + * Set TP Color ... + * + * @param value: Color ... + */ + void TPColor(color value) + { + mTPTrend.Color(value); + } + + /** + * Set TP Style ... + * + * @param value: ENUM_LINE_STYLE ... + */ + void TPStyle(ENUM_LINE_STYLE value) + { + mTPTrend.Style(value); + } + + // + // SL ... + + /** + * Set SL Width ... + * + * @param value: Integer ... + */ + void SLWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mSLTrend.Width(value); + } + + /** + * Set SL Color ... + * + * @param value: Color ... + */ + void SLColor(color value) + { + mSLTrend.Color(value); + } + + /** + * Set SL Style ... + * + * @param value: ENUM_LINE_STYLE ... + */ + void SLStyle(ENUM_LINE_STYLE value) + { + mSLTrend.Style(value); + } + + // + // TARGET ... + + /** + * Set Target Width ... + * + * @param value: Integer ... + */ + void TargetWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + for (int i = 0; i < mTargetTrends.Total(); i++) + { + // + CChartObjectTrend *iTrend = (CChartObjectTrend *)mTargetTrends.At(i); + iTrend.Width(value); + } + } + + /** + * Set Target Color ... + * + * @param value: Color ... + */ + void TargetColor(color value) + { + // + for (int i = 0; i < mTargetTrends.Total(); i++) + { + // + CChartObjectTrend *iTrend = (CChartObjectTrend *)mTargetTrends.At(i); + iTrend.Color(value); + } + } + + /** + * Set Target Style ... + * + * @param value: ENUM_LINE_STYLE ... + */ + void TargetStyle(ENUM_LINE_STYLE value) + { + // + for (int i = 0; i < mTargetTrends.Total(); i++) + { + // + CChartObjectTrend *iTrend = (CChartObjectTrend *)mTargetTrends.At(i); + iTrend.Style(value); + } + } + + // + // ENTRY ... + + /** + * Set Entry Width ... + * + * @param value: Integer ... + */ + void EntryWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mEntryTrend.Width(value); + } + + /** + * Set Entry Color ... + * + * @param value: Color ... + */ + void EntryColor(color value) + { + mEntryTrend.Color(value); + } + + /** + * Set Entry Style ... + * + * @param value: ENUM_LINE_STYLE ... + */ + void EntryStyle(ENUM_LINE_STYLE value) + { + mEntryTrend.Style(value); + } + + // + private: + // + + // + CChartObjectTrend mTPTrend; + CChartObjectTrend mSLTrend; + CChartObjectTrend mEntryTrend; + CArrayObj mTargetTrends; +}; + +/** + * XRR Object ... + **/ +class XCRRObject : public XCSignalObject +{ + // + // Public ... + public: + // + // Constructor ... + bool CreateBoxRR( + long chart_id, + const int window, + XBoxZone &box, + double &rewardRatios[], + int length = 3, + string prefix = NULL // + ) + { + // + bool result = false; + + // + length = NormalizeInt(length, 3); + + // + result = box.IsValid(); + if (!result) + { + return result; + } + + // + XSignal signal; + result = ToXSignal( + box, + signal, + rewardRatios // + ); + if (!result) + { + // + signal.Clean(); + + // + return result; + } + + // + result = Create( + chart_id, + window, + signal, + length, + prefix // + ); + + // + signal.Clean(); + + // + return result; + } + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + virtual int Type(void) + { + return (int)X_RR_OBJ; + } + + /** + * Type as String ... + **/ + string TypeString() override + { + return ToXString(X_RR_OBJ); + } +}; + +/** + * XOHCL Object ... + **/ +class XCOHCLObject : public XCBaseObject +{ + // + public: + // + + /** + * Creator ... + * + * @param chart_id: Long, Specified Chart ID ... + * @param window: Integer, Specified Chart Window ID ... + * @param pivot: XPVPivot instance ... + * @param prefix: String ... + * + * @return ( bool ) + */ + bool Create( + long chart_id, + int window, + XOHCL &bar, + datetime to, + string prefix = NULL // + ) + { + // + bool result = false; + + // + result = bar.IsValid() && + IsValid(to); + if (!result) + { + return result; + } + + // + string name = bar.GetTag(); + if (IsValid(prefix)) + { + name = prefix + "_" + name; + } + string nameMD5 = ToMD5(name); + + // + // High Shadow ... + string hShadowName = ToString(X_BAR_H_SHW) + "_" + nameMD5; + + // + result = mHighShadowRect.Create( + chart_id, + hShadowName, + window, + bar.time, + bar.high, + to, + bar.GetUp() // + ); + if (!result) + { + return result; + } + + // + // Body ... + string bodyName = ToString(X_BAR_BDY) + "_" + nameMD5; + + // + result = mBodyRect.Create( + chart_id, + bodyName, + window, + bar.time, + bar.GetUp(), + to, + bar.GetDown() // + ); + if (!result) + { + // + mHighShadowRect.Delete(); + mHighShadowRect.Detach(); + return result; + } + + // + // Low Shadow ... + string lShadowName = ToString(X_BAR_L_SHW) + "_" + nameMD5; + + // + result = mLowShadowRect.Create( + chart_id, + lShadowName, + window, + bar.time, + bar.GetDown(), + to, + bar.low // + ); + if (!result) + { + // + mBodyRect.Delete(); + mBodyRect.Detach(); + mHighShadowRect.Delete(); + mHighShadowRect.Detach(); + return result; + } + + // + if (result) + { + ObjName(name); + } + + // + return result; + } + + // + // Virtual ... + + /** + * Destroy ... + */ + void virtual Destroy() + { + // + mBodyRect.Detach(); + mBodyRect.Delete(); + + // + mLowShadowRect.Detach(); + mLowShadowRect.Delete(); + + // + mHighShadowRect.Detach(); + mHighShadowRect.Delete(); + + // + Detach(); + Delete(); + } + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + virtual int Type(void) + { + return (int)X_OHCL_OBJ; + } + + /** + * Type as String ... + **/ + string TypeString() override + { + return ToXString(X_OHCL_OBJ); + } + + // + // Getter(s) / Setter(s) ... + + /** + * Set High Shadow Width ... + * + * @param value: Integer ... + */ + void HighShadowWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mHighShadowRect.Width(value); + } + + /** + * Set High Shadow Color ... + * + * @param value: Color ... + */ + void HighShadowColor(color value) + { + mHighShadowRect.Color(value); + } + + /** + * Set High Shadow Style ... + * + * @param value: ENUM_LINE_STYLE member ... + */ + void HighShadowStyle(ENUM_LINE_STYLE value) + { + mHighShadowRect.Style(value); + } + + /** + * Set High Shadow Fill ... + * + * @param value: Boolean ... + */ + void HighShadowFill(bool value) + { + mHighShadowRect.Fill(value); + } + + /** + * Set Body Width ... + * + * @param value: Integer ... + */ + void BodyWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mBodyRect.Width(value); + } + + /** + * Set Body Color ... + * + * @param value: Color ... + */ + void BodyColor(color value) + { + mBodyRect.Color(value); + } + + /** + * Set Body Style ... + * + * @param value: ENUM_LINE_STYLE member ... + */ + void BodyStyle(ENUM_LINE_STYLE value) + { + mBodyRect.Style(value); + } + + /** + * Set Body Fill ... + * + * @param value: Boolean ... + */ + void BodyFill(bool value) + { + mBodyRect.Fill(value); + } + + /** + * Set Low Shadow Width ... + * + * @param value: Integer ... + */ + void LowShadowWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mLowShadowRect.Width(value); + } + + /** + * Set Low Shadow Color ... + * + * @param value: Color ... + */ + void LowShadowColor(color value) + { + mLowShadowRect.Color(value); + } + + /** + * Set Low Shadow Style ... + * + * @param value: ENUM_LINE_STYLE member ... + */ + void LowShadowStyle(ENUM_LINE_STYLE value) + { + mLowShadowRect.Style(value); + } + + /** + * Set Low Shadow Fill ... + * + * @param value: Boolean ... + */ + void LowShadowFill(bool value) + { + mLowShadowRect.Fill(value); + } + + void BarSpes( + int width = 1, + color clr = clrNONE, + ENUM_LINE_STYLE style = STYLE_SOLID, + bool fill = false // + ) + { + // + BodyWidth(width); + LowShadowWidth(width); + HighShadowWidth(width); + + // + BodyColor(clr); + LowShadowColor(clr); + HighShadowColor(clr); + + // + BodyStyle(style); + LowShadowStyle(style); + HighShadowStyle(style); + + // + BodyFill(fill); + LowShadowFill(fill); + HighShadowFill(fill); + } + + // + private: + // + + // + // Props ... + CChartObjectRectangle mHighShadowRect; + CChartObjectRectangle mBodyRect; + CChartObjectRectangle mLowShadowRect; +}; + +/** + * Box Object ... + **/ +class XCBoxObject : public XCBaseObject +{ + // + public: + // + + /** + * Creator ... + * + * @param chart_id: Long, Specified Chart ID ... + * @param window: Integer, Specified Chart Window ID ... + * @param pivot: XPVPivot instance ... + * @param prefix: String ... + * + * @return ( bool ) + */ + bool Create( + long chart_id, + int window, + string name, + double upper, + double lower, + datetime from, + datetime to, + datetime at = NULL, + string prefix = NULL // + ) + { + // + bool result = false; + + // + result = + upper > 0 && + lower > 0 && + to > from && + IsValid(to) && + IsValid(name) && + IsValid(from) && + upper > lower; + if (!result) + { + return result; + } + + // + if (IsValid(prefix)) + { + name = prefix + "_" + name; + } + string nameMD5 = ToMD5(name); + + // + result = mRect.Create( + chart_id, + name, + window, + from, + upper, + to, + lower // + ); + if (!result) + { + return result; + } + + // + if (result) + { + // + if (IsValid(at)) + { + // + result = mAt.Create( + chart_id, + name + ToString(X_AT), + window, + at // + ); + } + + // + if (!result) + { + // + mAt.Detach(); + mAt.Delete(); + + // + mRect.Detach(); + mRect.Delete(); + } + } + + // + if (result) + { + ObjName(name); + } + + // + return result; + } + + // + // Virtual ... + + /** + * Destroy ... + */ + void virtual Destroy() + { + // + mAt.Detach(); + mAt.Delete(); + + // + mRect.Detach(); + mRect.Delete(); + + // + Detach(); + Delete(); + } + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + virtual int Type(void) + { + return (int)X_BOX_OBJ; + } + + /** + * Type as String ... + **/ + string TypeString() override + { + return ToXString(X_BOX_OBJ); + } + + // + // Getter(s) / Setter(s) ... + + /** + * Set Width ... + * + * @param value: Integer ... + */ + void BoxWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mAt.Width(value); + mRect.Width(value); + } + + /** + * Set Color ... + * + * @param value: Color ... + */ + void BoxColor(color value) + { + // + mAt.Color(value); + mRect.Color(value); + } + + /** + * Set Style ... + * + * @param value: ENUM_LINE_STYLE member ... + */ + void BoxStyle(ENUM_LINE_STYLE value) + { + // + mAt.Style(value); + mRect.Style(value); + } + + /** + * Set Fill ... + * + * @param value: Boolean ... + */ + void BoxFill(bool value) + { + mRect.Fill(value); + } + + // + private: + // + + // + // Props ... + CChartObjectVLine mAt; + CChartObjectRectangle mRect; +}; + +/** + * Position Object ... + **/ +class XCPositionObject : public XCBaseObject +{ + // + // Public ... + public: + // + XPOIStyle riskStyle; // Risk Box Style ... + color inProfitColor; // In Profit Price Box Color ... + color inDrawdownColor; // In Drawdown Price Box Color ... + XPOIStyle rewardStyle; // Reward Box Style ... + ENUM_LINE_STYLE priceStyle; // Price Box Style ... + + // + // Creators ... + + /** + * Create a Position Object by Signal reference ... + * + * @param chart_id: Long, Specified Chart ID ... + * @param window: Integer, Specified Chart Window ID ... + * @param signal: XSignal, reference to Provided Signal ... + * @param magic: ulong, Specified Position Magic Number ... + * @param ticket: ulong, Specified Position Ticket ... + * + * @return ( bool ) + */ + bool Create( + long chart_id, + int window, + XSignal &signal, + ulong magic = 0, + ulong ticket = 0 // + ) + { + // + bool result = false; + + // + // Converts Signal to Test Position ... + XPosition _position; + result = ToXPosition( + signal, + _position, + magic, + ticket // + ); + + // + // Validate ... + result = chart_id >= 0 && + window >= 0 && + _position.IsValid(); + if (!result) + { + return result; + } + + // + result = Create( + chart_id, + window, + _position // + ); + + // + return result; + } + + /** + * Create a Position Object ... + * + * @param chart_id: Long, Specified Chart ID ... + * @param window: Integer, Specified Chart Window ID ... + * @param position: XPosition, reference to Specified Position ... + * + * @return ( bool ) + */ + bool Create( + long chart_id, + int window, + XPosition &position // + ) + { + // + bool result = false; + + // + // Validate ... + result = chart_id >= 0 && + window >= 0 && + position.IsValid(); + if (!result) + { + return result; + } + + // + result = Update(position); + if (!result) + { + // + Destroy(); + return result; + } + + // + return result; + } + + /** + * Update Position if Belongs to ... + * + * @param position: XPosition, reference to Specified Position ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool Update( + XPosition &position, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + + // + // Validate ... + result = + mChartID >= 0 && + mWindowID >= 0 && + position.IsValid() && + (!HasPosition() + ? true + : IsBelong(position)); + if (!result) + { + return result; + } + + // + datetime _toTime = GetBarTime( + position.symbol, + position.period, + barIndex // + ); + + // + // Validate Chart Info ... + result = UpdatePosition( + position, + _toTime // + ); + + // + return result; + } + + /** + * Update Position if Belongs to ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool Update(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + + // + // Validate ... + result = HasPosition(); + if (!result) + { + return result; + } + + // + // Update mPosition ... + result = XUpdatePosition(mPosition, barIndex); + if (!result) + { + return result; + } + + // + result = Update( + mPosition, + barIndex // + ); + + // + return result; + } + + // + // Retrievers ... + + bool GetPosition(XPosition &_position) + { + // + bool result = false; + + // + // Prepare ... + _position.Clean(); + + // + // Validate ... + result = HasPosition(); + if (!result) + { + return result; + } + + // + _position = mPosition; + + // + return result; + } + + // + // Checkers ... + + /** + * Check Object is Belongs to Specified Position or not ... + * + * @param position: XPosition, reference to Specified Position ... + * + * @return ( bool ) + */ + bool IsBelong(XPosition &position) + { + // + bool result = false; + + // + // Validate ... + result = + HasPosition() && + position.IsValid(); + + // + // Check ... + result = + result && + mPosition.ticket == position.ticket; + + // + return result; + } + + // + // Overrides ... + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + string TypeString() override + { + return ToXString(X_POSITION_OBJ); + } + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + int Type(void) const override + { + return ((int)X_POSITION_OBJ); + } + + /** + * Destroy Object ... + **/ + void Destroy() override + { + // + ObjName(NULL); + + // + mRiskBox.Clean(); + mPosition.Clean(); + mPriceBox.Clean(); + mRewardBox.Clean(); + + // + mRiskBoxObj.Detach(); + mRiskBoxObj.Delete(); + + // + mPriceBoxObj.Detach(); + mPriceBoxObj.Delete(); + + // + mRewardBoxObj.Detach(); + mRewardBoxObj.Delete(); + } + + // + // Stylers ... + + /** + * Apply Styles based on Current Style Configurations ... + */ + void ApplyStyle() + { + // + // Validate ... + bool has = HasPosition(); + if (!has) + { + return; + } + + // + // Check Position in Profit ... + bool isLong = IsLong(mPosition.type); + bool isRiskFreed = + isLong + ? mPosition.sl > mPosition.entry + : mPosition.sl < mPosition.entry; + bool isInProfit = mPosition.profit > 0; + XPOIStyle _priceStyle; + if (isInProfit) + { + // + _priceStyle = rewardStyle; + _priceStyle.clr = inProfitColor; + } + else + { + // + _priceStyle = riskStyle; + _priceStyle.clr = inDrawdownColor; + } + + // + // Apply Profit Based Styles ... + _priceStyle.fill = true; + _priceStyle.style = priceStyle; + + // + // Change Risk Style if Risk Freed Position ... + if (isRiskFreed) { + // + riskStyle.fill = true; + riskStyle.clr = rewardStyle.clr; + } + + // + // Risk Style ... + mRiskBoxObj.BoxColor(riskStyle.clr); + mRiskBoxObj.BoxFill(riskStyle.fill); + mRiskBoxObj.BoxStyle(riskStyle.style); + mRiskBoxObj.BoxWidth(riskStyle.width); + + // + // Reward Style ... + mRewardBoxObj.BoxColor(rewardStyle.clr); + mRewardBoxObj.BoxFill(rewardStyle.fill); + mRewardBoxObj.BoxStyle(rewardStyle.style); + mRewardBoxObj.BoxWidth(rewardStyle.width); + + // + // Price Style .. + mPriceBoxObj.BoxColor(_priceStyle.clr); + mPriceBoxObj.BoxFill(_priceStyle.fill); + mPriceBoxObj.BoxStyle(_priceStyle.style); + mPriceBoxObj.BoxWidth(_priceStyle.width); + + // + // Cleanup Resources ... + _priceStyle.Clean(); + } + + // + void ApplyStyle( + XPOIStyle &bullishStyle, + XPOIStyle &bearishStyle // + ) + { + // + // Validate ... + if (!HasPosition()) + { + return; + } + + // + // Risk Box ... + if (mRiskBox.IsValid()) + { + // + mRiskBoxObj.BoxColor(bearishStyle.clr); + mRiskBoxObj.BoxFill(bearishStyle.fill); + mRiskBoxObj.BoxStyle(bearishStyle.style); + mRiskBoxObj.BoxWidth(bearishStyle.width); + } + + // + // Reward Box ... + if (mRewardBox.IsValid()) + { + // + mRewardBoxObj.BoxColor(bullishStyle.clr); + mRewardBoxObj.BoxFill(bullishStyle.fill); + mRewardBoxObj.BoxStyle(bullishStyle.style); + mRewardBoxObj.BoxWidth(bullishStyle.width); + } + + // + // Price Box ... + if (mPriceBox.IsValid()) + { + // + XPOIStyle _priceStyle; + if (mPriceBox.IsBullish()) + { + _priceStyle = bullishStyle; + } + else + { + _priceStyle = bearishStyle; + } + + // + mPriceBoxObj.BoxColor(_priceStyle.clr); + mPriceBoxObj.BoxFill(_priceStyle.fill); + mPriceBoxObj.BoxStyle(_priceStyle.style); + mPriceBoxObj.BoxWidth(_priceStyle.width); + + // + _priceStyle.Clean(); + } + } + + // + // Protected ... + protected: + // + + // + bool HasPosition() + { + return mPosition.IsValid(); + } + + // + bool UpdatePosition( + XPosition &_position, + datetime _toTime = NULL // + ) + { + // + bool result = false; + + // + // Normalize ... + _toTime = NormalizeTime(_toTime); + + // + // Validate ... + result = _position.IsValid() && + (!HasPosition() + ? true + : _position.ticket == mPosition.ticket // + ); + if (!result) + { + return result; + } + + // + mPosition = _position; + result = UpdateZones(_toTime); + + // + return result; + } + + // + bool UpdateZones(datetime _toTime = NULL) + { + // + bool result = false; + + // + // Normalize ... + _toTime = NormalizeTime(_toTime); + + // + // Validate ... + result = HasPosition(); + if (!result) + { + return result; + } + + // + string iSymbol = mPosition.symbol; + ENUM_TIMEFRAMES iPeriod = mPosition.period; + + // + datetime iAt = mPosition.openAt; + datetime iFrom = mPosition.openAt; + + // + datetime _defaultToTime = iFrom + (PeriodSeconds(iPeriod) * 3); + datetime iTo = _toTime <= _defaultToTime + ? _defaultToTime + : _toTime; + + // + double iTP = mPosition.tp; + double iSL = mPosition.sl; + double iEntry = mPosition.entry; + double iPrice = mPosition.price; + + // + bool isLong = IsLong(mPosition.type); + ENUM_X_DIRECTION iRiskDir = isLong + ? X_DIRECTION_BEARISH + : X_DIRECTION_BULLISH; + ENUM_X_DIRECTION iRewardDir = isLong + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + bool isInProfit = mPosition.profit > 0; + bool isRiskFreed = + isLong + ? mPosition.sl > mPosition.entry + : mPosition.sl < mPosition.entry; + ENUM_X_DIRECTION iPriceDir = isInProfit + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Try to Update Zones ... + string iSuffix = ToXString(mPosition.type) + "_" + ToXString(mPosition.ticket); + string iPrefix = ToXString(TimeToSeconds(mPosition.openAt)); + string iName = iSuffix + "_" + iPrefix; + string iRiskName = iSuffix + "_" + "RISK" + "_" + iPrefix; + string iPriceName = iSuffix + "_" + "PRICE" + "_" + iPrefix; + string iRewardName = iSuffix + "_" + "REWARD" + "_" + iPrefix; + + // + // Risk Box ... + mRiskBox.to = iTo; + mRiskBox.at = iAt; + mRiskBox.lower = + isLong + ? isRiskFreed + ? iEntry + : iSL + : isRiskFreed + ? iSL + : iEntry; + mRiskBox.upper = + isLong + ? isRiskFreed + ? iSL + : iEntry + : isRiskFreed + ? iEntry + : iSL; + mRiskBox.from = iFrom; + mRiskBox.symbol = iSymbol; + mRiskBox.period = iPeriod; + mRiskBox.type = iRiskName; + mRiskBox.dir = isRiskFreed + ? X_DIRECTION_BEARISH + : X_DIRECTION_BULLISH; + + // + // Reward Box ... + mRewardBox.to = iTo; + mRewardBox.at = iAt; + mRewardBox.lower = + isLong + ? iEntry + : iTP; + mRewardBox.upper = + isLong + ? iTP + : iEntry; + mRewardBox.from = iFrom; + mRewardBox.symbol = iSymbol; + mRewardBox.period = iPeriod; + mRewardBox.type = iRewardName; + mRewardBox.dir = X_DIRECTION_BULLISH; + + // + // Price Box ... + mPriceBox.to = iTo; + mPriceBox.at = iAt; + mPriceBox.lower = + isLong + ? isInProfit + ? isRiskFreed + ? iSL + : iEntry + : iPrice + : isInProfit + ? isRiskFreed + ? iSL + : iPrice + : iEntry; + mPriceBox.upper = + isLong + ? isInProfit + ? iPrice + : iEntry + : isInProfit + ? iEntry + : iPrice; + mPriceBox.from = iFrom; + mPriceBox.symbol = iSymbol; + mPriceBox.period = iPeriod; + mPriceBox.type = iPriceName; + mPriceBox.dir = isInProfit + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + result = mRiskBox.IsValid() && + mPriceBox.IsValid() && + mRewardBox.IsValid(); + if (!result) + { + return result; + } + + // + mRiskBoxObj.Detach(); + mRiskBoxObj.Delete(); + bool isRiskCreated = + mRiskBoxObj.Create( + mChartID, + mWindowID, + mRiskBox.type, + mRiskBox.upper, + mRiskBox.lower, + mRiskBox.from, + mRiskBox.to, + NULL, // At ... + NULL // Prefix ... + ); + + // + mRewardBoxObj.Detach(); + mRewardBoxObj.Delete(); + bool isRewardCreated = + mRewardBoxObj.Create( + mChartID, + mWindowID, + mRewardBox.type, + mRewardBox.upper, + mRewardBox.lower, + mRewardBox.from, + mRewardBox.to, + NULL, // At ... + NULL // Prefix ... + ); + + // + mPriceBoxObj.Detach(); + mPriceBoxObj.Delete(); + bool isPriceCreated = + mPriceBoxObj.Create( + mChartID, + mWindowID, + mPriceBox.type, + mPriceBox.upper, + mPriceBox.lower, + mPriceBox.from, + mPriceBox.to, + NULL, // At ... + NULL // Prefix ... + ); + + // + result = + isRiskCreated && + isPriceCreated && + isRewardCreated; + if (result) + { + // + ObjName(iName); + + // + // Apply Styles ... + ApplyStyle(); + } + + // + return result; + } + + // + // Private ... + private: + // + // Props ... + + // + int mWindowID; + long mChartID; + + // + XBoxZone mRiskBox; + XBoxZone mPriceBox; + XPosition mPosition; + XBoxZone mRewardBox; + + // + XCBoxObject mRiskBoxObj; + XCBoxObject mPriceBoxObj; + XCBoxObject mRewardBoxObj; + + // +}; + +/** + * XPivotAnalysis Chart Object ... + **/ +class XCPivotAnalysisObject : public XCBaseObject +{ + // + public: + // + + /** + * Create Object ... + * + * @param chart_id: Long, Specified Chart ID ... + * @param window: Integer, Specified Chart Window ID ... + * @param model: XPivotAnalysis, reference model ... + * @param drawTrends: Specified to Draw Trends or not ... + * @param drawZones: Specified to Draw Support and Resistance Zones or not ... + * @param drawPivots: Specified to Draw Pivots or not ... + * @param peakArrow: int, Specified Arrow Code for Peak Pivots ... + * @param valeArrow: int, Specified Arrow Code for Vale Pivots ... + * @param threshold: int, distance between price and arrow in Point ... + * + * @return ( bool ) + */ + bool Create( + long chart_id, + int window, + XPivotAnalysis &model, + bool drawTrends = true, + bool drawZones = true, + bool drawPivots = true, + int peakArrow = 159, + int valeArrow = 159, + int threshold = 5 // + ) + { + // + bool result = false; + + // + bool has = false; + + // + // Validate ... + result = model.IsValid(); + if (!result) + { + return result; + } + + // + // Generate Object ID ... + string objID = model.GetObjectID(); + + // + // Draw Trend Lines ... + mUpper = NULL; + mLower = NULL; + if (drawTrends) + { + // + string upperName = model.GetUpperObjectID(); + string lowerName = model.GetLowerObjectID(); + + // + RemoveObjects(upperName, chart_id, window); + RemoveObjects(lowerName, chart_id, window); + + // + // Creating Upper ... + mUpper = new CChartObjectTrend(); + result = mUpper.Create( + chart_id, + upperName, + window, + model.fromTime, + model.peakFrom, + model.toTime, + model.peakTo // + ); + if (!result) + { + // + // Destroy Trending Objects ... + DestroyObject(mUpper); + DestroyObject(mLower); + + // + return result; + } + + // + // Create Lower ... + mLower = new CChartObjectTrend(); + result = mLower.Create( + chart_id, + lowerName, + window, + model.fromTime, + model.valeFrom, + model.toTime, + model.valeTo // + ); + if (!result) + { + // + // Destroy Trending Objects ... + DestroyObject(mUpper); + DestroyObject(mLower); + + // + return result; + } + } + + // + // Draw Zones ... + mSupportBox = NULL; + mResistanceBox = NULL; + if (drawZones) + { + // + // Support ... + XBoxZone tmpBox; + has = model.HasSupportBox(tmpBox); + if (has) + { + // + datetime to = TimeCurrent(); + string name = model.GetSupportBoxObjectID(); + RemoveObjects(name, chart_id, window); + mSupportBox = new XCBoxObject(); + result = mSupportBox.Create( + chart_id, + window, + name, + tmpBox.upper, + tmpBox.lower, + tmpBox.from, + to // + ); + if (!result) + { + // + DestroyObject(mUpper); + DestroyObject(mLower); + DestroyObject(mSupportBox); + + // + return result; + } + } + + // + // Resistance ... + tmpBox.Clean(); + has = model.HasResistanceBox(tmpBox); + if (has) + { + // + datetime to = TimeCurrent(); + string name = model.GetResistanceBoxObjectID(); + RemoveObjects(name, chart_id, window); + mResistanceBox = new XCBoxObject(); + result = mResistanceBox.Create( + chart_id, + window, + name, + tmpBox.upper, + tmpBox.lower, + tmpBox.from, + to // + ); + if (!result) + { + // + DestroyObject(mUpper); + DestroyObject(mLower); + DestroyObject(mSupportBox); + DestroyObject(mResistanceBox); + + // + return result; + } + } + } + + // + // Draw Pivots ... + if (drawPivots && + model.HasPivots()) + { + // + XOHCL iBar; + int arrow = 0; + string name = NULL; + XCBarArrowObject *iObj; + ENUM_X_PRICE type = X_PRICE_NONE; + int pivotsCount = ArraySize(model.pivots); + for (int i = 0; i < pivotsCount; i++) + { + // + has = model.pivots[i].GetBar(iBar); + if (!has) + { + continue; + } + + // + arrow = model.pivots[i].IsPeak() + ? peakArrow + : valeArrow; + name = model.pivots[i].GetObjectID(); + RemoveObjects(name, chart_id, window); + type = model.pivots[i].IsPeak() + ? X_PRICE_HIGH + : X_PRICE_LOW; + iObj = new XCBarArrowObject(); + has = iObj.CreateByBar( + chart_id, + name, + window, + arrow, + iBar, + type, + threshold // + ); + if (has) + { + // + if (model.pivots[i].IsPeak()) + { + // + if (mPeaks == NULL) + { + mPeaks = new CArrayObj(); + } + + // + mPeaks.Add(iObj); + } + else + { + // + if (mVales == NULL) + { + mVales = new CArrayObj(); + } + + // + mVales.Add(iObj); + } + } + + // + iBar.Clean(); + ZeroMemory(iObj); + } + + // + // Cleanup Resources ... + iBar.Clean(); + ZeroMemory(iObj); + } + + // + // Setting Object Name ... + if (result) + { + ObjName(objID); + } + + // + return result; + } + + // + // Virtuals ... + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + virtual int Type(void) + { + return (int)X_PIVOT_OBJ; + } + + /** + * Type as String ... + **/ + string TypeString() override + { + return ToXString(X_PIVOT_OBJ); + } + + /** + * Destroy ... + */ + void virtual Destroy() + { + // + DestroyObjects(mPeaks); + DestroyObjects(mVales); + + // + DestroyObject(mUpper); + DestroyObject(mLower); + DestroyObject(mSupportBox); + DestroyObject(mResistanceBox); + + // + delete mPeaks; + delete mVales; + delete mUpper; + delete mLower; + delete mSupportBox; + delete mResistanceBox; + + // + ZeroMemory(mPeaks); + ZeroMemory(mVales); + ZeroMemory(mUpper); + ZeroMemory(mLower); + ZeroMemory(mSupportBox); + ZeroMemory(mResistanceBox); + + // + Detach(); + Delete(); + } + + // + // Styling ... + + /** + * Set Width ... + * + * @param value: Integer ... + */ + void UpperWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + if (mUpper == NULL) + { + return; + } + + // + mUpper.Width(value); + } + + /** + * Set Color ... + * + * @param value: Color ... + */ + void UpperColor(color value) + { + // + if (mUpper == NULL) + { + return; + } + + // + mUpper.Color(value); + } + + /** + * Set Style ... + * + * @param value: ENUM_LINE_STYLE member ... + */ + void UpperStyle(ENUM_LINE_STYLE value) + { + // + if (mUpper == NULL) + { + return; + } + + // + mUpper.Style(value); + } + + /** + * Specified Upper Ray to Left or not ... + * + * @param value: bool + */ + void UpperRayLeft(bool value) + { + // + if (mUpper == NULL) + { + return; + } + + // + mUpper.RayLeft(value); + } + + /** + * Specified Upper Ray to Right or not ... + * + * @param value: bool + */ + void UpperRayRight(bool value) + { + // + if (mUpper == NULL) + { + return; + } + + // + mUpper.RayRight(value); + } + + /** + * Set Width ... + * + * @param value: Integer ... + */ + void LowerWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + if (mLower == NULL) + { + return; + } + + // + mLower.Width(value); + } + + /** + * Set Color ... + * + * @param value: Color ... + */ + void LowerColor(color value) + { + // + if (mLower == NULL) + { + return; + } + + // + mLower.Color(value); + } + + /** + * Set Style ... + * + * @param value: ENUM_LINE_STYLE member ... + */ + void LowerStyle(ENUM_LINE_STYLE value) + { + // + if (mLower == NULL) + { + return; + } + + // + mLower.Style(value); + } + + /** + * Specified Lower Ray to Left or not ... + * + * @param value: bool + */ + void LowerRayLeft(bool value) + { + // + if (mLower == NULL) + { + return; + } + + // + mLower.RayLeft(value); + } + + /** + * Specified Lower Ray to Right or not ... + * + * @param value: bool + */ + void LowerRayRight(bool value) + { + // + if (mLower == NULL) + { + return; + } + + // + mLower.RayRight(value); + } + + /** + * Set Width ... + * + * @param value: Integer ... + */ + void SupportWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + if (mSupportBox == NULL) + { + return; + } + + // + mSupportBox.BoxWidth(value); + } + + /** + * Set Color ... + * + * @param value: Color ... + */ + void SupportColor(color value) + { + // + if (mSupportBox == NULL) + { + return; + } + + // + mSupportBox.BoxColor(value); + } + + /** + * Set Style ... + * + * @param value: ENUM_LINE_STYLE member ... + */ + void SupportStyle(ENUM_LINE_STYLE value) + { + // + if (mSupportBox == NULL) + { + return; + } + + // + mSupportBox.BoxStyle(value); + } + + /** + * Set Width ... + * + * @param value: Integer ... + */ + void ResistanceWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + if (mResistanceBox == NULL) + { + return; + } + + // + mResistanceBox.BoxWidth(value); + } + + /** + * Set Color ... + * + * @param value: Color ... + */ + void ResistanceColor(color value) + { + // + if (mResistanceBox == NULL) + { + return; + } + + // + mResistanceBox.BoxColor(value); + } + + /** + * Set Style ... + * + * @param value: ENUM_LINE_STYLE member ... + */ + void ResistanceStyle(ENUM_LINE_STYLE value) + { + // + if (mResistanceBox == NULL) + { + return; + } + + // + mResistanceBox.BoxStyle(value); + } + + /** + * Set Width ... + * + * @param value: Integer ... + */ + void PeaksWidth(int value) + { + // + if (mPeaks == NULL) + { + return; + } + + // + // Normalize ... + value = NormalizeInt(value, 1); + + // + // Validate ... + int count = mPeaks.Total(); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + XCBarArrowObject *iPeak; + for (int i = 0; i < count; i++) + { + // + iPeak = (XCBarArrowObject *)mPeaks.At(i); + iPeak.ArrowWidth(value); + ZeroMemory(iPeak); + } + } + + /** + * Set Color ... + * + * @param value: Color ... + */ + void PeaksColor(color value) + { + // + if (mPeaks == NULL) + { + return; + } + + // + // Validate ... + int count = mPeaks.Total(); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + XCBarArrowObject *iPeak; + for (int i = 0; i < count; i++) + { + // + iPeak = (XCBarArrowObject *)mPeaks.At(i); + iPeak.ArrowColor(value); + ZeroMemory(iPeak); + } + } + + /** + * Set Arrow Anchor ... + * + * @param value: ENUM_ARROW_ANCHOR member ... + */ + void PeaksAnchor(ENUM_ARROW_ANCHOR value) + { + // + if (mPeaks == NULL) + { + return; + } + + // + // Validate ... + int count = mPeaks.Total(); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + XCBarArrowObject *iPeak; + for (int i = 0; i < count; i++) + { + // + iPeak = (XCBarArrowObject *)mPeaks.At(i); + iPeak.ArrowAnchor(value); + ZeroMemory(iPeak); + } + } + + /** + * Set Width ... + * + * @param value: Integer ... + */ + void ValesWidth(int value) + { + // + if (mVales == NULL) + { + return; + } + + // + // Normalize ... + value = NormalizeInt(value, 1); + + // + // Validate ... + int count = mVales.Total(); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + XCBarArrowObject *iVale; + for (int i = 0; i < count; i++) + { + // + iVale = (XCBarArrowObject *)mVales.At(i); + iVale.ArrowWidth(value); + ZeroMemory(iVale); + } + } + + /** + * Set Color ... + * + * @param value: Color ... + */ + void ValesColor(color value) + { + // + if (mVales == NULL) + { + return; + } + + // + // Validate ... + int count = mVales.Total(); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + XCBarArrowObject *iVale; + for (int i = 0; i < count; i++) + { + // + iVale = (XCBarArrowObject *)mVales.At(i); + iVale.ArrowColor(value); + ZeroMemory(iVale); + } + } + + /** + * Set Arrow Anchor ... + * + * @param value: ENUM_ARROW_ANCHOR member ... + */ + void ValesAnchor(ENUM_ARROW_ANCHOR value) + { + // + if (mVales == NULL) + { + return; + } + + // + // Validate ... + int count = mVales.Total(); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + XCBarArrowObject *iVale; + for (int i = 0; i < count; i++) + { + // + iVale = (XCBarArrowObject *)mVales.At(i); + iVale.ArrowAnchor(value); + ZeroMemory(iVale); + } + } + + // + private: + // + CArrayObj *mPeaks; + CArrayObj *mVales; + CChartObjectTrend *mUpper; + CChartObjectTrend *mLower; + XCBoxObject *mSupportBox; + XCBoxObject *mResistanceBox; +}; + +// +// Extensions ... + +/** + * Add all Items of Specified CArrayObj into another ... + * + * @param source: CArrayObj, pointer refrence Specified Data Source ... + * @param dest: CArrayObj, pointer refrence Specified Destination of Adding ... + */ +void AddObjects( + CArrayObj *&source, + CArrayObj &dest // +) +{ + // + bool has = source != NULL && + source.Total() > 0; + if (!has) + { + return; + } + + // + for (int i = 0; i < source.Total(); i++) + { + dest.Add(source.At(i)); + } +} + +/** + * Destroy Object if Exists ... + * + * @param object: pointer refrence to Destroy ... + */ +void DestroyObject(XCBoxObject *&object) +{ + // + // Validate ... + bool has = object != NULL; + if (!has) + { + return; + } + + // + object.Destroy(); + + // + object.Detach(); + object.Delete(); + + // + delete object; + ZeroMemory(object); +} + +/** + * Destroy Object if Exists ... + * + * @param object: pointer refrence to Destroy ... + */ +void DestroyObject(XCPivotAnalysisObject *&object) +{ + // + // Validate ... + bool has = object != NULL; + if (!has) + { + return; + } + + // + object.Destroy(); + + // + object.Detach(); + object.Delete(); + + // + delete object; + ZeroMemory(object); +} + +/** + * Destroy Object if Exists ... + * + * @param object: pointer refrence to Destroy ... + */ +void DestroyObject(CChartObjectTrend *&object) +{ + // + // Validate ... + bool has = object != NULL; + if (!has) + { + return; + } + + // + object.Detach(); + object.Delete(); + + // + delete object; + ZeroMemory(object); +} + +/** + * Completely Destroy all Chart Objects ... + * + * @param objects: CArrayObj, pointer refrence Specified Data Source ... + */ +void DestroyObjects(CArrayObj *&objects) +{ + // + // Validate Exists ... + if (objects == NULL) + { + return; + } + + // + // Count Childs ... + int count = objects.Total(); + if (!IsValidSize(count)) + { + return; + } + + // + // Destroy all Childs ... + for (int i = 0; i < count; i++) + { + // + // Checking Types ... + int iType = ((CChartObject *)objects.At(i)).Type(); + + // + string iTypeStr = NULL; + if (iType == X_EMPTY_OBJ) + { + // + XCBaseObject *iObj = (XCBaseObject *)objects.At(i); + iTypeStr = iObj.TypeString(); + + // + if (iTypeStr == ToXString(X_BOX_OBJ)) + { + iType = X_BOX_OBJ; + } + else if (iTypeStr == ToXString(X_BAR_ARROW_OBJ)) + { + iType = X_BAR_ARROW_OBJ; + } + else if (iTypeStr == ToXString(X_SIGNAL_OBJ)) + { + iType = X_SIGNAL_OBJ; + } + else if (iTypeStr == ToXString(X_OHCL_OBJ)) + { + iType = X_OHCL_OBJ; + } + else if (iTypeStr == ToXString(X_RR_OBJ)) + { + iType = X_RR_OBJ; + } + else if (iTypeStr == ToXString(X_PIVOT_OBJ)) + { + iType = X_PIVOT_OBJ; + } + } + + // + string iName = ((CChartObject *)objects.At(i)).Name(); + if (!IsSpecifiedValid(iName)) + { + iName = ((XCBaseObject *)objects.At(i)).ObjName(); + } + + // + switch (iType) + { + // + case X_RR_OBJ: { + // + XCRRObject *iObj = (XCRRObject *)objects.At(i); + iObj.Destroy(); + + // + delete iObj; + ZeroMemory(iObj); + } + break; + case X_BOX_OBJ: { + // + XCBoxObject *iObj = (XCBoxObject *)objects.At(i); + iObj.Destroy(); + iObj.Detach(); + iObj.Delete(); + + // + delete iObj; + ZeroMemory(iObj); + } + break; + case X_OHCL_OBJ: { + // + XCOHCLObject *iObj = (XCOHCLObject *)objects.At(i); + iObj.Destroy(); + + // + delete iObj; + ZeroMemory(iObj); + } + break; + case X_PIVOT_OBJ: { + // + XCPivotAnalysisObject *iObj = (XCPivotAnalysisObject *)objects.At(i); + iObj.Destroy(); + + // + delete iObj; + ZeroMemory(iObj); + } + break; + case X_SIGNAL_OBJ: { + // + XCSignalObject *iObj = (XCSignalObject *)objects.At(i); + iObj.Destroy(); + + // + delete iObj; + ZeroMemory(iObj); + } + break; + case X_BAR_ARROW_OBJ: { + // + XCBarArrowObject *iObj = (XCBarArrowObject *)objects.At(i); + iObj.Destroy(); + + // + delete iObj; + ZeroMemory(iObj); + } + break; + // + // Default Object Types ... + case OBJ_VLINE: + case OBJ_HLINE: + case OBJ_TREND: + case OBJ_TRENDBYANGLE: + case OBJ_CYCLES: + case OBJ_ARROWED_LINE: + case OBJ_CHANNEL: + case OBJ_STDDEVCHANNEL: + case OBJ_REGRESSION: + case OBJ_PITCHFORK: + case OBJ_GANNLINE: + case OBJ_GANNFAN: + case OBJ_GANNGRID: + case OBJ_FIBO: + case OBJ_FIBOTIMES: + case OBJ_FIBOFAN: + case OBJ_FIBOARC: + case OBJ_FIBOCHANNEL: + case OBJ_EXPANSION: + case OBJ_ELLIOTWAVE5: + case OBJ_ELLIOTWAVE3: + case OBJ_RECTANGLE: + case OBJ_TRIANGLE: + case OBJ_ELLIPSE: + case OBJ_ARROW_THUMB_UP: + case OBJ_ARROW_THUMB_DOWN: + case OBJ_ARROW_UP: + case OBJ_ARROW_DOWN: + case OBJ_ARROW_STOP: + case OBJ_ARROW_CHECK: + case OBJ_ARROW_LEFT_PRICE: + case OBJ_ARROW_RIGHT_PRICE: + case OBJ_ARROW_BUY: + case OBJ_ARROW_SELL: + case OBJ_ARROW: + case OBJ_TEXT: + case OBJ_LABEL: + case OBJ_BUTTON: + case OBJ_CHART: + case OBJ_BITMAP: + case OBJ_BITMAP_LABEL: + case OBJ_EDIT: + case OBJ_EVENT: + case OBJ_RECTANGLE_LABEL: { + // + CChartObject *iObj = (CChartObject *)objects.At(i); + + // + iObj.Detach(); + iObj.Delete(); + + // + delete iObj; + ZeroMemory(iObj); + } + break; + } + + // + RemoveObjects(iName); + } + + // + // Destroy itSelf ... + objects.Clear(); + delete objects; + ZeroMemory(objects); +} + +/** + * Remove Drawn Objects from Chart ... + * + * @param tag: Specified Object Name, if NULL remove all Objects ... + * @param chartId: long, Specified Chart ... + * @param subWindow: int Specified Sub Window ... + */ +void RemoveObjects( + string tag = NULL, + long chartId = -1, + int subWindow = -1 // +) +{ + // + // Normalize Args ... + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + bool has = false; + string iName = NULL; + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + // Retrieve Object Name ... + iName = ObjectName(chartId, iObj, subWindow); + + // + // Check Can Delete Object or not ... + has = + !IsSpecifiedValid(tag) + ? true + : StringFind(iName, tag) >= 0; + if (has) + { + ObjectDelete(chartId, iName); + } + } + + // + // Redraw Chart ... + ChartRedraw(); +} + +// +// Color Manipulation Functions ... + +/** + * Apply Alph to Color ... + * + * @param _clr: Specified Color ... + * @param _alpha: Specified Alpha to Apply ... + * + * @return ( color ) + */ +color ApplyAlpha( + color _clr, + uchar _alpha = 255 // +) +{ + // + color result = _clr; + + // + // Normalize ... + _alpha = (uchar)NormalizeInt(_alpha, 0, 255); + + // + uchar alpha = _alpha / 255; + + // + uint uintColor = ColorToARGB(_clr, alpha); + result = (color)uintColor; + + // + return result; +} +// \ No newline at end of file diff --git a/Documents/BKP/x-saherelm.xfima.x-poi.drawer.class.mq5 b/Documents/BKP/x-saherelm.xfima.x-poi.drawer.class.mq5 index ef98c557..8e2661c4 100644 --- a/Documents/BKP/x-saherelm.xfima.x-poi.drawer.class.mq5 +++ b/Documents/BKP/x-saherelm.xfima.x-poi.drawer.class.mq5 @@ -1772,4 +1772,178 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer // }; +/** + * Draw Pivot Analysis ... + * + * @param analysis: XPivotAnalysis, referece Specified Pivot Analysis ... + * @param object: XCPivotAnalysisObject, pointer reference for Drawn Object ... + * @param drawTrends: Specified to Draw Trends or not ... + * @param drawZones: Specified to Draw Support and Resistance Zones or not ... + * @param drawPivots: Specified to Draw Pivots or not ... + * @param peakArrow: int, Specified Arrow Code for Peak Pivots ... + * @param valeArrow: int, Specified Arrow Code for Vale Pivots ... + * @param threshold: int, distance between price and arrow in Point ... + * + * @return ( bool ) + */ +bool DrawPivotAnalysis( + XPivotAnalysis &analysis, + XCPivotAnalysisObject *&object, + bool drawTrends = true, + bool drawZones = true, + bool drawPivots = true, + int peakArrow = 159, + int valeArrow = 159, + int threshold = 5 // +) +{ + // + bool result = false; + + // + // Prepare ... + object = NULL; + + // + // Normalize ... + + // + // Validate ... + result = analysis.IsValid() && + analysis.IsAnalysed(); + if (!result) + { + return result; + } + + // + object = new XCPivotAnalysisObject(); + result = object.Create( + ChartIdentification(), + SubWindowIdentification(), + analysis, + drawTrends, + drawZones, + drawPivots, + peakArrow, + valeArrow, + threshold // + ); + if (result) + { + // + ApplyPivotAnalysisStyle( + object, + analysis // + ); + } + + // + return result; +} + +/** + * Apply Specified Style to Specified Object ... + * + * @param object: CChartObject, pointer reference of Object ... + * @param model: XPivotAnalysis, referece to access requirements ... + */ +void ApplyPivotAnalysisStyle( + XCPivotAnalysisObject *&object, + XPivotAnalysis &model // +) +{ + // + // Validate ... + bool has = model.IsValid() && + model.IsAnalysed() && + object != NULL; + if (!has) + { + return; + } + + // + XPOIStyle style; + + // + // Support ... + style = defaultBullishStyle; + object.SupportColor(style.clr); + object.SupportWidth(style.width); + object.SupportStyle(style.style); + + // + // Resistance ... + style = defaultBearishStyle; + object.ResistanceColor(style.clr); + object.ResistanceWidth(style.width); + object.ResistanceStyle(style.style); + + // + // Upper ... + if (model.IsPeakAnalysed()) + { + // + GetStyle( + style, + model.peakDir // + ); + if (!HasDirection(model.peakDir)) + { + // + style.Default(); + style.clr = clrGray; + } + + // + object.UpperColor(style.clr); + object.UpperWidth(style.width); + object.UpperStyle(style.style); + object.UpperRayLeft(false); + object.UpperRayRight(true); + } + + // + // Lower ... + if (model.IsValeAnalysed()) + { + // + GetStyle( + style, + model.valeDir // + ); + if (!HasDirection(model.valeDir)) + { + // + style.Default(); + style.clr = clrGray; + } + + // + object.LowerColor(style.clr); + object.LowerWidth(style.width); + object.LowerStyle(style.style); + object.UpperRayLeft(false); + object.LowerRayRight(true); + } + + // + // Peak Pivots ... + style = defaultBearishStyle; + object.PeaksColor(style.clr); + object.PeaksWidth(style.width); + object.PeaksAnchor(ANCHOR_BOTTOM); + + // + // Vale Pivots ... + style = defaultBullishStyle; + object.ValesColor(style.clr); + object.ValesWidth(style.width); + object.ValesAnchor(ANCHOR_TOP); + + // + style.Clean(); +} + // \ No newline at end of file diff --git a/Documents/BKP/xfima-zone-detector.bkp.mq5 b/Documents/BKP/xfima-zone-detector.bkp.mq5 new file mode 100644 index 00000000..abc73a71 --- /dev/null +++ b/Documents/BKP/xfima-zone-detector.bkp.mq5 @@ -0,0 +1,1219 @@ + + // + // Detectors ... + + /** + * Detect Zones (Support / Resistance) based on XFIMA Validators ... + * + * @param zones: XBoxZone, reference to Collection for holding Detected Zones ... + * @param barIndex: int, Specified Start Looking Bar Index ... + * @param onlyValidZones: bool, Only Validation Zones ... + * @param requiredNumberOfZones: int, Specified how many zones looking for ... + * @param shadowMultiplier: double, a valid zone's Shadow side multiplier ... + * @param validationStrength: double, Validation Strength ... + * @param validationLength: int, Validation Length ... + * @param maxAllowedLoopbackLength: int, Specified Max Allowed Looping back trhough Bars for Detection ... + * + * @return ( int ) + */ + int DetectXFIMAZones( + XBoxZone &zones[], + int barIndex = 0, + bool onlyValidZones = false, + int requiredNumberOfZones = 50, + double shadowMultiplier = 4, + double validationStrength = 1, + int validationLength = 7, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + XClean(zones); + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + validationLength = NormalizeInt(validationLength, 3); + shadowMultiplier = NormalizeDouble(shadowMultiplier, 2); + validationStrength = NormalizeDouble(validationStrength, 1); + requiredNumberOfZones = NormalizeInt(requiredNumberOfZones, 5); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + XOHCL bar; + bool has = IsValid() && + bar.Init( + mSymbol, + mPeriod, + barIndex + 1 // + ); + if (!has) + { + return result; + } + + // + // Define Requirements ... + XOHCL iBar; + XBoxZone iBox; + bool isBullish = false; + bool isBearish = false; + double iUpper = EMPTY_VALUE; + double iLower = EMPTY_VALUE; + double iHKUpper = EMPTY_VALUE; + double iHKLower = EMPTY_VALUE; + double iMAUpper = EMPTY_VALUE; + double iMALower = EMPTY_VALUE; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + // Create a Loop to Detect Zones ... + int start = barIndex; + int idx = start - 1; + int end = start + maxAllowedLoopbackLength; + while (ArraySize(zones) < requiredNumberOfZones && idx < end) + { + // + idx++; + + // + // Initialize Indexed Bar ... + has = bar.BarAt(idx, iBar); + if (!has) + { + continue; + } + + // + // Reading Bars ... + iMAUpper = GetMABondUpper(idx); + iMALower = GetMABondLower(idx); + iHKUpper = GetHKBondUpper(idx); + iHKLower = GetHKBondLower(idx); + + // + iUpper = MathMax(iMAUpper, iHKUpper); + iLower = MathMin(iMALower, iHKLower); + + // + // Check Bar State ... + has = + NotEmptyZero(iUpper) && + NotEmptyZero(iLower); + if (!has) + { + continue; + } + + // + // Check Direction of Zone ... + isBullish = iBar.low < iLower; + isBearish = iBar.high > iUpper; + has = (isBullish && !isBearish) || + (isBearish && !isBullish); + if (!has) + { + continue; + } + + // + // Validate Price Based on Bar ... + // Validate Shadow Multiplier ... + has = + isBullish + ? iBar.low < bar.low + : iBar.high > bar.high; + has = + has && + (isBullish + ? iBar.GetLowShadow() > iBar.GetHighShadow() * shadowMultiplier + : iBar.GetHighShadow() > iBar.GetLowShadow() * shadowMultiplier); + if (!has) + { + continue; + } + + // + iDir = isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Fill Bax ... + iBox.dir = iDir; + iBox.symbol = mSymbol; + iBox.period = mPeriod; + iBox.upper = + isBullish + ? iBar.GetDown() + : iBar.high; + iBox.lower = + isBullish + ? iBar.low + : iBar.GetUp(); + iBox.type = + (isBullish ? "XFIMA_Support" : "XFIMA_Resistance") + "_" + + ToXString(NormalizePrice(iBox.upper, iBox.symbol)) + "_" + + ToXString(NormalizePrice(iBox.lower, iBox.symbol)); + + // + iBox.at = iBar.time; + iBox.to = bar.time; + + // + // Loopback to Detect From Time ... + XOHCL pBar; + datetime fromTime = NULL; + has = iBar.GetPreviousBar(pBar); + if (has) + { + // + while (!IsXValid(fromTime)) + { + // + // Check Price Inside ... + has = + isBullish + ? pBar.GetDown() < iBox.lower + : pBar.GetUp() > iBox.upper; + if (has) + { + fromTime = pBar.time; + } + + // + // Retrieve PrevBar ... + has = pBar.GetPreviousBar(pBar); + if (!has) + { + break; + } + } + } + has = IsXValid(fromTime); + if (has) + { + iBox.from = fromTime; + } + + // + // Validate Zone Length ... + has = iBox.IsValid() && + (validationStrength >= 1 + ? iBox.GetRange() >= validationStrength * GetPoints(iBox.symbol) + : true) && + (iBox.FromIndex() - iBox.AtIndex() >= validationLength); + + // + // Validate Zone State ... + if (has) + { + // + // Cleanup Bar ... + iBar.Clean(); + + // + // Loopingh through At Index ... + for (int i = iBox.ToIndex(); i < iBox.AtIndex(); i++) + { + // + // Initialized Indexed Bar ... + has = bar.BarAt(i, iBar); + if (!has) + { + break; + } + + // + // Validate Bar ... + has = + iBox.IsBullish() + ? iBar.low > iBox.lower + : iBar.high < iBox.upper; + if (!has) + { + break; + } + } + } + + // + if (has) + { + // + AddIfNotExists( + iBox, + zones // + ); + } + + // + // Cleanup Resources ... + iBar.Clean(); + pBar.Clean(); + iBox.Clean(); + } + + // + result = ArraySize(zones); + + // + // Cleanup Resources ... + if (!result) + { + XClean(zones); + } + bar.Clean(); + iBar.Clean(); + iBox.Clean(); + + // + return result; + } + + int DetecteXFIMAPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOfPivots = 50, + int validationLength = 7, + int maxAllowedLoopbackLength = 1500, // + // + // PV ... + int pvValidationLength = 7, + // + // Momentum ... + int momentumBarValidationLength = 3, + double momentumBarApprovedMultiplier = 3, + // + // TrueGap ... + double trueGapApprovedStrength = 2, + // + // Pin ... + double pinBarShadowApprovedMultiplier = 3, + double pinBarRangeMultiplier = 4, + bool pinBarForceDirection = false, + // + // Flag ... + int flagPatternPullbackLength = 3 // + ) + { + // + int result = 0; + + // + // Prepare ... + XClean(pivots); + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + validationLength = NormalizeInt(validationLength, 1); + requiredNumberOfPivots = NormalizeInt(requiredNumberOfPivots, 5); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + pvValidationLength = NormalizeInt(pvValidationLength, 0); + + // + momentumBarValidationLength = NormalizeInt(momentumBarValidationLength, 2); + momentumBarApprovedMultiplier = NormalizeDouble(momentumBarApprovedMultiplier, 1); + + // + trueGapApprovedStrength = NormalizeDouble(trueGapApprovedStrength, 1); + + // + pinBarRangeMultiplier = NormalizeDouble(pinBarRangeMultiplier, 4); + pinBarShadowApprovedMultiplier = NormalizeDouble(pinBarShadowApprovedMultiplier, 3); + + // + flagPatternPullbackLength = NormalizeInt(flagPatternPullbackLength, 3); + + // + // Validate ... + bool has = IsValid(); + if (!has) + { + return result; + } + + // + XOHCL iBar; + XOHCL tmpBar; + XPivot iPivot; + int count = 0; + string iPrefix = NULL; + int idx = barIndex - 1; + double iMin = EMPTY_VALUE; + double iMax = EMPTY_VALUE; + double iValue = EMPTY_VALUE; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_DIRECTION tmpDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int end = barIndex + maxAllowedLoopbackLength; + while ( + idx < end && + ArraySize(pivots) < requiredNumberOfPivots) + { + // + idx++; + + // + iBar.Clean(); + iPivot.Clean(); + tmpBar.Clean(); + iPrefix = NULL; + iDir = X_DIRECTION_NONE; + + // + has = iBar.Init( + mSymbol, + mPeriod, + idx // + ); + if (!has) + { + break; + } + + // + // Pivots List ... + + // + // PV ... + bool isPV = false; + bool isPeak = false; + bool isVale = false; + tmpDir = X_DIRECTION_NONE; + if (pvValidationLength > 0) + { + // + isPV = patternDetector.IsPV( + iBar, + tmpDir, + pvValidationLength // + ); + isPeak = isPV && + IsXBearish(tmpDir); + isVale = isPV && + IsXBullish(tmpDir); + if (isPV) + { + iPrefix += isPeak ? "XPK" : "XVL"; + } + + // + // Continue Loopback if PV Validation Provided and not isPV ... + if (!isPV) + { + continue; + } + } + + // + // Momentum Bar ... + bool isMomentum = patternDetector.IsMomentumBar( + iBar, + iDir, + momentumBarValidationLength, + momentumBarApprovedMultiplier // + ); + if (isMomentum) + { + // + if (!IsXValid(tmpDir)) + { + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isMomentum = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "MNTM"; + } + } + + // + // Engulf Bar ... + bool isEngulfed = patternDetector.IsEngulfedBar( + iBar, + iDir // + ); + if (isEngulfed) + { + // + if (!IsXValid(tmpDir)) + { + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isEngulfed = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "ENGLF"; + } + } + + // + // True Gap ... + bool isTrueGaped = patternDetector.IsTrueGapedBar( + iBar, + iDir, + trueGapApprovedStrength // + ); + if (isTrueGaped) + { + // + if (!IsXValid(tmpDir)) + { + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isTrueGaped = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "TG"; + } + } + + // + // Pin Bar ... + bool isPinned = patternDetector.IsPinnedBar( + iBar, + iDir, + pinBarShadowApprovedMultiplier, + pinBarRangeMultiplier, + pinBarForceDirection // + ); + if (isPinned) + { + // + if (!IsXValid(tmpDir)) + { + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isPinned = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "PND"; + } + } + + // + // Patterns ... + + // + // Star Pattern ... + bool isStarPattern = patternDetector.IsStarPattern( + iBar, + iDir // + ); + if (isStarPattern) + { + // + if (!IsXValid(tmpDir)) + { + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isStarPattern = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "STR"; + } + } + + // + // Piercing Pattern ... + bool isPiercingPattern = patternDetector.IsPiercingPattern( + iBar, + iDir // + ); + if (isPiercingPattern) + { + // + if (!IsXValid(tmpDir)) + { + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isPiercingPattern = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "PRCG"; + } + } + + // + // Rising Pattern ... + bool isRisingPattern = patternDetector.IsRisingPattern( + iBar, + iDir // + ); + if (isRisingPattern) + { + // + if (!IsXValid(tmpDir)) + { + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isRisingPattern = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "RSG"; + } + } + + // + // Flag Pattern ... + bool isFlagPattern = patternDetector.IsFlagPattern( + iBar, + iDir, + tmpBar, + flagPatternPullbackLength // + ); + if (isFlagPattern) + { + // + if (!IsXValid(tmpDir)) + { + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isFlagPattern = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "FLG"; + } + } + + // + // Signal Key Pattern ... + bool isSignalKeyPattern = patternDetector.IsSignalKeyBarPattern( + iBar, + iDir, + pinBarShadowApprovedMultiplier, + pinBarRangeMultiplier, + pinBarForceDirection // + ); + if (isSignalKeyPattern) + { + // + if (!IsXValid(tmpDir)) + { + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isSignalKeyPattern = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "SKB"; + } + } + + // + has = + isPinned || + isMomentum || + isEngulfed || + isTrueGaped || + isStarPattern || + isFlagPattern || + isRisingPattern || + isPiercingPattern || + isSignalKeyPattern; + if (!has) + { + continue; + } + + // // + // // Validate Pivot Length ... + // // Validate Pivot vs XFIMA Values ... + // for (int i = iBar.Index(); i < iBar.Index() + validationLength; i++) + // { + // // + // tmpBar.Clean(); + // has = iBar.BarAt(i, tmpBar); + // if (!has) + // { + // break; + // } + + // // + // iMin = EMPTY_VALUE; + // iMax = EMPTY_VALUE; + // has = GetBoundaryValues( + // iMin, + // iMax, + // i // + // ); + + // // + // // Validate Bar vs TmpBar and Also Boundary Values ... + // has = + // has && + // (IsXBullish(iDir) + // ? + // // tmpBar.low < iMin && + // (tmpBar.low > iBar.low || + // tmpBar.GetDown() || iBar.GetDown()) + // : + // // tmpBar.high > iMax && + // (tmpBar.high < iBar.high || + // tmpBar.GetUp() < iBar.GetUp())); + // if (!has) + // { + // break; + // } + + // // + // iValue = IsXBullish(iDir) + // ? iBar.low + // : iBar.high; + + // // + // iType = IsXBullish(iDir) + // ? X_PIVOT_TYPE_VALE + // : X_PIVOT_TYPE_PEAK; + + // // + // tmpBar.Clean(); + // } + + // + has = IsXValid(iPrefix); + if (has) + { + // + iValue = IsXBullish(iDir) + ? iBar.low + : iBar.high; + + // + iType = IsXBullish(iDir) + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_PEAK; + + // + // Preparing Pivot ... + has = iPivot.Init( + iValue, + iBar.time, + iBar.symbol, + iDir, + iBar.period, + iType // + ); + if (has) + { + // + iPivot.prefix = iPrefix; + + // + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + } + + // + // Cleanup Resources ... + iBar.Clean(); + iPivot.Clean(); + tmpBar.Clean(); + + // + result = ArraySize(pivots); + + // + return result; + } + + /** + * Detect XFIMA Based POI Bars ... + * + * @param bars: XOHCL, reference collection to holds detected bars ... + * @param dirs: ENUM_X_DIRECTION, reference collection to holds detected bars Direction ... + * @param barIndex: int, Specified Bar Index ... + * @param forDir: ENUM_X_DIRECTION, specified which Direction of potential bars looking for ... + * @param requiredNumberOfBars: int, Specified how many bars looking for ... + * @param maxAllowedLoopbackLength: int, Specified Max Allowed Looping back trhough Bars for Detection ... + * @return ( int ) + */ + int DetectXFIMAPOIBars( + XOHCL &bars[], + ENUM_X_DIRECTION &dirs[], + int barIndex = 0, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + int requiredNumberOfBars = 300, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + XClean(bars); + XClean(dirs); + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + requiredNumberOfBars = NormalizeInt(requiredNumberOfBars, 5); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + bool has = IsValid(); + if (!has) + { + return result; + } + + // + XOHCL iBar; + int idx = barIndex - 1; + int start = barIndex; + bool isBullish = false; + bool isBearish = false; + double iMin = EMPTY_VALUE; + double iMax = EMPTY_VALUE; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + int end = start + maxAllowedLoopbackLength; + while (ArraySize(bars) < requiredNumberOfBars || + idx < maxAllowedLoopbackLength) + { + // + idx++; + has = iBar.Init( + mSymbol, + mPeriod, + idx // + ); + if (!has) + { + continue; + } + + // + has = GetBoundaryValues( + iMin, + iMax, + idx // + ); + if (!has) + { + continue; + } + + // + isBullish = iBar.low < iMin; + isBearish = iBar.high > iMax; + has = + !HasDirection(forDir) + ? ((isBullish && !isBearish) || + (isBearish && !isBullish)) + : IsXBullish(forDir) + ? (isBullish && !isBearish) + : (isBearish && !isBullish); + if (has) + { + // + iDir = isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + AddRef( + iBar, + bars // + ); + + // + Add( + iDir, + dirs // + ); + } + } + + // + result = ArraySize(bars); + + // + // Cleanup Resources ... + iBar.Clean(); + + // + return result; + } + + int DetectXFIMAReversalPOIBars( + XOHCL &bars[], + ENUM_X_DIRECTION &dirs[], + int barIndex = 0, + bool forceTouchBoundary = false, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + int requiredNumberOfBars = 300, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + XClean(bars); + XClean(dirs); + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + requiredNumberOfBars = NormalizeInt(requiredNumberOfBars, 5); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + bool has = IsValid(); + if (!has) + { + return result; + } + + // + // Detect POI Bars ... + XOHCL decisionBars[]; + ENUM_X_DIRECTION decisionBarDirs[]; + int decisionBarsCount = DetectXFIMAPOIBars( + decisionBars, + decisionBarDirs, + barIndex, + forDir, + requiredNumberOfBars, + maxAllowedLoopbackLength // + ); + has = IsValidSize(decisionBarsCount); + if (!has) + { + // + XClean(decisionBars); + XClean(decisionBarDirs); + + // + return result; + } + + // + bool isBullish = false; + bool isBearish = false; + double iMin = EMPTY_VALUE; + double iMax = EMPTY_VALUE; + bool isCond1Bullish = false; + bool isCond1Bearish = false; + for (int i = 0; i < decisionBarsCount; i++) + { + // + // Read Boundary Values ... + has = GetBoundaryValues(iMin, iMax, i); + if (!has) + { + continue; + } + + // + // Check Bar Decision Direction ... + isBullish = IsXBullish(decisionBarDirs[i]); + isBearish = IsXBearish(decisionBarDirs[i]); + + // + // Validate ... + + // + isCond1Bullish = decisionBars[i].IsBullish(); + + // + isCond1Bearish = decisionBars[i].IsBearish(); + + // + isBullish = + isBullish && + (isCond1Bullish); + + // + isBearish = + isBearish && + (isCond1Bearish); + + // + if (forceTouchBoundary) + { + // + isBullish = + isBullish && + (decisionBars[i].high > iMin || + decisionBars[i].GetUp() > iMin); + + // + isBearish = + isBearish && + (decisionBars[i].low < iMax || + decisionBars[i].GetDown() < iMax); + } + + // + has = + isBullish || + isBearish; + if (has) + { + // + AddRef( + decisionBars[i], + bars // + ); + + // + Add( + decisionBarDirs[i], + dirs // + ); + } + } + + // + result = ArraySize(bars); + + // + // Cleanup Resources ... + XClean(decisionBars); + XClean(decisionBarDirs); + + // + return result; + } + + int DetectXFIMAContinuationalPOIBars( + XOHCL &bars[], + ENUM_X_DIRECTION &dirs[], + int barIndex = 0, + bool forceTouchBoundary = false, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + int requiredNumberOfBars = 300, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + XClean(bars); + XClean(dirs); + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + requiredNumberOfBars = NormalizeInt(requiredNumberOfBars, 5); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + bool has = IsValid(); + if (!has) + { + return result; + } + + // + // Detect POI Bars ... + XOHCL decisionBars[]; + ENUM_X_DIRECTION decisionBarDirs[]; + int decisionBarsCount = DetectXFIMAPOIBars( + decisionBars, + decisionBarDirs, + barIndex, + forDir, + requiredNumberOfBars, + maxAllowedLoopbackLength // + ); + has = IsValidSize(decisionBarsCount); + if (!has) + { + // + XClean(decisionBars); + XClean(decisionBarDirs); + + // + return result; + } + + // + bool isBullish = false; + bool isBearish = false; + double iMin = EMPTY_VALUE; + double iMax = EMPTY_VALUE; + bool isCond1Bullish = false; + bool isCond1Bearish = false; + for (int i = 0; i < decisionBarsCount; i++) + { + // + // Read Indexed Bars Boundaries ... + has = GetBoundaryValues(iMin, iMax, decisionBars[i].Index()); + if (!has) + { + continue; + } + + // + // Make Direction Opposit ... + decisionBarDirs[i] = Opposit(decisionBarDirs[i]); + + // + isBullish = IsXBullish(decisionBarDirs[i]); + isBearish = IsXBearish(decisionBarDirs[i]); + + // + // Check Bar Validations ... + + // + // Cond 1 ... + + // + isCond1Bullish = + decisionBars[i].IsBearish() && + (decisionBars[i].low >= iMax || + (decisionBars[i].low <= iMax && + decisionBars[i].GetUp() >= iMax)); + + // + isCond1Bearish = + decisionBars[i].IsBullish() && + (decisionBars[i].high <= iMin || + (decisionBars[i].high >= iMin && + decisionBars[i].GetDown() <= iMin)); + + // + isBullish = + isBullish && + (isCond1Bullish); + + // + isBearish = + isBearish && + (isCond1Bearish); + + // + if (forceTouchBoundary) + { + // + isBullish = + isBullish && + (decisionBars[i].low >= iMax || + (decisionBars[i].low <= iMax && + decisionBars[i].GetUp() >= iMax)); + + // + isBearish = + isBearish && + (decisionBars[i].high <= iMin || + (decisionBars[i].high >= iMin && + decisionBars[i].GetDown() <= iMin)); + } + + // + has = + isBullish || + isBearish; + if (has) + { + // + AddRef( + decisionBars[i], + bars // + ); + + // + Add( + decisionBarDirs[i], + dirs // + ); + } + } + + // + result = MathMin(ArraySize(bars), ArraySize(dirs)); + + // + // Cleanup Resources ... + XClean(decisionBars); + XClean(decisionBarDirs); + + // + return result; + } diff --git a/Helpers/x-saherelm.xfima.helper.mq5 b/Helpers/x-saherelm.xfima.helper.mq5 index c46cc33c..a8ee9470 100644 --- a/Helpers/x-saherelm.xfima.helper.mq5 +++ b/Helpers/x-saherelm.xfima.helper.mq5 @@ -30,6 +30,138 @@ // // Definitions ... +enum ENUM_XFIMA_PIVOTS +{ + XFIMA_PIVOT_NONE = 0, + XFIMA_PIVOT_PV = 1, + XFIMA_PIVOT_HK = 2, + XFIMA_PIVOT_ZIGZAG = 3, + XFIMA_PIVOT_MA_CROSS = 4, + XFIMA_PIVOT_HK_SWITCH = 5, + XFIMA_PIVOT_SAR_SWITCH = 6, + XFIMA_PIVOT_BOUNDARY_SWITCH = 7, +}; + +bool IsXValid(ENUM_XFIMA_PIVOTS value) +{ + // + bool result = false; + + // + result = value != XFIMA_PIVOT_NONE; + + // + return result; +} + +string ToXString(ENUM_XFIMA_PIVOTS value) +{ + // + string result = NULL; + + // + if (!IsXValid(value)) + { + return result; + } + + // + switch (value) + { + // + case XFIMA_PIVOT_NONE: + result = "NONE"; + break; + + // + case XFIMA_PIVOT_PV: + result = "XPV"; + break; + + // + case XFIMA_PIVOT_HK: + result = "XHK"; + break; + + // + case XFIMA_PIVOT_ZIGZAG: + result = "XZGP"; + break; + + // + case XFIMA_PIVOT_MA_CROSS: + result = "XMACRS"; + break; + + // + case XFIMA_PIVOT_HK_SWITCH: + result = "XHKSWCH"; + break; + + // + case XFIMA_PIVOT_SAR_SWITCH: + result = "XSARSWCH"; + break; + + // + case XFIMA_PIVOT_BOUNDARY_SWITCH: + result = "XBNDSWCH"; + break; + } + + // + return result; +} + +ENUM_XFIMA_PIVOTS ToXFIMAPivots(string value) +{ + // + ENUM_XFIMA_PIVOTS result = XFIMA_PIVOT_NONE; + + // + if (!IsXValid(value)) + { + return result; + } + + // + if (value == ToXString(XFIMA_PIVOT_NONE)) + { + result = XFIMA_PIVOT_NONE; + } + else if (value == ToXString(XFIMA_PIVOT_PV)) + { + result = XFIMA_PIVOT_PV; + } + else if (value == ToXString(XFIMA_PIVOT_HK)) + { + result = XFIMA_PIVOT_HK; + } + else if (value == ToXString(XFIMA_PIVOT_ZIGZAG)) + { + result = XFIMA_PIVOT_ZIGZAG; + } + else if (value == ToXString(XFIMA_PIVOT_MA_CROSS)) + { + result = XFIMA_PIVOT_MA_CROSS; + } + else if (value == ToXString(XFIMA_PIVOT_HK_SWITCH)) + { + result = XFIMA_PIVOT_HK_SWITCH; + } + else if (value == ToXString(XFIMA_PIVOT_SAR_SWITCH)) + { + result = XFIMA_PIVOT_SAR_SWITCH; + } + else if (value == ToXString(XFIMA_PIVOT_BOUNDARY_SWITCH)) + { + result = XFIMA_PIVOT_BOUNDARY_SWITCH; + } + + // + return result; +} + // // Buffers ... enum ENUM_XFIMA_BUFFERS @@ -1174,6 +1306,317 @@ class XCXFIMAHelper : public XCBaseHelper return result; } + /** + * Check Specified Bar Price is In Boundary or not ... + * + * @param priceType: ENUM_X_PRICE, Specified Price type of Bar ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsInBoundary( + ENUM_X_PRICE priceType = X_PRICE_CLOSE, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + if (!IsXValid(priceType)) + { + priceType = X_PRICE_CLOSE; + } + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Retrieve Bar ... + XOHCL bar; + result = bar.Init( + mSymbol, + mPeriod, + barIndex // + ); + if (!result) + { + // + bar.Clean(); + return result; + } + double value = bar.GetPrice(priceType); + + // + // Read Boundary Values ... + double min; + double max; + result = GetBoundaryValues(min, max, barIndex); + if (!result) + { + // + bar.Clean(); + return result; + } + + // + result = value < max && + value > min; + + // + // Cleanup Resources ... + bar.Clean(); + + // + return result; + } + + /** + * Check Specified Bar Price is Over Boundary Min ... + * + * @param priceType: ENUM_X_PRICE, Specified Price type of Bar ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsOverBoundaryMin( + ENUM_X_PRICE priceType = X_PRICE_CLOSE, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + if (!IsXValid(priceType)) + { + priceType = X_PRICE_CLOSE; + } + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Retrieve Boundary ... + double min; + double max; + result = GetBoundaryValues(min, max, barIndex); + if (!result) + { + return result; + } + + // + // Retrieve Bar .... + XOHCL bar; + result = bar.Init( + mSymbol, + mPeriod, + barIndex // + ); + if (!result) + { + // + bar.Clean(); + return result; + } + double value = bar.GetPrice(priceType); + + // + result = value > min; + + // + // Cleanup ... + bar.Clean(); + + // + return result; + } + + /** + * Check Specified Bar Price is Under Boundary Max ... + * + * @param priceType: ENUM_X_PRICE, Specified Price type of Bar ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsUnderBoundaryMax( + ENUM_X_PRICE priceType = X_PRICE_CLOSE, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + if (!IsXValid(priceType)) + { + priceType = X_PRICE_CLOSE; + } + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Retrieve Boundary ... + double min; + double max; + result = GetBoundaryValues(min, max, barIndex); + if (!result) + { + return result; + } + + // + // Retrieve Bar .... + XOHCL bar; + result = bar.Init( + mSymbol, + mPeriod, + barIndex // + ); + if (!result) + { + // + bar.Clean(); + return result; + } + double value = bar.GetPrice(priceType); + + // + result = value < max; + + // + // Cleanup ... + bar.Clean(); + + // + return result; + } + + /** + * Check Boundary Fake Breaked or not ... + * + * @param dir: reference for holds cross Direction ... + * @param barIndex: int, Specified Bar Index ... + * @param overMaxPriceType: ENUM_X_PRICE, which price of Specified bar to Check ... + * @param underMinPriceType: ENUM_X_PRICE, which price of Specified bar to Check ... + * + * @return ( bool ) + */ + bool IsBoundaryFakeBreaked( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + ENUM_X_PRICE overMaxPriceType = X_PRICE_NONE, + ENUM_X_PRICE underMinPriceType = X_PRICE_NONE // + ) + { + // + bool result = false; + + // + // Prepare ... + dir = X_DIRECTION_NONE; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + if (!IsXValid(overMaxPriceType)) + { + overMaxPriceType = X_PRICE_CLOSE; + } + if (!IsXValid(underMinPriceType)) + { + underMinPriceType = X_PRICE_CLOSE; + } + + // + // Initial Bars ... + XOHCL bar; + XOHCL pBar; + double min; + double max; + double pMin; + double pMax; + double boundaryValues[]; + result = + bar.Init( + mSymbol, + mPeriod, + barIndex // + ) && + bar.GetPreviousBar(pBar) && + GetBoundaryValues(min, max, barIndex) && + GetBoundaryValues(pMin, pMax, barIndex + 1) && + FillBoundaryValues(boundaryValues, barIndex) > 0; + + // + bool isBullish = + result && + pBar.IsBearish() && + bar.IsBullish() && + pBar.GetPrice(underMinPriceType) < pMin && + bar.GetPrice(underMinPriceType) > min && + (bar.GetPrice(underMinPriceType) > FindLesserThan(max, boundaryValues) || + bar.GetPrice(underMinPriceType) > FindBiggerThan(min + ((max - min) / 2), boundaryValues)); + + // + bool isBearish = + result && + pBar.IsBullish() && + bar.IsBearish() && + pBar.GetPrice(overMaxPriceType) > pMax && + bar.GetPrice(overMaxPriceType) < max && + (bar.GetPrice(overMaxPriceType) < FindBiggerThan(min, boundaryValues) || + bar.GetPrice(overMaxPriceType) < FindLesserThan(min + ((max - min) / 2), boundaryValues)); + + // + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Cleanup ... + bar.Clean(); + pBar.Clean(); + + // + return result; + } + /** * Check Specified Bar's Price in Hot Place or Not ... * @@ -1276,7 +1719,194 @@ class XCXFIMAHelper : public XCBaseHelper return result; } - bool ( + /** + * Check Specified Bar price Crossed in Boundary or not ... + * + * @param dir: ENUM_X_DIRECTION, reference to hold Crossed in Dir ... + * @param priceType: ENUM_X_PRICE, Specified Price type of Bar ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsCrossedInBoundary( + ENUM_X_DIRECTION &dir, + ENUM_X_PRICE priceType = X_PRICE_CLOSE, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Prepare ... + dir = X_DIRECTION_NONE; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + int pBarIndex = barIndex + 1; + + // + if (!IsXValid(priceType)) + { + priceType = X_PRICE_CLOSE; + } + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Check PrevBar Is in Hot Place ... + result = IsInHotPlace( + dir, + pBarIndex, + X_PRICE_LOW, + X_PRICE_HIGH // + ); + if (!result) + { + // + dir = X_DIRECTION_NONE; + + // + return result; + } + + // + bool isBullish = IsXBullish(dir); + bool isBearish = IsXBearish(dir); + + // + // Current Bar must Into Boundary ... + result = IsInBoundary(priceType, barIndex); + if (!result) + { + dir = X_DIRECTION_NONE; + } + + // + result = HasDirection(dir); + + // + return result; + } + + /** + * Check Specified Bar price Crossed out Boundary or not ... + * + * @param dir: ENUM_X_DIRECTION, reference to hold Crossed in Dir ... + * @param priceType: ENUM_X_PRICE, Specified Price type of Bar ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsCrossedOutBoundary( + ENUM_X_DIRECTION &dir, + ENUM_X_PRICE priceType = X_PRICE_CLOSE, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Prepare ... + dir = X_DIRECTION_NONE; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + int pBarIndex = barIndex + 1; + + // + if (!IsXValid(priceType)) + { + priceType = X_PRICE_CLOSE; + } + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Prev Bar Must in Boundary ... + bool isBullish = IsInBoundary(X_PRICE_LOW, pBarIndex); + bool isBearish = IsInBoundary(X_PRICE_HIGH, pBarIndex); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Current Bar must Out of Boundary ... + + XOHCL bar; + result = bar.Init( + mSymbol, + mPeriod, + barIndex // + ); + + // + isBullish = + result && + isBullish && + bar.IsBullish() && + !IsInBoundary(priceType, barIndex); + + // + isBearish = + result && + isBearish && + bar.IsBearish() && + !IsInBoundary(priceType, barIndex); + + // + result = isBullish || + isBearish; + if (!result) + { + // + bar.Clean(); + return result; + } + + // + dir = isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + result = HasDirection(dir); + + // + // Cleanup ... + bar.Clean(); + + // + return result; + } + + /** + * Check Specified Bar has Boundary Trend or not ... + * + * @param dir: reference for holds cross Direction ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool HasBoundaryTrend( ENUM_X_DIRECTION &dir, int barIndex = 0 // ) @@ -1363,6 +1993,14 @@ class XCXFIMAHelper : public XCBaseHelper return result; } + /** + * Check Specified Bar has Boundary Trend Switched or not ... + * + * @param dir: reference for holds cross Direction ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ bool HasBoundarySwitch( ENUM_X_DIRECTION &dir, int barIndex = 0 // @@ -1789,235 +2427,6 @@ class XCXFIMAHelper : public XCBaseHelper return result; } - /** - * Retrieve Fast, Slow, MA Bond Upper/Lower, HK Bond Upper/Lower and PB Bond Upper/Lower Min/Max ... - * - * @param min: double, minimum value ... - * @param max: double, maximum value ... - * @param barIndex: int, Specified Bar Index ... - * - * @return ( bool ) - */ - bool GetBoundaryValues( - double &min, - double &max, - int barIndex = 0, - bool containsFastSlow = true, - bool containsMABond = true, - bool containsHKBound = true, - bool containsPBBond = true, - bool containsFiboLevels = false // - ) - { - // - bool result = false; - - // - // Prepare ... - min = EMPTY_VALUE; - max = EMPTY_VALUE; - - // - // Normalize ... - barIndex = NormalizeBarIndex(barIndex); - - // - // Validate ... - result = IsValid(); - if (!result) - { - return result; - } - - // - double fast = GetMAFast(barIndex); - double slow = GetMASlow(barIndex); - - // - double maBondUpper = GetMABondUpper(barIndex); - double maBondLower = GetMABondLower(barIndex); - - // - double pbBondUpper = GetPBBondUpper(barIndex); - double pbBondLower = GetPBBondLower(barIndex); - - // - double hkBondUpper = GetHKBondUpper(barIndex); - double hkBondLower = GetHKBondLower(barIndex); - - // - double fiboUpper = GetFiboUpper(barIndex); - double fiboLower = GetFiboLower(barIndex); - double fiboMiddle = GetFiboMiddle(barIndex); - - // - result = - NotEmptyZero(fast) && - NotEmptyZero(slow) && - NotEmptyZero(fiboLower) && - NotEmptyZero(fiboUpper) && - NotEmptyZero(fiboMiddle) && - NotEmptyZero(maBondUpper) && - NotEmptyZero(maBondLower) && - NotEmptyZero(pbBondUpper) && - NotEmptyZero(pbBondLower) && - NotEmptyZero(hkBondUpper) && - NotEmptyZero(hkBondLower); - if (!result) - { - return result; - } - - // - double values[]; - - // - if (containsFastSlow) - { - // - Add(fast, values); - Add(slow, values); - } - - // - if (containsMABond) - { - // - Add(maBondUpper, values); - Add(maBondLower, values); - } - - // - if (containsHKBound) - { - // - Add(hkBondUpper, values); - Add(hkBondLower, values); - } - - // - if (containsPBBond) - { - // - Add(pbBondUpper, values); - Add(pbBondLower, values); - } - - // - if (containsFiboLevels) - { - // - Add(fiboLower, values); - Add(fiboUpper, values); - Add(fiboMiddle, values); - } - - // - result = HasChild(values); - if (!result) - { - return result; - } - - // - min = GetMin(values); - max = GetMax(values); - - // - result = - NotEmptyZero(min) && - NotEmptyZero(max) && - min < max; - - // - return result; - } - - // - // Tools ... - - /** - * Detect Last Fibo Section Changed till Loopback Length ... - * - * @param lastBarIndex: int, reference to hold Detected Bar Index ... - * @param dir: ENUM_X_DIRECTION, reference to detected Direction ... - * @param barIndex: int, Specified Bar Index ... - * @param maxAllowedLoopbackLength: int, Max Allowed Loopback Bars ... - * @param forDir: ENUM_X_DIRECTION, Specified Section Change Direction Looking for ... - * - * @return ( bool ) - */ - bool GetLastFiboSectionChanged( - int &lastBarIndex, - ENUM_X_DIRECTION &dir, - int barIndex = 0, - int maxAllowedLoopbackLength = 100, - ENUM_X_DIRECTION forDir = X_DIRECTION_NONE // - ) - { - // - bool result = false; - - // - // Prepare ... - lastBarIndex = -1; - dir = X_DIRECTION_NONE; - - // - // Normalize ... - barIndex = NormalizeBarIndex(barIndex); - maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); - - // - // Validate ... - result = IsValid(); - if (!result) - { - return result; - } - - // - int start = barIndex + 1; - int end = start + maxAllowedLoopbackLength; - for (int i = start; i < end; i++) - { - // - result = IsFiboSectionChanged(dir, i); - if (result) - { - // - // Validate By forDir ... - if (HasDirection(forDir)) - { - result = dir == forDir; - } - - // - if (!result) - { - // - lastBarIndex = -1; - dir = X_DIRECTION_NONE; - } - - // - if (result) - { - // - lastBarIndex = i; - break; - } - } - } - - // - result = HasDirection(dir) && - IsValidIndex(lastBarIndex); - - // - return result; - } - // // Extractions ... @@ -2188,6 +2597,9 @@ class XCXFIMAHelper : public XCBaseHelper ); if (has) { + // + iPivot.prefix = ToXString(XFIMA_PIVOT_PV); + // // Add Pivot to Collection only if not Exists ... AddIfNotExists( @@ -2279,6 +2691,9 @@ class XCXFIMAHelper : public XCBaseHelper ); if (has) { + // + iPivot.prefix = ToXString(XFIMA_PIVOT_PV); + // // Add Pivot to Collection only if not Exists ... AddIfNotExists( @@ -2501,6 +2916,9 @@ class XCXFIMAHelper : public XCBaseHelper ); if (has) { + // + iPivot.prefix = ToXString(XFIMA_PIVOT_MA_CROSS); + // // Add Pivot to Collection only if not Exists ... AddIfNotExists( @@ -2671,6 +3089,9 @@ class XCXFIMAHelper : public XCBaseHelper // if (has) { + // + iPivot.prefix = ToXString(XFIMA_PIVOT_HK); + // iPivotTime = GetBarTime( symbol, @@ -2881,9 +3302,6 @@ class XCXFIMAHelper : public XCBaseHelper has = has && HasDirection(iDir); - // - // TODO: we can also Add other Validations Here ... - // if (has) { @@ -2899,6 +3317,9 @@ class XCXFIMAHelper : public XCBaseHelper ); if (has) { + // + iPivot.prefix = ToXString(XFIMA_PIVOT_SAR_SWITCH); + // // Add Pivot to Collection only if not Exists ... AddIfNotExists( @@ -3095,6 +3516,9 @@ class XCXFIMAHelper : public XCBaseHelper ); if (has) { + // + iPivot.prefix = ToXString(XFIMA_PIVOT_ZIGZAG); + // // Add Pivot to Collection only if not Exists ... AddIfNotExists( @@ -3317,9 +3741,8 @@ class XCXFIMAHelper : public XCBaseHelper // zone.to = TimeCurrent(); - zone.type = "XHK_" + (IsXBullish(zone.dir) ? "Support" : IsXBearish(zone.dir) ? "Resistance" - : "") + - "_" + ToXString(TimeToSeconds(zone.from)); + zone.type = ToXString(XFIMA_PIVOT_HK) + "_" + (IsXBullish(zone.dir) ? "Support" : IsXBearish(zone.dir) ? "Resistance" + : ""); // // Validate ... @@ -3366,31 +3789,29 @@ class XCXFIMAHelper : public XCBaseHelper } // - // Detectors ... + // Values Retrievers ... /** - * Detect Zones (Support / Resistance) based on XFIMA Validators ... + * Filling Specified Bar index Boundary Values ... * - * @param zones: XBoxZone, reference to Collection for holding Detected Zones ... - * @param barIndex: int, Specified Start Looking Bar Index ... - * @param onlyValidZones: bool, Only Validation Zones ... - * @param requiredNumberOfZones: int, Specified how many zones looking for ... - * @param shadowMultiplier: double, a valid zone's Shadow side multiplier ... - * @param validationStrength: double, Validation Strength ... - * @param validationLength: int, Validation Length ... - * @param maxAllowedLoopbackLength: int, Specified Max Allowed Looping back trhough Bars for Detection ... + * @param dest: double, reference collection to hold boundary Values ... + * @param barIndex: int, Specified Bar's Index ... + * @param containsFastSlow: bool, Contains XMA Fast / Slow ... + * @param containsMABond: bool, Contains XMA Boundary Upper / Lower ... + * @param containsHKBound: bool, Contains XHK Boundary Upper / Lower ... + * @param containsPBBond: bool, Contains XPB Boundary Upper / Lower ... + * @param containsFiboLevels: nool, Contains XFIBO Levels ... * * @return ( int ) */ - int DetectXFIMAZones( - XBoxZone &zones[], + int FillBoundaryValues( + double &dest[], int barIndex = 0, - bool onlyValidZones = false, - int requiredNumberOfZones = 50, - double shadowMultiplier = 4, - double validationStrength = 1, - int validationLength = 7, - int maxAllowedLoopbackLength = 1500 // + bool containsFastSlow = true, + bool containsMABond = true, + bool containsHKBound = true, + bool containsPBBond = true, + bool containsFiboLevels = false // ) { // @@ -3398,1195 +3819,262 @@ class XCXFIMAHelper : public XCBaseHelper // // Prepare ... - XClean(zones); + XClean(dest); // // Normalize ... barIndex = NormalizeBarIndex(barIndex); - validationLength = NormalizeInt(validationLength, 3); - shadowMultiplier = NormalizeDouble(shadowMultiplier, 2); - validationStrength = NormalizeDouble(validationStrength, 1); - requiredNumberOfZones = NormalizeInt(requiredNumberOfZones, 5); - maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); // // Validate ... - XOHCL bar; - bool has = IsValid() && - bar.Init( - mSymbol, - mPeriod, - barIndex + 1 // - ); + bool has = IsValid(); if (!has) { return result; } // - // Define Requirements ... - XOHCL iBar; - XBoxZone iBox; - bool isBullish = false; - bool isBearish = false; - double iUpper = EMPTY_VALUE; - double iLower = EMPTY_VALUE; - double iHKUpper = EMPTY_VALUE; - double iHKLower = EMPTY_VALUE; - double iMAUpper = EMPTY_VALUE; - double iMALower = EMPTY_VALUE; - ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + // Read and Validate Values ... // - // Create a Loop to Detect Zones ... - int start = barIndex; - int idx = start - 1; - int end = start + maxAllowedLoopbackLength; - while (ArraySize(zones) < requiredNumberOfZones && idx < end) + double fast = GetMAFast(barIndex); + double slow = GetMASlow(barIndex); + + // + double maBondUpper = GetMABondUpper(barIndex); + double maBondLower = GetMABondLower(barIndex); + + // + double pbBondUpper = GetPBBondUpper(barIndex); + double pbBondLower = GetPBBondLower(barIndex); + + // + double hkBondUpper = GetHKBondUpper(barIndex); + double hkBondLower = GetHKBondLower(barIndex); + + // + double fiboUpper = GetFiboUpper(barIndex); + double fiboLower = GetFiboLower(barIndex); + double fiboMiddle = GetFiboMiddle(barIndex); + + // + has = + NotEmptyZero(fast) && + NotEmptyZero(slow) && + NotEmptyZero(fiboLower) && + NotEmptyZero(fiboUpper) && + NotEmptyZero(fiboMiddle) && + NotEmptyZero(maBondUpper) && + NotEmptyZero(maBondLower) && + NotEmptyZero(pbBondUpper) && + NotEmptyZero(pbBondLower) && + NotEmptyZero(hkBondUpper) && + NotEmptyZero(hkBondLower); + if (!has) { - // - idx++; - - // - // Initialize Indexed Bar ... - has = bar.BarAt(idx, iBar); - if (!has) - { - continue; - } - - // - // Reading Bars ... - iMAUpper = GetMABondUpper(idx); - iMALower = GetMABondLower(idx); - iHKUpper = GetHKBondUpper(idx); - iHKLower = GetHKBondLower(idx); - - // - iUpper = MathMax(iMAUpper, iHKUpper); - iLower = MathMin(iMALower, iHKLower); - - // - // Check Bar State ... - has = - NotEmptyZero(iUpper) && - NotEmptyZero(iLower); - if (!has) - { - continue; - } - - // - // Check Direction of Zone ... - isBullish = iBar.low < iLower; - isBearish = iBar.high > iUpper; - has = (isBullish && !isBearish) || - (isBearish && !isBullish); - if (!has) - { - continue; - } - - // - // Validate Price Based on Bar ... - // Validate Shadow Multiplier ... - has = - isBullish - ? iBar.low < bar.low - : iBar.high > bar.high; - has = - has && - (isBullish - ? iBar.GetLowShadow() > iBar.GetHighShadow() * shadowMultiplier - : iBar.GetHighShadow() > iBar.GetLowShadow() * shadowMultiplier); - if (!has) - { - continue; - } - - // - iDir = isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - - // - // Fill Bax ... - iBox.dir = iDir; - iBox.symbol = mSymbol; - iBox.period = mPeriod; - iBox.upper = - isBullish - ? iBar.GetDown() - : iBar.high; - iBox.lower = - isBullish - ? iBar.low - : iBar.GetUp(); - iBox.type = - (isBullish ? "XFIMA_Support" : "XFIMA_Resistance") + "_" + - ToXString(NormalizePrice(iBox.upper, iBox.symbol)) + "_" + - ToXString(NormalizePrice(iBox.lower, iBox.symbol)); - - // - iBox.at = iBar.time; - iBox.to = bar.time; - - // - // Loopback to Detect From Time ... - XOHCL pBar; - datetime fromTime = NULL; - has = iBar.GetPreviousBar(pBar); - if (has) - { - // - while (!IsXValid(fromTime)) - { - // - // Check Price Inside ... - has = - isBullish - ? pBar.GetDown() < iBox.lower - : pBar.GetUp() > iBox.upper; - if (has) - { - fromTime = pBar.time; - } - - // - // Retrieve PrevBar ... - has = pBar.GetPreviousBar(pBar); - if (!has) - { - break; - } - } - } - has = IsXValid(fromTime); - if (has) - { - iBox.from = fromTime; - } - - // - // Validate Zone Length ... - has = iBox.IsValid() && - (validationStrength >= 1 - ? iBox.GetRange() >= validationStrength * GetPoints(iBox.symbol) - : true) && - (iBox.FromIndex() - iBox.AtIndex() >= validationLength); - - // - // Validate Zone State ... - if (has) - { - // - // Cleanup Bar ... - iBar.Clean(); - - // - // Loopingh through At Index ... - for (int i = iBox.ToIndex(); i < iBox.AtIndex(); i++) - { - // - // Initialized Indexed Bar ... - has = bar.BarAt(i, iBar); - if (!has) - { - break; - } - - // - // Validate Bar ... - has = - iBox.IsBullish() - ? iBar.low > iBox.lower - : iBar.high < iBox.upper; - if (!has) - { - break; - } - } - } - - // - if (has) - { - // - AddIfNotExists( - iBox, - zones // - ); - } - - // - // Cleanup Resources ... - iBar.Clean(); - pBar.Clean(); - iBox.Clean(); + return result; } // - result = ArraySize(zones); + // Fill Dest ... // - // Cleanup Resources ... + // XMA Fast / Slow ... + if (containsFastSlow) + { + // + Add(fast, dest); + Add(slow, dest); + } + + // + // XMA Bound ... + if (containsMABond) + { + // + Add(maBondUpper, dest); + Add(maBondLower, dest); + } + + // + // XHK Bond ... + if (containsHKBound) + { + // + Add(hkBondUpper, dest); + Add(hkBondLower, dest); + } + + // + // XPB Bond ... + if (containsPBBond) + { + // + Add(pbBondUpper, dest); + Add(pbBondLower, dest); + } + + // + // XFIBO Zones ... + if (containsFiboLevels) + { + // + Add(fiboLower, dest); + Add(fiboUpper, dest); + Add(fiboMiddle, dest); + } + + // + result = ArraySize(dest); + + // + return result; + } + + /** + * Retrieve Fast, Slow, MA Bond Upper/Lower, HK Bond Upper/Lower and PB Bond Upper/Lower Min/Max ... + * + * @param min: double, minimum value ... + * @param max: double, maximum value ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool GetBoundaryValues( + double &min, + double &max, + int barIndex = 0, + bool containsFastSlow = true, + bool containsMABond = true, + bool containsHKBound = true, + bool containsPBBond = true, + bool containsFiboLevels = false // + ) + { + // + bool result = false; + + // + // Prepare ... + min = EMPTY_VALUE; + max = EMPTY_VALUE; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); if (!result) { - XClean(zones); + return result; } - bar.Clean(); - iBar.Clean(); - iBox.Clean(); + + // + double fast = GetMAFast(barIndex); + double slow = GetMASlow(barIndex); + + // + double maBondUpper = GetMABondUpper(barIndex); + double maBondLower = GetMABondLower(barIndex); + + // + double pbBondUpper = GetPBBondUpper(barIndex); + double pbBondLower = GetPBBondLower(barIndex); + + // + double hkBondUpper = GetHKBondUpper(barIndex); + double hkBondLower = GetHKBondLower(barIndex); + + // + double fiboUpper = GetFiboUpper(barIndex); + double fiboLower = GetFiboLower(barIndex); + double fiboMiddle = GetFiboMiddle(barIndex); + + // + result = + NotEmptyZero(fast) && + NotEmptyZero(slow) && + NotEmptyZero(fiboLower) && + NotEmptyZero(fiboUpper) && + NotEmptyZero(fiboMiddle) && + NotEmptyZero(maBondUpper) && + NotEmptyZero(maBondLower) && + NotEmptyZero(pbBondUpper) && + NotEmptyZero(pbBondLower) && + NotEmptyZero(hkBondUpper) && + NotEmptyZero(hkBondLower); + if (!result) + { + return result; + } + + // + double values[]; + + // + if (containsFastSlow) + { + // + Add(fast, values); + Add(slow, values); + } + + // + if (containsMABond) + { + // + Add(maBondUpper, values); + Add(maBondLower, values); + } + + // + if (containsHKBound) + { + // + Add(hkBondUpper, values); + Add(hkBondLower, values); + } + + // + if (containsPBBond) + { + // + Add(pbBondUpper, values); + Add(pbBondLower, values); + } + + // + if (containsFiboLevels) + { + // + Add(fiboLower, values); + Add(fiboUpper, values); + Add(fiboMiddle, values); + } + + // + result = HasChild(values); + if (!result) + { + return result; + } + + // + min = GetMin(values); + max = GetMax(values); + + // + result = + NotEmptyZero(min) && + NotEmptyZero(max) && + min < max; // return result; } - int DetecteXFIMAPivots( - XPivot &pivots[], - int barIndex = 0, - int requiredNumberOfPivots = 50, - int validationLength = 7, - int maxAllowedLoopbackLength = 1500, // - // - // PV ... - int pvValidationLength = 7, - // - // Momentum ... - int momentumBarValidationLength = 3, - double momentumBarApprovedMultiplier = 3, - // - // TrueGap ... - double trueGapApprovedStrength = 2, - // - // Pin ... - double pinBarShadowApprovedMultiplier = 3, - double pinBarRangeMultiplier = 4, - bool pinBarForceDirection = false, - // - // Flag ... - int flagPatternPullbackLength = 3 // - ) - { - // - int result = 0; - - // - // Prepare ... - XClean(pivots); - - // - // Normalize ... - barIndex = NormalizeBarIndex(barIndex); - validationLength = NormalizeInt(validationLength, 1); - requiredNumberOfPivots = NormalizeInt(requiredNumberOfPivots, 5); - maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); - - // - pvValidationLength = NormalizeInt(pvValidationLength, 0); - - // - momentumBarValidationLength = NormalizeInt(momentumBarValidationLength, 2); - momentumBarApprovedMultiplier = NormalizeDouble(momentumBarApprovedMultiplier, 1); - - // - trueGapApprovedStrength = NormalizeDouble(trueGapApprovedStrength, 1); - - // - pinBarRangeMultiplier = NormalizeDouble(pinBarRangeMultiplier, 4); - pinBarShadowApprovedMultiplier = NormalizeDouble(pinBarShadowApprovedMultiplier, 3); - - // - flagPatternPullbackLength = NormalizeInt(flagPatternPullbackLength, 3); - - // - // Validate ... - bool has = IsValid(); - if (!has) - { - return result; - } - - // - XOHCL iBar; - XOHCL tmpBar; - XPivot iPivot; - int count = 0; - string iPrefix = NULL; - int idx = barIndex - 1; - double iMin = EMPTY_VALUE; - double iMax = EMPTY_VALUE; - double iValue = EMPTY_VALUE; - ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; - ENUM_X_DIRECTION tmpDir = X_DIRECTION_NONE; - ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; - int end = barIndex + maxAllowedLoopbackLength; - while ( - idx < end && - ArraySize(pivots) < requiredNumberOfPivots) - { - // - idx++; - - // - iBar.Clean(); - iPivot.Clean(); - tmpBar.Clean(); - iPrefix = NULL; - iDir = X_DIRECTION_NONE; - - // - has = iBar.Init( - mSymbol, - mPeriod, - idx // - ); - if (!has) - { - break; - } - - // - // Pivots List ... - - // - // PV ... - bool isPV = false; - bool isPeak = false; - bool isVale = false; - tmpDir = X_DIRECTION_NONE; - if (pvValidationLength > 0) - { - // - isPV = patternDetector.IsPV( - iBar, - tmpDir, - pvValidationLength // - ); - isPeak = isPV && - IsXBearish(tmpDir); - isVale = isPV && - IsXBullish(tmpDir); - if (isPV) - { - iPrefix += isPeak ? "XPK" : "XVL"; - } - - // - // Continue Loopback if PV Validation Provided and not isPV ... - if (!isPV) - { - continue; - } - } - - // - // Momentum Bar ... - bool isMomentum = patternDetector.IsMomentumBar( - iBar, - iDir, - momentumBarValidationLength, - momentumBarApprovedMultiplier // - ); - if (isMomentum) - { - // - if (!IsXValid(tmpDir)) - { - tmpDir = iDir; - } - - // - if (iDir != tmpDir) - { - isMomentum = false; - } - else - { - // - count++; - iPrefix += (IsXValid(iPrefix) ? "_" : "") + "MNTM"; - } - } - - // - // Engulf Bar ... - bool isEngulfed = patternDetector.IsEngulfedBar( - iBar, - iDir // - ); - if (isEngulfed) - { - // - if (!IsXValid(tmpDir)) - { - tmpDir = iDir; - } - - // - if (iDir != tmpDir) - { - isEngulfed = false; - } - else - { - // - count++; - iPrefix += (IsXValid(iPrefix) ? "_" : "") + "ENGLF"; - } - } - - // - // True Gap ... - bool isTrueGaped = patternDetector.IsTrueGapedBar( - iBar, - iDir, - trueGapApprovedStrength // - ); - if (isTrueGaped) - { - // - if (!IsXValid(tmpDir)) - { - tmpDir = iDir; - } - - // - if (iDir != tmpDir) - { - isTrueGaped = false; - } - else - { - // - count++; - iPrefix += (IsXValid(iPrefix) ? "_" : "") + "TG"; - } - } - - // - // Pin Bar ... - bool isPinned = patternDetector.IsPinnedBar( - iBar, - iDir, - pinBarShadowApprovedMultiplier, - pinBarRangeMultiplier, - pinBarForceDirection // - ); - if (isPinned) - { - // - if (!IsXValid(tmpDir)) - { - tmpDir = iDir; - } - - // - if (iDir != tmpDir) - { - isPinned = false; - } - else - { - // - count++; - iPrefix += (IsXValid(iPrefix) ? "_" : "") + "PND"; - } - } - - // - // Patterns ... - - // - // Star Pattern ... - bool isStarPattern = patternDetector.IsStarPattern( - iBar, - iDir // - ); - if (isStarPattern) - { - // - if (!IsXValid(tmpDir)) - { - tmpDir = iDir; - } - - // - if (iDir != tmpDir) - { - isStarPattern = false; - } - else - { - // - count++; - iPrefix += (IsXValid(iPrefix) ? "_" : "") + "STR"; - } - } - - // - // Piercing Pattern ... - bool isPiercingPattern = patternDetector.IsPiercingPattern( - iBar, - iDir // - ); - if (isPiercingPattern) - { - // - if (!IsXValid(tmpDir)) - { - tmpDir = iDir; - } - - // - if (iDir != tmpDir) - { - isPiercingPattern = false; - } - else - { - // - count++; - iPrefix += (IsXValid(iPrefix) ? "_" : "") + "PRCG"; - } - } - - // - // Rising Pattern ... - bool isRisingPattern = patternDetector.IsRisingPattern( - iBar, - iDir // - ); - if (isRisingPattern) - { - // - if (!IsXValid(tmpDir)) - { - tmpDir = iDir; - } - - // - if (iDir != tmpDir) - { - isRisingPattern = false; - } - else - { - // - count++; - iPrefix += (IsXValid(iPrefix) ? "_" : "") + "RSG"; - } - } - - // - // Flag Pattern ... - bool isFlagPattern = patternDetector.IsFlagPattern( - iBar, - iDir, - tmpBar, - flagPatternPullbackLength // - ); - if (isFlagPattern) - { - // - if (!IsXValid(tmpDir)) - { - tmpDir = iDir; - } - - // - if (iDir != tmpDir) - { - isFlagPattern = false; - } - else - { - // - count++; - iPrefix += (IsXValid(iPrefix) ? "_" : "") + "FLG"; - } - } - - // - // Signal Key Pattern ... - bool isSignalKeyPattern = patternDetector.IsSignalKeyBarPattern( - iBar, - iDir, - pinBarShadowApprovedMultiplier, - pinBarRangeMultiplier, - pinBarForceDirection // - ); - if (isSignalKeyPattern) - { - // - if (!IsXValid(tmpDir)) - { - tmpDir = iDir; - } - - // - if (iDir != tmpDir) - { - isSignalKeyPattern = false; - } - else - { - // - count++; - iPrefix += (IsXValid(iPrefix) ? "_" : "") + "SKB"; - } - } - - // - has = - isPinned || - isMomentum || - isEngulfed || - isTrueGaped || - isStarPattern || - isFlagPattern || - isRisingPattern || - isPiercingPattern || - isSignalKeyPattern; - if (!has) - { - continue; - } - - // // - // // Validate Pivot Length ... - // // Validate Pivot vs XFIMA Values ... - // for (int i = iBar.Index(); i < iBar.Index() + validationLength; i++) - // { - // // - // tmpBar.Clean(); - // has = iBar.BarAt(i, tmpBar); - // if (!has) - // { - // break; - // } - - // // - // iMin = EMPTY_VALUE; - // iMax = EMPTY_VALUE; - // has = GetBoundaryValues( - // iMin, - // iMax, - // i // - // ); - - // // - // // Validate Bar vs TmpBar and Also Boundary Values ... - // has = - // has && - // (IsXBullish(iDir) - // ? - // // tmpBar.low < iMin && - // (tmpBar.low > iBar.low || - // tmpBar.GetDown() || iBar.GetDown()) - // : - // // tmpBar.high > iMax && - // (tmpBar.high < iBar.high || - // tmpBar.GetUp() < iBar.GetUp())); - // if (!has) - // { - // break; - // } - - // // - // iValue = IsXBullish(iDir) - // ? iBar.low - // : iBar.high; - - // // - // iType = IsXBullish(iDir) - // ? X_PIVOT_TYPE_VALE - // : X_PIVOT_TYPE_PEAK; - - // // - // tmpBar.Clean(); - // } - - // - has = IsXValid(iPrefix); - if (has) - { - // - iValue = IsXBullish(iDir) - ? iBar.low - : iBar.high; - - // - iType = IsXBullish(iDir) - ? X_PIVOT_TYPE_VALE - : X_PIVOT_TYPE_PEAK; - - // - // Preparing Pivot ... - has = iPivot.Init( - iValue, - iBar.time, - iBar.symbol, - iDir, - iBar.period, - iType // - ); - if (has) - { - // - iPivot.prefix = iPrefix; - - // - AddIfNotExists( - iPivot, - pivots // - ); - } - } - - // - } - - // - // Cleanup Resources ... - iBar.Clean(); - iPivot.Clean(); - tmpBar.Clean(); - - // - result = ArraySize(pivots); - - // - return result; - } - - /** - * Detect XFIMA Based POI Bars ... - * - * @param bars: XOHCL, reference collection to holds detected bars ... - * @param dirs: ENUM_X_DIRECTION, reference collection to holds detected bars Direction ... - * @param barIndex: int, Specified Bar Index ... - * @param forDir: ENUM_X_DIRECTION, specified which Direction of potential bars looking for ... - * @param requiredNumberOfBars: int, Specified how many bars looking for ... - * @param maxAllowedLoopbackLength: int, Specified Max Allowed Looping back trhough Bars for Detection ... - * @return ( int ) - */ - int DetectXFIMAPOIBars( - XOHCL &bars[], - ENUM_X_DIRECTION &dirs[], - int barIndex = 0, - ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, - int requiredNumberOfBars = 300, - int maxAllowedLoopbackLength = 1500 // - ) - { - // - int result = 0; - - // - // Prepare ... - XClean(bars); - XClean(dirs); - - // - // Normalize ... - barIndex = NormalizeBarIndex(barIndex); - requiredNumberOfBars = NormalizeInt(requiredNumberOfBars, 5); - maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); - - // - // Validate ... - bool has = IsValid(); - if (!has) - { - return result; - } - - // - XOHCL iBar; - int idx = barIndex - 1; - int start = barIndex; - bool isBullish = false; - bool isBearish = false; - double iMin = EMPTY_VALUE; - double iMax = EMPTY_VALUE; - ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; - int end = start + maxAllowedLoopbackLength; - while (ArraySize(bars) < requiredNumberOfBars || - idx < maxAllowedLoopbackLength) - { - // - idx++; - has = iBar.Init( - mSymbol, - mPeriod, - idx // - ); - if (!has) - { - continue; - } - - // - has = GetBoundaryValues( - iMin, - iMax, - idx // - ); - if (!has) - { - continue; - } - - // - isBullish = iBar.low < iMin; - isBearish = iBar.high > iMax; - has = - !HasDirection(forDir) - ? ((isBullish && !isBearish) || - (isBearish && !isBullish)) - : IsXBullish(forDir) - ? (isBullish && !isBearish) - : (isBearish && !isBullish); - if (has) - { - // - iDir = isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - - // - AddRef( - iBar, - bars // - ); - - // - Add( - iDir, - dirs // - ); - } - } - - // - result = ArraySize(bars); - - // - // Cleanup Resources ... - iBar.Clean(); - - // - return result; - } - - int DetectXFIMAReversalPOIBars( - XOHCL &bars[], - ENUM_X_DIRECTION &dirs[], - int barIndex = 0, - bool forceTouchBoundary = false, - ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, - int requiredNumberOfBars = 300, - int maxAllowedLoopbackLength = 1500 // - ) - { - // - int result = 0; - - // - // Prepare ... - XClean(bars); - XClean(dirs); - - // - // Normalize ... - barIndex = NormalizeBarIndex(barIndex); - requiredNumberOfBars = NormalizeInt(requiredNumberOfBars, 5); - maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); - - // - // Validate ... - bool has = IsValid(); - if (!has) - { - return result; - } - - // - // Detect POI Bars ... - XOHCL decisionBars[]; - ENUM_X_DIRECTION decisionBarDirs[]; - int decisionBarsCount = DetectXFIMAPOIBars( - decisionBars, - decisionBarDirs, - barIndex, - forDir, - requiredNumberOfBars, - maxAllowedLoopbackLength // - ); - has = IsValidSize(decisionBarsCount); - if (!has) - { - // - XClean(decisionBars); - XClean(decisionBarDirs); - - // - return result; - } - - // - bool isBullish = false; - bool isBearish = false; - double iMin = EMPTY_VALUE; - double iMax = EMPTY_VALUE; - bool isCond1Bullish = false; - bool isCond1Bearish = false; - for (int i = 0; i < decisionBarsCount; i++) - { - // - // Read Boundary Values ... - has = GetBoundaryValues(iMin, iMax, i); - if (!has) - { - continue; - } - - // - // Check Bar Decision Direction ... - isBullish = IsXBullish(decisionBarDirs[i]); - isBearish = IsXBearish(decisionBarDirs[i]); - - // - // Validate ... - - // - isCond1Bullish = decisionBars[i].IsBullish(); - - // - isCond1Bearish = decisionBars[i].IsBearish(); - - // - isBullish = - isBullish && - (isCond1Bullish); - - // - isBearish = - isBearish && - (isCond1Bearish); - - // - if (forceTouchBoundary) - { - // - isBullish = - isBullish && - (decisionBars[i].high > iMin || - decisionBars[i].GetUp() > iMin); - - // - isBearish = - isBearish && - (decisionBars[i].low < iMax || - decisionBars[i].GetDown() < iMax); - } - - // - has = - isBullish || - isBearish; - if (has) - { - // - AddRef( - decisionBars[i], - bars // - ); - - // - Add( - decisionBarDirs[i], - dirs // - ); - } - } - - // - result = ArraySize(bars); - - // - // Cleanup Resources ... - XClean(decisionBars); - XClean(decisionBarDirs); - - // - return result; - } - - int DetectXFIMAContinuationalPOIBars( - XOHCL &bars[], - ENUM_X_DIRECTION &dirs[], - int barIndex = 0, - bool forceTouchBoundary = false, - ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, - int requiredNumberOfBars = 300, - int maxAllowedLoopbackLength = 1500 // - ) - { - // - int result = 0; - - // - // Prepare ... - XClean(bars); - XClean(dirs); - - // - // Normalize ... - barIndex = NormalizeBarIndex(barIndex); - requiredNumberOfBars = NormalizeInt(requiredNumberOfBars, 5); - maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); - - // - // Validate ... - bool has = IsValid(); - if (!has) - { - return result; - } - - // - // Detect POI Bars ... - XOHCL decisionBars[]; - ENUM_X_DIRECTION decisionBarDirs[]; - int decisionBarsCount = DetectXFIMAPOIBars( - decisionBars, - decisionBarDirs, - barIndex, - forDir, - requiredNumberOfBars, - maxAllowedLoopbackLength // - ); - has = IsValidSize(decisionBarsCount); - if (!has) - { - // - XClean(decisionBars); - XClean(decisionBarDirs); - - // - return result; - } - - // - bool isBullish = false; - bool isBearish = false; - double iMin = EMPTY_VALUE; - double iMax = EMPTY_VALUE; - bool isCond1Bullish = false; - bool isCond1Bearish = false; - for (int i = 0; i < decisionBarsCount; i++) - { - // - // Read Indexed Bars Boundaries ... - has = GetBoundaryValues(iMin, iMax, decisionBars[i].Index()); - if (!has) - { - continue; - } - - // - // Make Direction Opposit ... - decisionBarDirs[i] = Opposit(decisionBarDirs[i]); - - // - isBullish = IsXBullish(decisionBarDirs[i]); - isBearish = IsXBearish(decisionBarDirs[i]); - - // - // Check Bar Validations ... - - // - // Cond 1 ... - - // - isCond1Bullish = - decisionBars[i].IsBearish() && - (decisionBars[i].low >= iMax || - (decisionBars[i].low <= iMax && - decisionBars[i].GetUp() >= iMax)); - - // - isCond1Bearish = - decisionBars[i].IsBullish() && - (decisionBars[i].high <= iMin || - (decisionBars[i].high >= iMin && - decisionBars[i].GetDown() <= iMin)); - - // - isBullish = - isBullish && - (isCond1Bullish); - - // - isBearish = - isBearish && - (isCond1Bearish); - - // - if (forceTouchBoundary) - { - // - isBullish = - isBullish && - (decisionBars[i].low >= iMax || - (decisionBars[i].low <= iMax && - decisionBars[i].GetUp() >= iMax)); - - // - isBearish = - isBearish && - (decisionBars[i].high <= iMin || - (decisionBars[i].high >= iMin && - decisionBars[i].GetDown() <= iMin)); - } - - // - has = - isBullish || - isBearish; - if (has) - { - // - AddRef( - decisionBars[i], - bars // - ); - - // - Add( - decisionBarDirs[i], - dirs // - ); - } - } - - // - result = MathMin(ArraySize(bars), ArraySize(dirs)); - - // - // Cleanup Resources ... - XClean(decisionBars); - XClean(decisionBarDirs); - - // - return result; - } - - // - // Values Retrievers ... - // // Fast MA ... diff --git a/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 b/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 index 6b7a3b3f..10b0b52c 100644 --- a/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 +++ b/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 @@ -2557,36 +2557,131 @@ struct XPatternAnalysisConfig // }; +// +// Anaysis Draw Config Models ... + +struct XPivotAnalysisDrawConfig +{ + // + // Props ... + + // + // Drawing Flags ... + bool drawSupport; + bool drawResistance; + + // + bool drawPeakTrend; + bool drawValeTrend; + bool rayLeftTrends; + bool rayRightTrends; + + // + bool drawPivots; + + // + // Drawing Configs ... + XPOIDrawConfig drawConfig; + + // + // Constructor ... + XPivotAnalysisDrawConfig() + { + Clean(); + } + + // + // Tools ... + + /** + * This function fulfills the will of the developer + */ + void Clean() + { + // + // Drawing Flags ... + + // + drawPivots = false; + drawSupport = false; + drawPeakTrend = false; + drawValeTrend = false; + rayLeftTrends = false; + rayRightTrends = false; + drawResistance = false; + + // + // Drawing Configs ... + drawConfig.Clean(); + + // + ZeroMemory(this); + } + + /** + * Default Configurations ... + */ + void Default() + { + // + // Drawing Flags ... + + // + drawPivots = false; + drawSupport = true; + drawPeakTrend = false; + drawValeTrend = false; + rayLeftTrends = true; + rayRightTrends = true; + drawResistance = true; + + // + // Drawing Configs ... + drawConfig.Default(); + } + + /** + * No Draw Abilioty ... + */ + void Off() + { + // + drawPivots = false; + drawSupport = false; + drawPeakTrend = false; + drawValeTrend = false; + drawResistance = false; + } + + /** + * Full Draw Abilioty ... + */ + void Full() + { + // + drawPivots = true; + drawSupport = true; + drawPeakTrend = true; + drawValeTrend = true; + drawResistance = true; + } + + // +}; + struct XPatternAnalysisDrawConfig { // // Props ... - // - int zonesWidth; - bool fillZones; - int arrowsWidth; - bool ignoreZonesAt; - int arrowsThreshold; - ENUM_LINE_STYLE zonesStyle; - - // - int bullishArrow; - int bearishArrow; - - // - color bullishColor; - color bearishColor; - - // - ENUM_X_PRICE arrowValePriceType; - ENUM_X_PRICE arrowPeakPriceType; - // ENUM_X_BAR_PATTERN allowedDraws[]; // Allowed Draw Patterns ENUM_X_BAR_PATTERN allowedDrawZones[]; // Allowed Draw Pattern Zones ENUM_X_BAR_PATTERN allowedDrawPivots[]; // Allowed Draw Pattern Pivots + // + XPOIDrawConfig drawConfig; + // // Constructor ... XPatternAnalysisDrawConfig() @@ -2603,18 +2698,8 @@ struct XPatternAnalysisDrawConfig void Clean() { // - arrowsWidth = 0; - zonesWidth = 0; - bullishArrow = 0; - bearishArrow = 0; - fillZones = false; - arrowsThreshold = 0; - ignoreZonesAt = false; - bullishColor = CLR_NONE; - bearishColor = CLR_NONE; - zonesStyle = STYLE_SOLID; - arrowValePriceType = X_PRICE_NONE; - arrowPeakPriceType = X_PRICE_NONE; + // Drawing Configs ... + drawConfig.Clean(); // XClean(allowedDraws); @@ -2628,18 +2713,8 @@ struct XPatternAnalysisDrawConfig void Default() { // - zonesWidth = 1; - arrowsWidth = 1; - arrowsThreshold = 2; - bullishArrow = 159; - bearishArrow = 159; - fillZones = false; - ignoreZonesAt = true; - bullishColor = clrAqua; - zonesStyle = STYLE_SOLID; - bearishColor = clrMagenta; - arrowValePriceType = X_PRICE_LOW; - arrowPeakPriceType = X_PRICE_HIGH; + // Drawing Configs ... + drawConfig.Default(); // FullDraw(); diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 82c8f707..3261e114 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -254,9 +254,9 @@ ENUM_X_BAR_PATTERN ToBarPattern(string value) /** * Get All Available Valid Bar Patterns ... - * + * * @param dest: ENUM_X_BAR_PATTERN, reference collection to fill ... - * + * * @return ( int ) */ int GetAllBarPatters(ENUM_X_BAR_PATTERN &dest[]) @@ -1570,4 +1570,88 @@ struct XDirectionShift } }; +struct XPOIDrawConfig +{ + // + // Props ... + + // + color bullishColor; + color bearishColor; + + // + int arrowsWidth; + int bullishArrow; + int bearishArrow; + int arrowsThreshold; + ENUM_X_PRICE arrowsValePriceType; + ENUM_X_PRICE arrowsPeakPriceType; + + // + int zonesWidth; + bool zonesFill; + bool ignoreZonesAt; + ENUM_LINE_STYLE zonesStyle; + + // + // Constructor ... + XPOIDrawConfig() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + bullishColor = CLR_NONE; + bearishColor = CLR_NONE; + + // + arrowsWidth = 0; + bullishArrow = 0; + bearishArrow = 0; + arrowsThreshold = 0; + arrowsValePriceType = X_PRICE_NONE; + arrowsPeakPriceType = X_PRICE_NONE; + + // + zonesWidth = 1; + zonesFill = false; + ignoreZonesAt = true; + zonesStyle = STYLE_SOLID; + } + + /** + * Default Config ... + */ + void Default() + { + // + bullishColor = clrAqua; + bearishColor = clrMagenta; + + // + arrowsWidth = 1; + bullishArrow = 159; + bearishArrow = 159; + arrowsThreshold = 5; + arrowsValePriceType = X_PRICE_LOW; + arrowsPeakPriceType = X_PRICE_HIGH; + + // + zonesWidth = 1; + zonesFill = true; + ignoreZonesAt = true; + zonesStyle = STYLE_SOLID; + } + + // +}; + // \ No newline at end of file diff --git a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 index bd25e1d7..19cc4a73 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 @@ -41,14 +41,13 @@ class XCXFIMABaseSignaller : public XCBaseSignaller // Props ... // - bool ignoreTargets; // Ignore Signal Targets ... - CArrayObj drawnObjects; // Drawing Objects Holder ... - XFIMAInputs fimaInputs; // XFIMA Inputs ... - XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ... - XCXFIMAPOIDrawer *poiDrawer; // XFIMA POI Drawer ... - XCXFIMAPOIDetector *poiDetector; // XFIMA POI Detector ... - XPatternAnalysisConfig patternAnalyserConfig; // Bar Pattern Analyser Config ... - XPatternAnalysisDrawConfig patternAnalyserDrawConfig; // Bar Pattern Analysis Drawer Config ... + bool ignoreTargets; // Ignore Signal Targets ... + CArrayObj drawnObjects; // Drawing Objects Holder ... + XFIMAInputs fimaInputs; // XFIMA Inputs ... + XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ... + XCXFIMAPOIDrawer *poiDrawer; // XFIMA POI Drawer ... + XCXFIMAPOIDetector *poiDetector; // XFIMA POI Detector ... + XPatternAnalysisConfig patternAnalyserConfig; // Bar Pattern Analyser Config ... // // Constructor ... @@ -104,11 +103,6 @@ class XCXFIMABaseSignaller : public XCBaseSignaller patternAnalyserConfig.Clean(); patternAnalyserConfig.Default(); patternAnalyserConfig.FullPattern(); - - // - patternAnalyserDrawConfig.Clean(); - patternAnalyserDrawConfig.Default(); - patternAnalyserDrawConfig.FullDraw(); } // @@ -150,7 +144,6 @@ class XCXFIMABaseSignaller : public XCBaseSignaller // // analyserConfig.Clean(); patternAnalyserConfig.Clean(); - patternAnalyserDrawConfig.Clean(); } // @@ -246,1096 +239,6 @@ class XCXFIMABaseSignaller : public XCBaseSignaller // // Protected Actions ... - // - // Drawer Functions ... - - /** - * Draw Specified Pattern Pivot ... - * - * @param _pivot: XPivot, reference to Specified Pivot ... - * @param config: XPatternAnalysisDrawConfig, Darwing Configuration ... - * @param thresholdMultiplier: int, pivot point threshold ... - */ - void DrawPivot( - XPivot &_pivot, - XPatternAnalysisDrawConfig &config, - int thresholdMultiplier = 0 // - ) - { - // - // Normalize ... - thresholdMultiplier = NormalizeInt(thresholdMultiplier, 1); - - // - int arrowThreshold = config.arrowsThreshold * thresholdMultiplier; - arrowThreshold = NormalizeInt(arrowThreshold, 1); - - // - // Validate ... - bool has = - poiDrawer != NULL && - _pivot.IsValid(); - if (!has) - { - return; - } - - // - XOHCL _bar; - has = _pivot.GetBar(_bar); - if (!has) - { - // - _bar.Clean(); - return; - } - - // - XCBarArrowObject *iObj; - has = poiDrawer.DrawBarArrow( - _bar, - iObj, - _pivot.IsPeak() - ? config.arrowPeakPriceType - : config.arrowValePriceType, - _pivot.IsBullish() - ? config.bullishArrow - : config.bearishArrow, - _pivot.IsBullish() - ? config.bullishColor - : config.bearishColor, - config.arrowsWidth, - _pivot.IsBullish() - ? ANCHOR_TOP - : ANCHOR_BOTTOM, - _pivot.prefix + "_Pivot_" + ToXString(TimeToSeconds(_pivot.time)), - true, // Ignore Bar Tag ... - arrowThreshold // Threshold ... - ); - if (has) - { - drawnObjects.Add(iObj); - } - - // - ZeroMemory(iObj); - } - - /** - * Draw Specified Pattern Zone ... - * - * @param _zone: XBozxZone, reference to Specified Zone ... - * @param config: XPatternAnalysisDrawConfig, Darwing Configuration ... - */ - void DrawZone( - XBoxZone &_zone, - XPatternAnalysisDrawConfig &config // - ) - { - // - // Validate ... - bool has = - poiDrawer != NULL && - _zone.IsValid(); - if (!has) - { - return; - } - - // - XCBoxObject *iObj; - has = poiDrawer.DrawBox( - _zone, - iObj, - config.ignoreZonesAt, - _zone.type + "_Zone_" + ToXString(TimeToSeconds(_zone.from)) // - ); - if (has) - { - // - XPOIStyle iStyle; - poiDrawer.GetBoxStyle( - iStyle, - _zone.dir // - ); - - // - iStyle.clr = - _zone.IsBullish() - ? config.bullishColor - : config.bearishColor; - iStyle.width = config.zonesWidth; - iStyle.style = config.zonesStyle; - - // - poiDrawer.ApplyBoxStyle( - iObj, - iStyle // - ); - - // - drawnObjects.Add(iObj); - - // - iStyle.Clean(); - } - - // - ZeroMemory(iObj); - } - - /** - * Draw Specified Pattern info ... - * - * @param _bar: XOHCL, reference to Pattern's Bar ... - * @param _pivot: XPivot, reference to Pattern's Pivot ... - * @param _zone: XBoxZone, reference to Pattern's Zone ... - * @param _pattern: ENUM_X_BAR_PATTERN, Specified Bar Pattern ... - * @param _patternDir: ENUM_X_DIRECTION, Specified Bar Pattern's Direction ... - * @param thresholdMultiplier: int, pivot point threshold ... - * @param ignorePermissions: bool, force to Check Permissions from Config ... - */ - void DrawPattern( - XOHCL &_bar, - XPivot &_pivot, - XBoxZone &_zone, - ENUM_X_BAR_PATTERN _pattern, - ENUM_X_DIRECTION _patternDir, - int thresholdMultiplier = 0, - bool ignorePermissions = true // - ) - { - // - // Validate ... - bool has = - poiDrawer != NULL && - _bar.IsValid() && - IsXValid(_pattern) && - HasDirection(_patternDir); - if (!has) - { - return; - } - - // - // Handle Draws ... - - // - // Draw OHCL Bar ... - - // - // Draw Pivot ... - has = - ignorePermissions - ? true - : patternAnalyserDrawConfig.CanDrawPivot(_pattern); - if (has) - { - DrawPivot(_pivot, patternAnalyserDrawConfig, thresholdMultiplier); - } - - // - // Draw Zone ... - has = - ignorePermissions - ? true - : patternAnalyserDrawConfig.CanDrawZone(_pattern); - if (has) - { - DrawZone(_zone, patternAnalyserDrawConfig); - } - } - - /** - * Draw Specified Bar Pattern Analysis ... - * - * @param barAnalysis: XPatternAnalysis, reference to Specified Bar Pattern Analysis ... - */ - void DrawBarPatternAnalysis( - XPatternAnalysis &barAnalysis, - XPatternAnalysisDrawConfig &config // - ) - { - // - bool has = - poiDrawer != NULL && - barAnalysis.IsValid(); - if (!has) - { - return; - } - - // - bool canDraw; - bool isBullish; - bool isBearish; - XOHCL patternBar; - bool canDrawZone; - bool canDrawPivot; - XPivot patternPivot; - XBoxZone patternBox; - ENUM_X_BAR_PATTERN pattern; - ENUM_X_DIRECTION patternDir; - - // - int patternsPivotThresholdMultiplier = 0; - - // - // Support and Resistance ... - - // - // Support ... - isBearish = false; - isBullish = barAnalysis.IsSupport(); - has = isBullish; - if (has) - { - // - pattern = X_BAR_PATTERN_SUPPORT; - patternDir = X_DIRECTION_BULLISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // Resistance ... - isBullish = false; - isBearish = barAnalysis.IsResistance(); - has = isBearish; - if (has) - { - // - pattern = X_BAR_PATTERN_RESISTANCE; - patternDir = X_DIRECTION_BEARISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // PV: High and Low ... - - // - // Low ... - isBearish = false; - isBullish = barAnalysis.IsLow(); - has = isBullish; - if (has) - { - // - pattern = X_BAR_PATTERN_LOW; - patternDir = X_DIRECTION_BULLISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // High ... - isBullish = false; - isBearish = barAnalysis.IsHigh(); - has = isBearish; - if (has) - { - // - pattern = X_BAR_PATTERN_HIGH; - patternDir = X_DIRECTION_BEARISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // OB ... - isBullish = barAnalysis.IsOB(X_DIRECTION_BULLISH); - isBearish = barAnalysis.IsOB(X_DIRECTION_BEARISH); - has = isBullish || isBearish; - if (has) - { - // - pattern = X_BAR_PATTERN_OB; - patternDir = - isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // FVG ... - isBullish = barAnalysis.IsFVG(X_DIRECTION_BULLISH); - isBearish = barAnalysis.IsFVG(X_DIRECTION_BEARISH); - has = isBullish || isBearish; - if (has) - { - // - pattern = X_BAR_PATTERN_FVG; - patternDir = - isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // Momentum ... - isBullish = barAnalysis.IsMomentum(X_DIRECTION_BULLISH); - isBearish = barAnalysis.IsMomentum(X_DIRECTION_BEARISH); - has = isBullish || isBearish; - if (has) - { - // - pattern = X_BAR_PATTERN_MOMENTUM; - patternDir = - isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // Engulfed ... - isBullish = barAnalysis.IsEngulfed(X_DIRECTION_BULLISH); - isBearish = barAnalysis.IsEngulfed(X_DIRECTION_BEARISH); - has = isBullish || isBearish; - if (has) - { - // - pattern = X_BAR_PATTERN_ENGULFED; - patternDir = - isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // Pinned ... - isBullish = barAnalysis.IsPinned(X_DIRECTION_BULLISH); - isBearish = barAnalysis.IsPinned(X_DIRECTION_BEARISH); - has = isBullish || isBearish; - if (has) - { - // - pattern = X_BAR_PATTERN_PINNED; - patternDir = - isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // TrueGaped ... - isBullish = barAnalysis.IsTrueGaped(X_DIRECTION_BULLISH); - isBearish = barAnalysis.IsTrueGaped(X_DIRECTION_BEARISH); - has = isBullish || isBearish; - if (has) - { - // - pattern = X_BAR_PATTERN_TRUE_GAPED; - patternDir = - isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // Star ... - isBullish = barAnalysis.IsStar(X_DIRECTION_BULLISH); - isBearish = barAnalysis.IsStar(X_DIRECTION_BEARISH); - has = isBullish || isBearish; - if (has) - { - // - pattern = X_BAR_PATTERN_STAR; - patternDir = - isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // Piercing ... - isBullish = barAnalysis.IsPiercing(X_DIRECTION_BULLISH); - isBearish = barAnalysis.IsPiercing(X_DIRECTION_BEARISH); - has = isBullish || isBearish; - if (has) - { - // - pattern = X_BAR_PATTERN_PIERCING; - patternDir = - isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // Rising ... - isBullish = barAnalysis.IsRising(X_DIRECTION_BULLISH); - isBearish = barAnalysis.IsRising(X_DIRECTION_BEARISH); - has = isBullish || isBearish; - if (has) - { - // - pattern = X_BAR_PATTERN_RISING; - patternDir = - isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // Flag ... - isBullish = barAnalysis.IsFlag(X_DIRECTION_BULLISH); - isBearish = barAnalysis.IsFlag(X_DIRECTION_BEARISH); - has = isBullish || isBearish; - if (has) - { - // - pattern = X_BAR_PATTERN_FLAG; - patternDir = - isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // SignalKey ... - isBullish = barAnalysis.IsSignalKey(X_DIRECTION_BULLISH); - isBearish = barAnalysis.IsSignalKey(X_DIRECTION_BEARISH); - has = isBullish || isBearish; - if (has) - { - // - pattern = X_BAR_PATTERN_SIGNALKEY; - patternDir = - isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - canDraw = config.CanDraw(pattern); - if (canDraw) - { - // - has = barAnalysis.GetPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir // - ); - if (has) - { - // - canDrawZone = config.CanDrawZone(pattern); - if (!canDrawZone) - { - patternBox.Clean(); - } - - // - canDrawPivot = config.CanDrawPivot(pattern); - if (!canDrawPivot) - { - patternPivot.Clean(); - } - else - { - patternsPivotThresholdMultiplier++; - } - - // - DrawPattern( - patternBar, - patternPivot, - patternBox, - pattern, - patternDir, - patternsPivotThresholdMultiplier // - ); - } - } - } - - // - // Cleanup Resources ... - patternBar.Clean(); - patternBox.Clean(); - patternPivot.Clean(); - } - // // Private ... private: @@ -1381,11 +284,6 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller patternAnalyserConfig.Default(); patternAnalyserConfig.FullPattern(); - // - patternAnalyserDrawConfig.Clean(); - patternAnalyserDrawConfig.Default(); - patternAnalyserDrawConfig.FullDraw(); - // // Ignore Signal Targets ... ignoreTargets = true; @@ -1484,15 +382,51 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller // ); // DrawBarPatternAnalysis(iBarAnalysis, patternAnalyserDrawConfig); - // - has = fimaHelper.HasBoundarySwitch( - iDir, - iBar.Index() // - ); - if (has) - { - Print("Hot Place Detected"); - } + // // + // has = fimaHelper.IsBoundaryFakeBreaked( + // iDir, + // iBar.Index() // + // ); + // if (has) + // { + // Print("Hot Place Detected"); + // } + + // // + // XPivot pvPivots[]; + // count = fimaHelper.ExtractPVPivots( + // pvPivots, + // iBar.Index(), + // 25, + // 1500, + // 5 // + // ); + // has = IsValidSize(count); + // if (has) { + // // + // XPivotAnalysis pvAnalysis; + // has = pvAnalysis.Init( + // "XPV", + // symbol, + // period, + // pvPivots // + // ); + // if (has) { + // // + // XPivotAnalysisDrawConfig iC; + // iC.Default(); + // iC.drawPivots = true; + // iC.drawPeakTrend = true; + // iC.drawValeTrend = true; + // poiDrawer.DrawPivotAnalysis( + // pvAnalysis, + // iC // + // ); + + // // + // Print("PV Analysis ..."); + // } + // } // // Disable Signallers ... diff --git a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 index de1d9c22..014b1a6a 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 @@ -367,8 +367,8 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector */ void AnalyseMarket( XOHCL &forBar, - XFIMAMarketStructure &structure, - XFIMAPatternDetectorConfig &config // + XFIMAMarketStructure &structure // , + //XFIMAPatternDetectorConfig &config // ) { // // diff --git a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 index 1a953b24..f5fb350d 100644 --- a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 +++ b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 @@ -29,56 +29,6 @@ // // Definitions ... -/** - * Configure Market Structure Detection ... - **/ -struct XFIMAPatternDetectorConfig -{ - // - // Props ... - - // - // Constructor ... - XFIMAPatternDetectorConfig() - { - Clean(); - } - - // - // Tools ... - - /** - * Cleanup Model ... - */ - void Clean() - { - ZeroMemory(this); - } - - /** - * Default Model ... - */ - void Default() - { - } - - /** - * Full Detection Model ... - */ - void FullDetect() - { - } - - /** - * Default Config, by turn off all detecting flags ... - */ - void OffDetectors() - { - } - - // -}; - /** * XFIMA Base Market Structure ... * AnalyseMarket result ... @@ -86,7 +36,22 @@ struct XFIMAPatternDetectorConfig struct XFIMAMarketStructure { // - XOHCL bar; + XOHCL bar; // Spacified Start Bar for Analysing ... + int length; // Loopback Length for Analyse Structure ... + + // + XPivotAnalysis pvAnalysis; // PV Pivot Analysis Result ... + XPivotAnalysis zgAnalysis; // ZG Pivot Analysis Result ... + XPivotAnalysis barsPivotsAnalysis; // Bars Pivot Analysis Result ... + + // + XPatternAnalysis barsAnalysis[]; // Anaysed Bars ... + XPatternAnalysisConfig barsAnalysisConfig; // Bars Analyser Config ... + + // + // Configure Pivots Detection ... + int requiredPivots; // Required Extracted Pivots for Analysis ... + // // Constructor ... @@ -99,17 +64,41 @@ struct XFIMAMarketStructure // Tools ... /** - * Cleanup Model ... + * Cleanup ... */ void Clean() { + // + bar.Clean(); + length = 0; + + // + pvAnalysis.Clean(); + zgAnalysis.Clean(); + XClean(barsAnalysis); + barsAnalysisConfig.Clean(); // ZeroMemory(this); } - // - // Checker Functions ... + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = bar.IsValid() && + length > 0; + + // + return result; + } // }; @@ -121,6 +110,7 @@ struct XFIMAMarketStructureDrawerConfig { // // Props ... + XPatternAnalysisDrawConfig barAnalysisDrawConfig; // // Constructor ... diff --git a/compile.cmd b/compile.cmd index 8a7a3d90..9ccec06c 100644 --- a/compile.cmd +++ b/compile.cmd @@ -1,8 +1,8 @@ @echo off @REM set METAEDITOR="C:\Program Files\MetaTrader 5 General\MetaEditor64.exe" - @REM set METAEDITOR="C:\Program Files\MetaTrader 5 Main\MetaEditor64.exe" - set METAEDITOR="C:\Program Files\MetaTrader 5 General\MetaEditor64.exe" + set METAEDITOR="C:\Program Files\MetaTrader 5 Main\MetaEditor64.exe" + @REM set METAEDITOR="C:\Program Files\MetaTrader 5 General\MetaEditor64.exe" set "LOGFILE=%~dpn1.log" if "%~1"=="" (