diff --git a/Classes/x-saherelm.x-bar.analyser.class.mq5 b/Classes/x-saherelm.x-bar.analyser.class.mq5 index 6fd75b1f..a6596c5d 100644 --- a/Classes/x-saherelm.x-bar.analyser.class.mq5 +++ b/Classes/x-saherelm.x-bar.analyser.class.mq5 @@ -401,7 +401,7 @@ class XCBarAnalyser : public XCBase return result; } - // + // double points = GetPoints(bar.symbol); int index = bar.Index(); @@ -1458,6 +1458,11 @@ class XCBarAnalyser : public XCBase // // Check Body ... double rangePercent = GetBarRangePercent(bar); + result = rangePercent > 0; + if (!result) + { + return result; + } // double body = bar.GetBody(); diff --git a/Classes/x-saherelm.x-cobject.class.mq5 b/Classes/x-saherelm.x-cobject.class.mq5 index 1edcf174..0dc8f05e 100644 --- a/Classes/x-saherelm.x-cobject.class.mq5 +++ b/Classes/x-saherelm.x-cobject.class.mq5 @@ -233,8 +233,9 @@ class XCBarArrowObject : public XCBaseObject // result = - // - bar.IsValid() + // + bar.IsValid() && + IsValid(name) // ; if (!result) @@ -2872,6 +2873,162 @@ class XCTrendObject : public XCBaseObject public: // + /** + * Creator ... + * + * @param chart_id: Long, Specified Chart ID ... + * @param window: Integer, Specified Chart Window ID ... + * @param rr: XRR instance Reference ... + * @param prefix: String ... + * + * @return ( bool ) + */ + bool Create( + long chart_id, + int window, + XPoint &swings[], + bool useMinAsStart = true, + string prefix = NULL // + ) + { + // + bool result = false; + + // + int count = ArraySize(swings); + result = + count >= 2 && + IsValidSize(count); + if (!result) + { + return result; + } + + // + double min = 0; + datetime minAt = NULL; + + // + double max = 0; + datetime maxAt = NULL; + + // + // Etract Min/Max ... + for (int i = 0; i < count; i++) + { + // + XPoint iPoint = swings[i]; + + // + if (!iPoint.IsValid()) + { + // + iPoint.Clean(); + continue; + } + + // + bool canSetMin = + min == 0 + ? true + : min > iPoint.value; + if (canSetMin) + { + // + minAt = iPoint.at; + min = iPoint.value; + } + + // + bool canSetMax = + max == 0 + ? true + : max < iPoint.value; + if (canSetMax) + { + // + maxAt = iPoint.at; + max = iPoint.value; + } + + // + iPoint.Clean(); + } + + // + double first = + useMinAsStart + ? min + : max; + datetime firstTime = + useMinAsStart + ? minAt + : maxAt; + + // + double second = + useMinAsStart + ? max + : min; + datetime secondTime = + useMinAsStart + ? maxAt + : minAt; + + // + // Validate Points ... + result = + // + first > 0 && + second > 0 && + (useMinAsStart + ? first <= second + : first >= second) && + IsSpecifiedValid(firstTime) && + IsSpecifiedValid(secondTime) + // + ; + if (!result) + { + return result; + } + + // + ENUM_X_DIRECTION dir = + useMinAsStart + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + string name = "XTRND" + ToString(dir) + "_" + ToString(first) + "_" + ToString(second); + if (IsValid(prefix)) + { + name = prefix + "_" + name; + } + string nameMD5 = ToMD5(name); + + // + result = mTrend.Create( + chart_id, + name, + window, + firstTime, + first, + secondTime, + second // + ); + if (!result) + { + return result; + } + + // + ObjName(name); + + // + return result; + } + /** * Creator ... * diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index 8954063a..898fa363 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -23,6 +23,7 @@ // Imports ... #include "../Classes/x-saherelm.base.class.mq5" #include "../Classes/x-saherelm.x-cobject.class.mq5" +#include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5" // // Definitions ... @@ -2872,6 +2873,66 @@ class XCPOIDrawer : public XCBase return result; } + /** + * Create Trend Line Object ... + * + * @param swings: XSwingPoint instance Collection ... + * @param useMinAsStart: Specified Min Value as Start ... + * + * @return ( bool ) + */ + bool CreateTrend( + XPoint &swings[], + XCTrendObject *&object, + bool useMinAsStart = true // + ) + { + // + bool result = false; + + // + object = NULL; + + // + result = ArraySize(swings) >= 2 && + IsValidSize(ArraySize(swings)); + if (!result) + { + return result; + } + + // + string prefix = Prefix(); + long chartID = ChartIdentification(); + int window = SubWindowIdentification(); + + // + object = new XCTrendObject(); + result = object.Create( + chartID, + window, + swings, + useMinAsStart, + prefix // + ); + + // + if (!result) + { + return result; + } + + // + color clrTrend = useMinAsStart + ? SwingLowColor() + : SwingHighColor(); + object.TrendColor(clrTrend); + object.TrendRayRight(true); + + // + return result; + } + /** * Create Consolidation Zone Object ... * @@ -2929,7 +2990,7 @@ class XCPOIDrawer : public XCBase /** * Create Bar Object ... * - * @param bar: XOHCL instance Reference .. + * @param bar: XOHCL instance Reference ... * @param object: XCOHCLObject pointer Reference .. * @param to: Datetime ... * @@ -3030,6 +3091,84 @@ class XCPOIDrawer : public XCBase return result; } + /** + * Create Bar Arrow Object ... + * + * @param bar: XOHCL instance Reference ... + * @param priceType: ENUM_X_PRICE member ... + * @param arrow: int, Arrow Code ... + * @param clr: color, Arro Color ... + * @param width: int, Arrow Width ... + * @param anchor: ENUM_ARROW_ANCHOR, anchor of Arrow ... + * @param name: string, name of Arrow ... + * + * @return ( bool ) + */ + bool CreateBarArrow( + XOHCL &bar, + XCBarArrowObject *&object, + ENUM_X_PRICE priceType, + int arrow = 159, + color clr = clrYellow, + int width = 3, + ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, + string name = NULL // + ) + { + // + bool result = false; + + // + object = NULL; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + string barTag = bar.GetTag(name); + + // + string prefix = Prefix(); + long chartID = ChartIdentification(); + int window = SubWindowIdentification(); + + // + color mBullishColor = BarBullishColor(); + color mBearishColor = BarBearishColor(); + + // + prefix = + (IsValid(prefix) + ? prefix + "_" + : prefix) + + barTag; + + // + object = new XCBarArrowObject(); + result = object + .CreateByBar( + chartID, + prefix, + window, + arrow, + bar, + priceType // + ); + if (result) + { + // + object.ArrowColor(clr); + object.ArrowWidth(width); + } + + // + return result; + } + /** * Create Specific Box on Chart ... * diff --git a/Documents/BKP/tmpPOIS.mq5 b/Documents/BKP/tmpPOIS.mq5 new file mode 100644 index 00000000..62c9cda4 --- /dev/null +++ b/Documents/BKP/tmpPOIS.mq5 @@ -0,0 +1,346 @@ + // + // Detect Inside Zones ... + + // + XCFVG *insideFVG; + bool hasInsideFVG = false; + + // + XCOrderBlock *insideOB; + bool hasInsideOB = false; + + // + XCSupplyZone *insideSupply; + bool hasInsideSupply = false; + + // + XCDemandZone *insideDemand; + bool hasInsideDemand = false; + + // + XCSupportZone *insideSupport; + bool hasInsideSupport = false; + + // + XCResistanceZone *insideResistnce; + bool hasInsideResistance = false; + + // + // Detect PullBack ... + + // + ENUM_X_DIRECTION pullbackDir; + bool hasPullBack = mXWZBarAnalyser.HasPullBack( + pullbackDir, + iBar // + ); + bool hasBullishPullBack = + hasPullBack && + IsBullish(pullbackDir); + bool hasBearishPullBack = + hasPullBack && + IsBearish(pullbackDir); + + // + // Detect PinBar ... + + // + ENUM_X_DIRECTION pinBarDir; + bool hasPinBar = mXWZBarAnalyser.IsPinBar( + iBar, + pinBarDir, + 0 // + ); + bool hasBullishPinBar = + hasPinBar && + IsBullish(pinBarDir); + bool hasBearishPinBar = + hasPinBar && + IsBearish(pinBarDir); + + // + // Detect Order Block ... + + // + XOHCL obBar; + XCOrderBlock *ob; + ENUM_X_DIRECTION obDir; + bool hasOB = mXWZBarAnalyser.HasOrderBlock( + iBar, + obBar, + obDir // + ); + bool hasBullishOB = + hasOB && + IsBullish(obDir); + bool hasBearishOB = + hasOB && + IsBearish(obDir); + if (hasOB) + { + // + ob = new XCOrderBlock(); + bool isInited = ob.Init(obBar, obDir); + if (isInited) + { + // + ENUM_X_DIRECTION forDir = ob.GetDirection(); + + // + // Check OB Not Activated ... + XOHCL activationBar; + bool isObActivationBarBodyIn = false; + bool isActivated = ob.IsActivated( + forDir, + activationBar, + isObActivationBarBodyIn, + false, + _Period // + ); + + // + if (isActivated) + { + // + hasOB = false; + obBar.Clean(); + ZeroMemory(ob); + hasBullishOB = false; + hasBearishOB = false; + } + } + } + + // + if (hasBullishPinBar) + { + // + XCBarArrowObject *iObj; + bool isCreated = mXWZPOIDrawer + .CreateBarArrow( + iBar, + iObj, + X_PRICE_LOW, + 159, + clrAqua, + 3, + ANCHOR_BOTTOM, + "BULLPULL" // + ); + if (isCreated) + { + mXWZDrawnObjects.Add(iObj); + } + } + + // + if (hasBearishPinBar) + { + // + XCBarArrowObject *iObj; + bool isCreated = mXWZPOIDrawer + .CreateBarArrow( + iBar, + iObj, + X_PRICE_HIGH, + 159, + clrMagenta, + 3, + ANCHOR_TOP, + "BEARPULL" // + ); + if (isCreated) + { + mXWZDrawnObjects.Add(iObj); + } + } + + // + if (hasOB) + { + // + XCBaseObject *iObj; + bool isCreated = mXWZPOIDrawer.CreateOrderBlock( + ob, + iObj // + ); + if (isCreated) + { + mXWZDrawnObjects.Add(iObj); + } + } + + // + int idx = -1; + int count = 0; + bool has = false; + + // + ENUM_X_DIRECTION trend = + IsValid(lastBullishTrend) && + lastBullishTrend > lastBearishTrend + ? X_DIRECTION_BULLISH + : IsValid(lastBearishTrend) && + lastBearishTrend > lastBullishTrend + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + bool hasTrend = HasDirection(trend); + bool hasBullishTrend = hasTrend && + IsBullish(trend); + bool hasBearishTrend = hasTrend && + IsBearish(trend); + + // + // Order Block ... + has = hasBullishTrend; + if (has) + { + } + has = hasBearishTrend; + if (has) + { + } + + // + // Fair Value Gap ... + has = hasBullishTrend; + if (has) + { + } + has = hasBearishTrend; + if (has) + { + } + + // + // Supply Zone ... + has = hasBearishTrend; + if (has) + { + } + + // + // Resistance Zone ... + has = hasBearishTrend; + if (has) + { + } + + // + // Demand Zone ... + has = hasBullishTrend; + if (has) + { + } + + // + // Support Zone ... + has = hasBullishTrend; + if (has) + { + } + + // + // Draw Inside Zones ... + + // + if (hasInsideOB) + { + // + XCBaseObject *iObj; + bool isCreated = mXWZPOIDrawer + .CreateOrderBlock( + insideOB, + iObj // + ); + // + if (isCreated) + { + mXWZDrawnObjects.Add(iObj); + } + } + + // + if (hasInsideFVG) + { + // + XCBaseObject *iObj; + bool isCreated = mXWZPOIDrawer + .CreateFairValueGap( + insideFVG, + iObj // + ); + // + if (isCreated) + { + mXWZDrawnObjects.Add(iObj); + } + } + + // + if (hasInsideSupply) + { + // + XCSupplyZoneObject *iObj; + bool isCreated = mXWZPOIDrawer + .CreateSupplyZone( + insideSupply, + iObj // + ); + // + if (isCreated) + { + mXWZDrawnObjects.Add(iObj); + } + } + + // + if (hasInsideDemand) + { + // + XCDemandZoneObject *iObj; + bool isCreated = mXWZPOIDrawer + .CreateDemandZone( + insideDemand, + iObj // + ); + // + if (isCreated) + { + mXWZDrawnObjects.Add(iObj); + } + } + + // + if (hasInsideSupport) + { + // + XCSupportZoneObject *iObj; + bool isCreated = mXWZPOIDrawer + .CreateSupportZone( + insideSupport, + iObj // + ); + // + if (isCreated) + { + mXWZDrawnObjects.Add(iObj); + } + } + + // + if (hasInsideResistance) + { + // + XCResistanceZoneObject *iObj; + bool isCreated = mXWZPOIDrawer + .CreateResistanceZone( + insideResistnce, + iObj // + ); + // + if (isCreated) + { + mXWZDrawnObjects.Add(iObj); + } + } diff --git a/Documents/BKP/xsupdem/plib.tmp.codes.mq5 b/Documents/BKP/xsupdem/plib.tmp.codes.mq5 index 5be31c22..679b8500 100644 --- a/Documents/BKP/xsupdem/plib.tmp.codes.mq5 +++ b/Documents/BKP/xsupdem/plib.tmp.codes.mq5 @@ -2117,3 +2117,250 @@ bool IsReject( mObjects.Add(iObj); } } + +////////////////////////////////////////////////////////////////////////////////////////////// + + // + XPOIState state; + mXWZPOIDetector.GetState(state); + + // + ENUM_X_DIRECTION trend = + IsValid(lastBullishTrend) && + lastBullishTrend > lastBearishTrend + ? X_DIRECTION_BULLISH + : IsValid(lastBearishTrend) && + lastBearishTrend > lastBullishTrend + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + bool hasTrend = HasDirection(trend); + bool hasBullishTrend = hasTrend && + IsBullish(trend); + bool hasBearishTrend = hasTrend && + IsBearish(trend); + + // + // Order Block ... + has = hasBullishTrend && + state.HasBullishOrderBlocks(); + if (has) + { + // + XCOrderBlock *tmps[]; + count = ExtractInsideZones( + iBar, + state.bullishOrderBlocks, + tmps // + ); + has = IsValidSize(count); + if (has) + { + // + idx = GetLowest(tmps); + hasInsideOB = IsValidIndex(idx); + if (hasInsideOB) + { + insideOB = tmps[idx]; + } + } + + // + Clean(tmps); + } + has = hasBearishTrend && + state.HasBearishOrderBlocks(); + if (has) + { + // + XCOrderBlock *tmps[]; + count = ExtractInsideZones( + iBar, + state.bearishOrderBlocks, + tmps // + ); + has = IsValidSize(count); + if (has) + { + // + idx = GetHighest(tmps); + hasInsideOB = IsValidIndex(idx); + if (hasInsideOB) + { + insideOB = tmps[idx]; + } + } + + // + Clean(tmps); + } + + // + // Fair Value Gap ... + has = hasBullishTrend && + state.HasBullishFairValueGaps(); + if (has) + { + // + XCFVG *tmps[]; + count = ExtractInsideZones( + iBar, + state.bullishFairValueGaps, + tmps // + ); + has = IsValidSize(count); + if (has) + { + // + idx = GetLowest(tmps); + hasInsideFVG = IsValidIndex(idx); + if (hasInsideFVG) + { + insideFVG = tmps[idx]; + } + } + + // + Clean(tmps); + } + has = hasBearishTrend && + state.HasBearishFairValueGaps(); + if (has) + { + // + XCFVG *tmps[]; + count = ExtractInsideZones( + iBar, + state.bearishFairValueGaps, + tmps // + ); + has = IsValidSize(count); + if (has) + { + // + idx = GetHighest(tmps); + hasInsideFVG = IsValidIndex(idx); + if (hasInsideFVG) + { + insideFVG = tmps[idx]; + } + } + + // + Clean(tmps); + } + + // + // Supply Zone ... + has = hasBearishTrend && + state.HasSupplyZones(); + if (has) + { + // + XCSupplyZone *tmps[]; + count = ExtractInsideZones( + iBar, + state.supplyZones, + tmps // + ); + has = IsValidSize(count); + if (has) + { + // + idx = GetHighest(tmps); + hasInsideSupply = IsValidIndex(idx); + if (hasInsideSupply) + { + insideSupply = tmps[idx]; + } + } + + // + Clean(tmps); + } + + // + // Resistance Zone ... + has = hasBearishTrend && + state.HasResistanceZones(); + if (has) + { + // + XCResistanceZone *tmps[]; + count = ExtractInsideZones( + iBar, + state.resistanceZones, + tmps // + ); + has = IsValidSize(count); + if (has) + { + // + idx = GetHighest(tmps); + hasInsideResistance = IsValidIndex(idx); + if (hasInsideResistance) + { + insideResistnce = tmps[idx]; + } + } + + // + Clean(tmps); + } + + // + // Demand Zone ... + has = hasBullishTrend && + state.HasDemandZones(); + if (has) + { + // + XCDemandZone *tmps[]; + count = ExtractInsideZones( + iBar, + state.demandZones, + tmps // + ); + has = IsValidSize(count); + if (has) + { + // + idx = GetLowest(tmps); + hasInsideDemand = IsValidIndex(idx); + if (hasInsideDemand) + { + insideDemand = tmps[idx]; + } + } + + // + Clean(tmps); + } + + // + // Support Zone ... + has = hasBullishTrend && + state.HasSupportZones(); + if (has) + { + // + XCSupportZone *tmps[]; + count = ExtractInsideZones( + iBar, + state.supportZones, + tmps // + ); + has = IsValidSize(count); + if (has) + { + // + idx = GetLowest(tmps); + hasInsideSupport = IsValidIndex(idx); + if (hasInsideSupport) + { + insideSupport = tmps[idx]; + } + } + + // + Clean(tmps); + } diff --git a/Documents/BKP/xsupdem/tmp.signal.mq5 b/Documents/BKP/xsupdem/tmp.signal.mq5 index 175f9260..e67d9389 100644 --- a/Documents/BKP/xsupdem/tmp.signal.mq5 +++ b/Documents/BKP/xsupdem/tmp.signal.mq5 @@ -1149,6 +1149,83 @@ else if (isPriceRejected) ///////////////////////////////////////////////////////////////////////////////////////////////////// + // + XPoint llPoint; + llPoint.value = iLL; + llPoint.at = iLLTime; + + // + // + + // + XPoint hhPoint; + hhPoint.value = iHH; + hhPoint.at = iHHTime; + + // + XPoint llSwings[]; + AddRef( + llPoint, + llSwings // + ); + + // + llPoint.at = iHHTime; + AddRef( + llPoint, + llSwings // + ); + + // + // + + // + XPoint hhSwings[]; + + // + hhPoint.at = iLLTime; + AddRef( + hhPoint, + hhSwings // + ); + + // + hhPoint.at = iHHTime; + AddRef( + hhPoint, + hhSwings // + ); + + // + XCTrendObject *llTrendObj; + bool isCreated = mXWZPOIDrawer.CreateTrend( + llSwings, + llTrendObj // + ); + if (isCreated) + { + mXWZDrawnObjects.Add(llTrendObj); + } + + // + XCTrendObject *hhTrendObj; + isCreated = mXWZPOIDrawer.CreateTrend( + hhSwings, + hhTrendObj // + ); + if (isCreated) + { + mXWZDrawnObjects.Add(hhTrendObj); + } + + // + // + + // + Clean(llSwings); + Clean(hhSwings); + llPoint.Clean(); + hhPoint.Clean(); ///////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Indicators/x-saherelm.x121.xwz.mq5 b/Indicators/x-saherelm.x121.xwz.mq5 new file mode 100644 index 00000000..f1d21441 --- /dev/null +++ b/Indicators/x-saherelm.x121.xwz.mq5 @@ -0,0 +1,1596 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: X121 XWZ +// Description: XWZ ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121 XWZ Indicator" +#property strict + +// +// Definitions ... + +// +enum ENUM_XWZ_REJECTION_TYPES +{ + XWZ_REJECTION_BAR, // Only Bar Reject + XWZ_REJECTION_STRONG_BAR, // Directional Bar Reject + XWZ_REJECTION_PRESSURED_BAR, // Bar Reject using Pressure + XWZ_REJECTION_STRONG_PRESSURED_BAR, // Strong Bar Reject using Pressure +}; + +// +#define ShortName "X121 XWZ" + +// +// Includes Common Library ... +#include "../Classes/x-saherelm.x-bar.analyser.class.mq5" +#include "../Classes/x-saherelm.x-poi.drawer.class.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +// Market ... +input group "Market"; + +// +input group "Calculation"; +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Detect Price Type +input ENUM_XWZ_REJECTION_TYPES rejectionType = XWZ_REJECTION_STRONG_BAR; // Rejection Type +input int rejectionVerificationLength = 3; // Rejection Verification Length + +// +input group "MA Detection"; +input int maLength = 20; // MA Length +input ENUM_MA_METHOD maMethod = MODE_EMA; // MA Method + +// +input group "ATR StopLoss"; +input int atrLength = 14; // ATR Length +input int atrMultiplier = 2; // ATR Multiplier + +// +input group "ADX Detection"; +input int adxLength = 14; // ADX Length +input double adxThreshold = 25; // ADX Threshold for Strong Trends + +// +// Presentation ... +input group "Presentation"; + +// +input int startCalculationForLastBars = 1000; // Calculate Last n Bars +input int upTrendArrowCode = 233; // Up Trend Arrow Code +input int downTrendArrowCode = 234; // Down Trend Arrow Code +input int longRejectArrowCode = 225; // Long Reject Arrow Code +input int shortRejectArrowCode = 226; // Short Reject Arrow Code + +// +input bool showMA = true; // Show Moving Average +input bool showLongSL = true; // Show Long SL +input bool showShortSL = true; // Show Short SL +input bool showUpTrend = true; // Show Up Trend +input bool showDownTrend = true; // Show Down Trend +input bool showLongReject = true; // Show Long Reject +input bool showShortReject = true; // Show Short Reject + +// +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 7 + +// +// Plot Buffers ... + +// +#define maBufferIndex 0 +double maBuffer[]; + +// +#property indicator_label1 "X121 XWZ MA" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLightSkyBlue +#property indicator_style1 STYLE_SOLID +#property indicator_width1 2 + +// +#define longSLBufferIndex 1 +double longSLBuffer[]; + +// +#property indicator_label2 "X121 XWZ Long SL" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrOrange +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +#define shortSLBufferIndex 2 +double shortSLBuffer[]; + +// +#property indicator_label3 "X121 XWZ Short SL" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrOrange +#property indicator_style3 STYLE_SOLID +#property indicator_width3 1 + +// +#define longRejectBufferIndex 3 +double longRejectBuffer[]; + +// +#property indicator_label4 "X121 XWZ Long Reject" +#property indicator_type4 DRAW_ARROW +#property indicator_color4 clrLime +#property indicator_style4 STYLE_SOLID +#property indicator_width4 1 + +// +#define shortRejectBufferIndex 4 +double shortRejectBuffer[]; + +// +#property indicator_label5 "X121 XWZ Short Reject" +#property indicator_type5 DRAW_ARROW +#property indicator_color5 clrRed +#property indicator_style5 STYLE_SOLID +#property indicator_width5 1 + +// +#define upTrendBufferIndex 5 +double upTrendBuffer[]; + +// +#property indicator_label6 "X121 XTREND Up" +#property indicator_type6 DRAW_ARROW +#property indicator_color6 clrAqua +#property indicator_width6 1 + +// +#define downTrendBufferIndex 6 +double downTrendBuffer[]; + +// +#property indicator_label7 "X121 XTREND Down" +#property indicator_type7 DRAW_ARROW +#property indicator_color7 clrMagenta +#property indicator_width7 1 + +// +// Data Buffers ... + +// +int mLastBufferIndex = 6; + +// +#define atrBufferIndex mLastBufferIndex + 1 +double atrBuffer[]; + +// +#define adxBufferIndex mLastBufferIndex + 2 +double adxBuffer[]; + +// +// Variables, Properties and etc ... + +// +// this counts Available Bars ... +int limit; + +// +int maxLength; + +// +// MA Handler ... +int maHandler = INVALID_HANDLE; + +// +// ATR Handler ... +int atrHandler = INVALID_HANDLE; + +// +// ADX Handler ... +int adxHandler = INVALID_HANDLE; + +// +CArrayObj mXWZDrawnObjects; +XCPOIDrawer *mXWZPOIDrawer; +XCBarAnalyser *mXWZBarAnalyser; + +// +datetime lastBullishTrend = NULL; +datetime lastBearishTrend = NULL; + +// +// Un Activated POI(s) ... +XCFVG *mXWZUnActivatedFVGs[]; +XCOrderBlock *mXWZUnActivatedOBs[]; +XCSupplyZone *mXWZUnActivatedSupplyZones[]; +XCDemandZone *mXWZUnActivatedDemandZones[]; +XCSupportZone *mXWZUnActivatedSupportZones[]; +XCResistanceZone *mXWZUnActivatedResistanceZones[]; + +// +// Activated POI(s) ... +XCFVG *mXWZActivatedFVGs[]; +XCOrderBlock *mXWZActivatedOBs[]; +XCSupplyZone *mXWZActivatedSupplyZones[]; +XCDemandZone *mXWZActivatedDemandZones[]; +XCSupportZone *mXWZActivatedSupportZones[]; +XCResistanceZone *mXWZActivatedResistanceZones[]; + +// +// Event Handlers ... + +/** + * Initialize Indicator ... + * + * @return ( int ) + */ +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initialize Indicator Handlers ... + + // + // MA ... + maHandler = iMA( + _Symbol, + _Period, + maLength, + 0, + maMethod, + appliedTo // + ); + bool isInited = maHandler != INVALID_HANDLE; + if (!isInited) + { + return INIT_FAILED; + } + + // + // ATR ... + atrHandler = iATR( + _Symbol, + _Period, + atrLength // + ); + isInited = maHandler != INVALID_HANDLE; + if (!isInited) + { + return INIT_FAILED; + } + + // + // ADX ... + adxHandler = iADX( + _Symbol, + _Period, + adxLength // + ); + isInited = maHandler != INVALID_HANDLE; + if (!isInited) + { + return INIT_FAILED; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + IndicatorSetInteger(INDICATOR_DIGITS, 2); + + // + mXWZPOIDrawer = new XCPOIDrawer(); + mXWZBarAnalyser = new XCBarAnalyser(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +/** + * De Initialize Indicator ... + * + * @param reason: Integer, De Initialization Reason ... + */ +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + IndicatorRelease(maHandler); + IndicatorRelease(atrHandler); + IndicatorRelease(adxHandler); + + // + mXWZDrawnObjects.Clear(); + + // + ZeroMemory(mXWZPOIDrawer); + ZeroMemory(mXWZBarAnalyser); + + // + Clean(mXWZActivatedFVGs); + Clean(mXWZActivatedOBs); + Clean(mXWZActivatedSupplyZones); + Clean(mXWZActivatedDemandZones); + Clean(mXWZActivatedSupportZones); + Clean(mXWZActivatedResistanceZones); + + // + Clean(mXWZUnActivatedOBs); + Clean(mXWZUnActivatedFVGs); + Clean(mXWZUnActivatedSupplyZones); + Clean(mXWZUnActivatedDemandZones); + Clean(mXWZUnActivatedSupportZones); + Clean(mXWZUnActivatedResistanceZones); +} + +/** + * Calculate Bars ... + * + * @param rates_total: Integer, Total Bars on Chart ... + * @param prev_calculated: Integer, Total Calculated Bars on Charts ... + * @param time: DateTime Array, History of Open Time ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param low: Double Array, History of Low Prices ... + * @param close: Double Array, History of Close Prices ... + * @param tick_volume: Long, History of Tick Volumes on Bar ... + * @param volume: Long, History of Trade Volumes ... + * @param spread: Double, History of Spread Price ... + * + * @return ( int ) + */ +int OnCalculate( + const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[] // +) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // Validate Calculated Bars ... + + // + // MA ... + int maCalculatedBars = BarsCalculated(maHandler); + + // + // ATR ... + int atrCalculatedBars = BarsCalculated(atrHandler); + + // + // ADX ... + int adxCalculatedBars = BarsCalculated(adxHandler); + + // + bool isPassedRequiredCalculatedBars = + // + // MA ... + maCalculatedBars >= maxLength && + // + // ATR ... + atrCalculatedBars >= maxLength && + // + // ADX ... + adxCalculatedBars >= maxLength + // + ; + if (!isPassedRequiredCalculatedBars) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) + ? rates_total + : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + + // + // MA ... + int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer); + + // + // ATR ... + int copiedAtr = CopyBuffer(atrHandler, MAIN_LINE, 0, limit, atrBuffer); + + // + // ADX ... + int copiedAdxs = CopyBuffer(adxHandler, MAIN_LINE, 0, limit, adxBuffer); + + // + // Validate Copied Items ... + bool isPassedRequiredCopiedItems = + // + // MA ... + copiedMas > 0 && + // + // ATR ... + copiedAtr > 0 && + // + // ADX ... + copiedAdxs > 0 + // + ; + if (!isPassedRequiredCopiedItems) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + CalculatedPOIs( + // + i, + prev_calculated, + rates_total, + // + open, + high, + close, + low, + tick_volume // + ); + + // + CalculateBuffers( + // + i, + prev_calculated, + rates_total, + // + open, + high, + close, + low, + tick_volume // + ); + } + + // + return rates_total; +} + +// +// Functions ... + +/** + * Validate Input Args for Initialization ... + * + * @return ( bool ) + */ +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + // MA ... + maLength > 0 && + // + // ATR ... + atrLength > 0 && + atrMultiplier > 0 && + // + // ADX ... + adxLength > 0 && + adxThreshold > 0 + // + ; + + // + return result; +} + +/** + * Extract Max Length of Inputs ... + * + * @return ( int ) + */ +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(maLength, atrLength); + result = MathMax(result, adxLength); + + // + return result; +} + +/** + * Set Indicator Short Name and also we can define Buffers Labels ... + */ +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +/** + * Define Required Buffers ... + */ +void DefineBuffers() +{ + // + // Plot Buffers ... + + // + // MA Buffer ... + + // + ENUM_DRAW_TYPE maDrawType = showMA ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(maBufferIndex, PLOT_SHOW_DATA, showMA); + PlotIndexSetInteger(maBufferIndex, PLOT_DRAW_TYPE, maDrawType); + + // + PlotIndexSetDouble(maBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + // LONG SL Buffer ... + + // + ENUM_DRAW_TYPE longSLDrawType = showLongSL ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(longSLBuffer, true); + SetIndexBuffer(longSLBufferIndex, longSLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(longSLBufferIndex, PLOT_SHOW_DATA, showLongSL); + PlotIndexSetInteger(longSLBufferIndex, PLOT_DRAW_TYPE, longSLDrawType); + + // + PlotIndexSetDouble(longSLBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + // SHORT SL Buffer ... + + // + ENUM_DRAW_TYPE shortSLDrawType = showShortSL ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(shortSLBuffer, true); + SetIndexBuffer(shortSLBufferIndex, shortSLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(shortSLBufferIndex, PLOT_SHOW_DATA, showShortSL); + PlotIndexSetInteger(shortSLBufferIndex, PLOT_DRAW_TYPE, shortSLDrawType); + + // + PlotIndexSetDouble(shortSLBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + // LONG Reject ... + + // + ENUM_DRAW_TYPE longRejectDrawType = showLongReject ? DRAW_ARROW : DRAW_NONE; + + // + ArraySetAsSeries(longRejectBuffer, true); + SetIndexBuffer(longRejectBufferIndex, longRejectBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(longRejectBufferIndex, PLOT_SHOW_DATA, showLongReject); + PlotIndexSetInteger(longRejectBufferIndex, PLOT_DRAW_TYPE, longRejectDrawType); + + // + PlotIndexSetDouble(longRejectBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(longRejectBufferIndex, PLOT_ARROW, longRejectArrowCode); + + // + // SHORT Reject ... + + // + ENUM_DRAW_TYPE shortRejectDrawType = showShortReject ? DRAW_ARROW : DRAW_NONE; + + // + ArraySetAsSeries(shortRejectBuffer, true); + SetIndexBuffer(shortRejectBufferIndex, shortRejectBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(shortRejectBufferIndex, PLOT_SHOW_DATA, showShortReject); + PlotIndexSetInteger(shortRejectBufferIndex, PLOT_DRAW_TYPE, shortRejectDrawType); + + // + PlotIndexSetDouble(shortRejectBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(shortRejectBufferIndex, PLOT_ARROW, shortRejectArrowCode); + + // + // UP Trend ... + + // + ENUM_DRAW_TYPE upTrendDrawType = showUpTrend ? DRAW_ARROW : DRAW_NONE; + + // + ArraySetAsSeries(upTrendBuffer, true); + SetIndexBuffer(upTrendBufferIndex, upTrendBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(upTrendBufferIndex, PLOT_SHOW_DATA, showUpTrend); + PlotIndexSetInteger(upTrendBufferIndex, PLOT_DRAW_TYPE, upTrendDrawType); + + // + PlotIndexSetDouble(upTrendBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(upTrendBufferIndex, PLOT_ARROW, upTrendArrowCode); + + // + // DOWN Trend ... + + // + ENUM_DRAW_TYPE downTrendDrawType = showDownTrend ? DRAW_ARROW : DRAW_NONE; + + // + ArraySetAsSeries(downTrendBuffer, true); + SetIndexBuffer(downTrendBufferIndex, downTrendBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(downTrendBufferIndex, PLOT_SHOW_DATA, showDownTrend); + PlotIndexSetInteger(downTrendBufferIndex, PLOT_DRAW_TYPE, downTrendDrawType); + + // + PlotIndexSetDouble(downTrendBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(downTrendBufferIndex, PLOT_ARROW, downTrendArrowCode); + + // + // DATA Buffers ... + + // + ArraySetAsSeries(atrBuffer, true); + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(adxBuffer, true); + SetIndexBuffer(adxBufferIndex, adxBuffer, INDICATOR_CALCULATIONS); +} + +/** + * Calculate Custom Buffers ... + * + * @param bar_index: Integer, Represent Current Bar ... + * @param prevCalculated: Integer, Represent Previous Calculated Bars ... + * @param ratesTotal: Integer, Represents All Available Bars ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param close: Double Array, History of Close Prices ... + * @param low: Double Array, History of Low Prices ... + * @param tickVolume: Long, History of Tick Volumes on Bar ... + */ +void CalculateBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int barsLimit = startCalculationForLastBars > 0 + ? startCalculationForLastBars + : 0; + // + // bool canCalculate = true; + bool canCalculate = + barsLimit == 0 || + bar_index <= barsLimit; + if (canCalculate) + { + // + CalculateValues( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + } + else + { + FillBuffersZero(bar_index); + } +} + +/** + * Fill All Bufers to Zero Vlue for Specified Bar Index ... + * + * @param barIndex: Integer ... + */ +void FillBuffersZero(int barIndex) +{ + // + maBuffer[barIndex] = 0; + atrBuffer[barIndex] = 0; + adxBuffer[barIndex] = 0; + longSLBuffer[barIndex] = 0; + shortSLBuffer[barIndex] = 0; + upTrendBuffer[barIndex] = 0; + downTrendBuffer[barIndex] = 0; + longRejectBuffer[barIndex] = 0; + shortRejectBuffer[barIndex] = 0; +} + +/** + * Calculate Vales ... + * + * @param bar_index: Integer, Represent Current Bar ... + * @param prevCalculated: Integer, Represent Previous Calculated Bars ... + * @param ratesTotal: Integer, Represents All Available Bars ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param close: Double Array, History of Close Prices ... + * @param low: Double Array, History of Low Prices ... + * @param tickVolume: Long, History of Tick Volumes on Bar ... + */ +void CalculateValues( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + XOHCL iBar; + bool isInited = iBar.Init( + _Symbol, + _Period, + bar_index // + ); + if (!isInited) + { + // + iBar.Clean(); + return; + } + + // + XOHCL pBar; + isInited = iBar.GetPreviousBar(pBar); + if (!isInited) + { + // + iBar.Clean(); + pBar.Clean(); + return; + } + + // + double iPrice = GetAppliedPrice( + appliedTo, + open, + high, + low, + close, + bar_index // + ); + + // + double iMa = maBuffer[bar_index]; + double iAtr = atrBuffer[bar_index]; + double iAdx = adxBuffer[bar_index]; + double iAppliedAtr = iAtr * atrMultiplier; + + // + double points = GetPoints(_Symbol); + double points10 = 10 * points; + + // + // Calculate SL Values ... + + // + double iLongSL = iPrice - iAppliedAtr; + double iShortSL = iPrice + iAppliedAtr; + + // + // Calculate Trend Values ... + + // + bool isUpTrend = + // + iPrice > iMa && + iBar.open < iMa && + iAdx > adxThreshold + // + ; + + // + bool isDownTrend = + // + iPrice < iMa && + iBar.open > iMa && + iAdx > adxThreshold + // + ; + + // + double upTrendValue = 0; + double downTrendValue = 0; + if (isUpTrend) + { + // + lastBullishTrend = iBar.time; + upTrendValue = iBar.low - points10; + } + if (isDownTrend) + { + // + lastBearishTrend = iBar.time; + downTrendValue = iBar.high + points10; + } + + // + // Calculate Rejection Values ... + + // + double fiboUpDown = GetFibonacciLevel( + iBar.high, + iBar.low, + X_FIBO_LEVEL_382, + X_DIRECTION_BEARISH // + ); + double fiboDownUp = GetFibonacciLevel( + iBar.high, + iBar.low, + X_FIBO_LEVEL_382, + X_DIRECTION_BULLISH // + ); + + // + bool hasFiboToUpPressure = + fiboDownUp > 0 && + fiboDownUp <= iBar.GetDown(); + bool hasFiboToDownPressure = + fiboUpDown > 0 && + fiboUpDown >= iBar.GetUp(); + + // + bool isLongReject = + // + iBar.low < iMa && + iBar.high >= iMa && + iBar.GetDown() >= iMa + // + ; + bool isStrongLongReject = + iBar.IsBullish() && + isLongReject; + bool isPressuredLongReject = + isLongReject && + hasFiboToUpPressure; + bool isPressuredStrongLongReject = + isStrongLongReject && + isPressuredLongReject; + + // + bool isShortReject = + // + iBar.high > iMa && + iBar.low <= iMa && + iBar.GetUp() <= iMa + // + ; + bool isStrongShortReject = + iBar.IsBearish() && + isShortReject; + bool isPressuredShortReject = + isShortReject && + hasFiboToDownPressure; + bool isPressuredStrongShortReject = + isStrongShortReject && + isPressuredShortReject; + + // + double iLongRejectValue = 0; + double iShortRejectValue = 0; + + // + bool isAppliedLongReject = false; + bool isAppliedShortReject = false; + switch (rejectionType) + { + // + case XWZ_REJECTION_BAR: + isAppliedLongReject = isLongReject; + isAppliedShortReject = isShortReject; + break; + + // + case XWZ_REJECTION_STRONG_BAR: + isAppliedLongReject = isStrongLongReject; + isAppliedShortReject = isStrongShortReject; + break; + + // + case XWZ_REJECTION_PRESSURED_BAR: + isAppliedLongReject = isPressuredLongReject; + isAppliedShortReject = isPressuredShortReject; + break; + + // + case XWZ_REJECTION_STRONG_PRESSURED_BAR: + isAppliedLongReject = isPressuredStrongLongReject; + isAppliedShortReject = isPressuredStrongShortReject; + break; + } + + // + // Calculate Rejection Verification Values ... + + // + int iLLIDX = pBar + .FindLowestIndex( + rejectionVerificationLength, + MODE_LOW // + ); + datetime iLLTime = iTime( + _Symbol, + _Period, + iLLIDX // + ); + double iLL = iLow( + _Symbol, + _Period, + iLLIDX // + ); + + // + int iHHIDX = pBar + .FindHighestIndex( + rejectionVerificationLength, + MODE_HIGH // + ); + datetime iHHTime = iTime( + _Symbol, + _Period, + iHHIDX // + ); + double iHH = iHigh( + _Symbol, + _Period, + iHHIDX // + ); + + // + bool isLLBreaked = false; + bool isHHBreaked = false; + if (rejectionVerificationLength > 0) + { + // + for (int i = bar_index + 1; i < bar_index + rejectionVerificationLength; i++) + { + // + double iMaValue = maBuffer[i]; + + // + XOHCL iBar; + bool isInited = iBar.Init( + _Symbol, + _Period, + i // + ); + if (!isInited) + { + // + iBar.Clean(); + isLLBreaked = true; + isHHBreaked = true; + break; + } + + // + if (!isLLBreaked) + { + isLLBreaked = iBar.low < iMaValue; + } + + // + if (!isHHBreaked) + { + isHHBreaked = iBar.high > iMaValue; + } + + // + if (isLLBreaked && + isHHBreaked) + { + break; + } + } + } + + // + // Validate Rejections ... + + // + // -[] Before Reject Long, price + // must not touch Ma from Up for at least 3 Bar ... + bool isValidAppliedLongReject = + !isLLBreaked && + isAppliedLongReject; + + // + // -[] Before Reject Short Price + // must no touch Ma from down at least 3 Bar ... + bool isValidAppliedShortReject = + !isHHBreaked && + isAppliedShortReject; + + // + if (isValidAppliedLongReject) + { + iLongRejectValue = iBar.low - points10; + } + else + { + iLongRejectValue = 0; + } + + // + if (isValidAppliedShortReject) + { + iShortRejectValue = iBar.high + points10; + } + else + { + iShortRejectValue = 0; + } + + // + // Draw Verification Box ... + if (isValidAppliedLongReject || + isValidAppliedShortReject) + { + // + datetime time1 = iTime( + _Symbol, + _Period, + iBar.Index() + rejectionVerificationLength // + ); + datetime time2 = iTime( + _Symbol, + _Period, + iBar.Index() + 0 // + ); + string llName = ToString(iLLIDX) + "_" + + ToString(iLL) + "_" + + ToMD5(iLLTime); + CChartObjectTrend *llTrend; + llTrend = new CChartObjectTrend(); + bool isCreated = llTrend.Create( + 0, + llName, + 0, + time1, + iLL, + time2, + iLL // + ); + if (isCreated) + { + mXWZDrawnObjects.Add(llTrend); + } + + // + string hhName = ToString(iHHIDX) + "_" + + ToString(iHH) + "_" + + ToMD5(iHHTime); + CChartObjectTrend *hhTrend; + hhTrend = new CChartObjectTrend(); + isCreated = hhTrend.Create( + 0, + hhName, + 0, + time1, + iHH, + time2, + iHH // + ); + if (isCreated) + { + mXWZDrawnObjects.Add(hhTrend); + } + } + + // + int idx = -1; + int count = 0; + bool has = false; + + // + ENUM_X_DIRECTION trend = + IsValid(lastBullishTrend) && + lastBullishTrend > lastBearishTrend + ? X_DIRECTION_BULLISH + : IsValid(lastBearishTrend) && + lastBearishTrend > lastBullishTrend + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + bool hasTrend = HasDirection(trend); + bool hasBullishTrend = hasTrend && + IsBullish(trend); + bool hasBearishTrend = hasTrend && + IsBearish(trend); + + // + // Filling Buffers ... + + // + longSLBuffer[bar_index] = iLongSL; + shortSLBuffer[bar_index] = iShortSL; + + // + upTrendBuffer[bar_index] = upTrendValue; + downTrendBuffer[bar_index] = downTrendValue; + + // + longRejectBuffer[bar_index] = iLongRejectValue; + shortRejectBuffer[bar_index] = iShortRejectValue; + + // + // Cleanup Resources ... + + // + iBar.Clean(); + pBar.Clean(); +} + +// +// POIS Functions ... +void CalculatedPOIs( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + XOHCL iBar; + bool isInited = iBar.Init( + _Symbol, + _Period, + bar_index // + ); + if (!isInited) + { + // + iBar.Clean(); + return; + } + + // + XOHCL pBar; + isInited = iBar.GetPreviousBar(pBar); + if (!isInited) + { + // + iBar.Clean(); + pBar.Clean(); + return; + } + + // + // POI ... + DetectPOIs(iBar); + UpdatePOIs(iBar); + DrawPOIs(); +} + +// +void DetectPOIs( + XOHCL &bar // +) +{ + // + // Detect PullBack ... + + // + ENUM_X_DIRECTION pullbackDir; + bool hasPullBack = mXWZBarAnalyser.HasPullBack( + pullbackDir, + bar // + ); + bool hasBullishPullBack = + hasPullBack && + IsBullish(pullbackDir); + bool hasBearishPullBack = + hasPullBack && + IsBearish(pullbackDir); + + // + // Detect PinBar ... + + // + ENUM_X_DIRECTION pinBarDir; + bool hasPinBar = mXWZBarAnalyser.IsPinBar( + bar, + pinBarDir, + 0 // + ); + bool hasBullishPinBar = + hasPinBar && + IsBullish(pinBarDir); + bool hasBearishPinBar = + hasPinBar && + IsBearish(pinBarDir); + + // + // Detect Order Block ... + + // + XOHCL obBar; + XCOrderBlock *ob; + ENUM_X_DIRECTION obDir; + bool hasOB = mXWZBarAnalyser.HasOrderBlock( + bar, + obBar, + obDir // + ); + bool hasBullishOB = + hasOB && + IsBullish(obDir); + bool hasBearishOB = + hasOB && + IsBearish(obDir); + if (hasOB) + { + // + ob = new XCOrderBlock(); + bool isInited = ob.Init(obBar, obDir); + if (isInited) + { + // + ENUM_X_DIRECTION forDir = ob.GetDirection(); + + // + // Check OB Not Activated ... + XOHCL activationBar; + bool isActivationBarBodyIn = false; + bool isActivated = ob.IsActivated( + forDir, + activationBar, + isActivationBarBodyIn, + false, + _Period // + ); + + // + if (!isActivated) + { + // + Add( + ob, + mXWZUnActivatedOBs // + ); + } + + // + obBar.Clean(); + activationBar.Clean(); + } + } +} + +// +void UpdatePOIs( + XOHCL &bar // +) +{ + // + int count = -1; + bool has = false; + + // + if (!bar.IsValid()) + { + return; + } + + // + datetime to = bar.time; + + // + // Order Blocks ... + count = ArraySize(mXWZUnActivatedOBs); + has = IsValidSize(count); + if (has) + { + // + XCOrderBlock *tmps[]; + for (int i = 0; i < count; i++) + { + // + // Update To ... + mXWZUnActivatedOBs[i].To(to); + + // + // Check Activation ... + + // + // Check OB Not Activated ... + XOHCL activationBar; + bool isActivationBarBodyIn = false; + bool isActivated = mXWZUnActivatedOBs[i] + .IsActivated( + mXWZUnActivatedOBs[i].GetDirection(), + activationBar, + isActivationBarBodyIn, + false, + _Period // + ); + + // + activationBar.Clean(); + + // + if (!isActivated) + { + // + Add( + mXWZUnActivatedOBs[i], + tmps // + ); + } + else + { + // + Add( + mXWZUnActivatedOBs[i], + mXWZActivatedOBs // + ); + } + } + + // + Copy( + tmps, + mXWZUnActivatedOBs // + ); + } + + // + // Fair Value Gaps ... + count = ArraySize(mXWZUnActivatedFVGs); + has = IsValidSize(count); + if (has) + { + // + XCFVG *tmps[]; + for (int i = 0; i < count; i++) + { + // + // Update To ... + mXWZUnActivatedFVGs[i].To(to); + + // + // Check Activation ... + + // + // Check OB Not Activated ... + XOHCL activationBar; + bool isActivationBarBodyIn = false; + bool isActivated = mXWZUnActivatedOBs[i] + .IsActivated( + mXWZUnActivatedFVGs[i].GetDirection(), + activationBar, + isActivationBarBodyIn, + false, + _Period // + ); + + // + activationBar.Clean(); + + // + if (!isActivated) + { + // + Add( + mXWZUnActivatedFVGs[i], + tmps // + ); + } + } + + // + Copy( + tmps, + mXWZUnActivatedFVGs // + ); + } + + // +} + +// +void DrawPOIs() +{ + // + int count = 0; + bool has = false; + bool isCreated = false; + + // + mXWZDrawnObjects.Clear(); + + // + // Order Blocks ... + + // + // UnActivated ... + count = ArraySize(mXWZUnActivatedOBs); + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XCBaseObject *iObj; + isCreated = mXWZPOIDrawer + .CreateOrderBlock( + mXWZUnActivatedOBs[i], + iObj // + ); + if (isCreated) + { + mXWZDrawnObjects.Add(iObj); + } + } + } + + // + // Activated ... + count = ArraySize(mXWZActivatedOBs); + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = mXWZActivatedOBs[i]; + + // + bool isBullish = iOB.IsBullish(); + + // + XCBaseObject *iObj; + isCreated = mXWZPOIDrawer + .CreateOrderBlock( + iOB, + iObj // + ); + if (isCreated) + { + // + if (isBullish) + { + ((XCBullishOrderBlockObject *)iObj).ZoneFill(true); + } + else + { + ((XCBearishOrderBlockObject *)iObj).ZoneFill(true); + } + + // + mXWZDrawnObjects.Add(iObj); + } + } + } + + // + // Fair Value Gaps ... + count = ArraySize(mXWZUnActivatedFVGs); + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XCBaseObject *iObj; + isCreated = mXWZPOIDrawer + .CreateFairValueGap( + mXWZUnActivatedFVGs[i], + iObj // + ); + if (isCreated) + { + mXWZDrawnObjects.Add(iObj); + } + } + } +} + +// \ No newline at end of file diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index 3ff5c464..343da303 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -3588,6 +3588,45 @@ struct XMarketParser // }; +// +struct XPoint +{ + // + // Props ... + double value; + datetime at; + + // + XPoint() + { + Clean(); + } + + // + // Tools ... + + // + void Clean() + { + // + value = 0; + at = NULL; + + // + ZeroMemory(this); + } + + // + bool IsValid() + { + // + return value > 0 && + IsValid(at); + } + + // +}; + // // Specified Swing Point ... struct XSwingPoint diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index 8fe8d297..6b971a7d 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -2006,6 +2006,77 @@ void SortZones( Clean(tmpItems); } +/** + * Extract all Zones Which provided bar is Inside it ... + * + * @return ( int ) + */ +template +int ExtractInsideZones( + XOHCL &bar, // Bar ... + T *&zones[], // Source of Zones ... + T *&dest[] // Dest (all inside Zones) ... +) +{ + // + int result = 0; + + // + Clean(dest); + + // + int count = ArraySize(zones); + bool isValid = bar.IsValid() && + IsValidSize(count); + if (!isValid) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + T *iZone = zones[i]; + + // + bool isHighInside = IsInside( + bar.high, + iZone // + ); + + // + bool isLowInside = IsInside( + bar.low, + iZone // + ); + + // + bool isInside = + isLowInside && + isHighInside; + + // + if (isInside) + { + // + Add( + iZone, + dest // + ); + } + + // + ZeroMemory(iZone); + } + + // + result = ArraySize(dest); + + // + return result; +} + // template int FilterZones( diff --git a/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 b/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 index 44903236..8fa72127 100644 --- a/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 @@ -1094,9 +1094,29 @@ class XCX121SMCXWZSignalDetector : public XCBase ZeroMemory(newAnalyseFVG); } + // + // Reading Trand Line Value ... + double zValue = workingZone.GetOrderFlowTrendLinePrice( + zIndex, + period // + ); + double cValue = workingZone.GetOrderFlowTrendLinePrice( + cIndex, + period // + ); + double pValue = workingZone.GetOrderFlowTrendLinePrice( + pIndex, + period // + ); + double ppValue = workingZone.GetOrderFlowTrendLinePrice( + ppIndex, + period // + ); + // // TODO: Implement Trend Line Trading Senario ... + // // TODO: Implement Quarter Line Trading Senario ...