diff --git a/Documents/BKP/121.smc.strategy.tmp.mq5 b/Documents/BKP/121.smc.strategy.tmp.mq5 index 7aefd587..26e37223 100644 --- a/Documents/BKP/121.smc.strategy.tmp.mq5 +++ b/Documents/BKP/121.smc.strategy.tmp.mq5 @@ -547,3 +547,585 @@ // return result; } + +//////////////////////////////////////////////////////////////////////// + + + // + int supplyZonesCount = ArraySize(supplyAndDemandZoneState.supplyZones); + int demandZonesCount = ArraySize(supplyAndDemandZoneState.demandZones); + + // + XOHCL swingHighs[]; + Copy( + orderBlocksState.swingHighs, + swingHighs // + ); + Copy( + fvgsState.swingHighs, + swingHighs, + false // + ); + Copy( + triggerState.swingHighs, + swingHighs, + false // + ); + + // + XOHCL swingLows[]; + Copy( + orderBlocksState.swingLows, + swingLows // + ); + Copy( + fvgsState.swingLows, + swingLows, + false // + ); + Copy( + triggerState.swingLows, + swingLows, + false // + ); + + // + int swingHighsCount = ArraySize(swingHighs); + int swingLowsCount = ArraySize(swingLows); + if (!IsValidSize(swingLowsCount) || + !IsValidSize(swingHighsCount) || + !IsValidSize(supplyZonesCount) || + !IsValidSize(demandZonesCount)) + { + return result; + } + + // + XOHCL zBar; + bool isInited = zBar.Init( + Symbol(), + Period(), + 0 // + ); + if (!isInited) + { + return result; + } + + // + // Detect Swing High and Low as Market Structure Boundaries ... + + // + // Swing High ... + XOHCL tmpBar; + for (int i = 0; i < swingHighsCount; i++) + { + // + XOHCL iSwing = swingHighs[i]; + + // + if (!tmpBar.IsValid() || + tmpBar.high < iSwing.high) + { + tmpBar = iSwing; + } + } + if (tmpBar.IsValid()) + { + // + mSwingHigh = tmpBar; + string name = tmpBar.GetTag(ToString(X_POI_SWING_HIGH)); + if (mSwingHighObject != NULL) + { + mSwingHighObject.Delete(); + } + mSwingHighObject = new CChartObjectHLine(); + bool isCreated = mSwingHighObject.Create( + ChartIdentification(), + name, + SubWindowIdentification(), + tmpBar.high // + ); + if (isCreated) + { + // + mSwingHighObject.Width(2); + mSwingHighObject.Color(clrRed); + mSwingHighObject.Style(STYLE_DASHDOTDOT); + } + } + + // + // Swing Low ... + tmpBar.Clean(); + for (int i = 0; i < swingLowsCount; i++) + { + // + XOHCL iSwing = swingLows[i]; + + // + if (!tmpBar.IsValid() || + tmpBar.low > iSwing.low) + { + tmpBar = iSwing; + } + } + if (tmpBar.IsValid()) + { + // + mSwingLow = tmpBar; + string name = tmpBar.GetTag(ToString(X_POI_SWING_LOW)); + if (mSwingLowObject != NULL) + { + mSwingLowObject.Delete(); + } + mSwingLowObject = new CChartObjectHLine(); + bool isCreated = mSwingLowObject.Create( + ChartIdentification(), + name, + SubWindowIdentification(), + tmpBar.low // + ); + if (isCreated) + { + // + mSwingLowObject.Width(2); + mSwingLowObject.Color(clrLime); + mSwingLowObject.Style(STYLE_DASHDOTDOT); + } + } + tmpBar.Clean(); + + // + // Demand Zone ... + for (int i = 0; i < demandZonesCount; i++) + { + // + // Demand Zone ... + XZone iDemandZone = supplyAndDemandZoneState.demandZones[i]; + conditions.demandZone = iDemandZone; + + // + // TODO: Remove this ... + // XCDemandZoneObject *iDemandZoneObj; + // bool isCreated = mPOIDrawer.CreateDemandZone( + // iDemandZone, + // iDemandZoneObj // + // ); + + // + // Order Blocks ... + int orderBlocksCount = ArraySize(orderBlocksState.bullishOrderBlocks); + if (IsValidSize(orderBlocksCount)) + { + // + for (int j = 0; j < orderBlocksCount; j++) + { + // + XZone jZone = orderBlocksState.bullishOrderBlocks[j]; + + // + bool isInside = + (jZone.lower > iDemandZone.lower && + jZone.lower < iDemandZone.upper) || + (jZone.lower < iDemandZone.lower); + if (isInside) + { + // + jZone.to = TimeCurrent(); + + // + // TODO: Remove this ... + // XCBullishOrderBlockObject *iBullOBObj; + // bool isCreated = mPOIDrawer.CreateBullishOrderBlock( + // jZone, + // iBullOBObj // + // ); + + AddRef( + jZone, + conditions.bullishOrderBlocks // + ); + } + } + } + + // + // Support Zones ... + int supportsCount = ArraySize(fvgsState.supportZones); + if (IsValidSize(supportsCount)) + { + // + for (int j = 0; j < supportsCount; j++) + { + // + XOHCL jBar = fvgsState.supportZones[j]; + + // + bool isInside = + (jBar.low > iDemandZone.lower && + jBar.low < iDemandZone.upper) || + (jBar.low < iDemandZone.lower); + if (isInside) + { + // + // TODO: Remove this ... + // XCSupportZoneObject *iSupportZoneObj; + // bool isCreated = mPOIDrawer.CreateSupportZone( + // jBar, + // iSupportZoneObj, + // TimeCurrent() // + // ); + + // + AddRef( + jBar, + conditions.supports // + ); + } + } + } + + // + // Bullish FVGs ... + int fvgsCount = ArraySize(fvgsState.bullishFVGs); + if (IsValidSize(fvgsCount)) + { + // + for (int j = 0; j < fvgsCount; j++) + { + // + XZone jFVG = fvgsState.bullishFVGs[j]; + + // + bool isInside = + jFVG.from > iDemandZone.from && + jFVG.lower < iDemandZone.upper && + jFVG.upper > iDemandZone.upper; + if (isInside) + { + // + jFVG.to = TimeCurrent(); + + // + // TODO: Remove This ... + // XCBullishFVGObject *iObj; + // bool isCreated = mPOIDrawer.CreateBullishFVG( + // jFVG, + // iObj // + // ); + + // + AddRef( + jFVG, + conditions.bullishFVGs // + ); + } + } + } + + // + // Swing Lows ... + int swingLowsCount = ArraySize(triggerState.swingLows); + if (IsValidSize(swingLowsCount)) + { + // + for (int j = 0; j < swingLowsCount; j++) + { + // + XOHCL jBar = triggerState.swingLows[j]; + + // + bool isInside = + jBar.time > iDemandZone.from && + jBar.low > iDemandZone.lower && + jBar.GetDown() < iDemandZone.upper; + if (isInside) + { + // + // TODO: Remve this ... + // XCSwingLowObject *iObj; + // bool isCreated = mPOIDrawer.CreateSwingLow( + // jBar, + // iObj // + // ); + + // + AddRef( + jBar, + conditions.swingLows // + ); + } + } + } + + // + // Bullish Momentum Bars ... + int bullishMomentumBarsCount = ArraySize(triggerState.momentumBars); + if (IsValidSize(bullishMomentumBarsCount)) + { + // + for (int j = 0; j < bullishMomentumBarsCount; j++) + { + // + XOHCL jBar = triggerState.momentumBars[j]; + + // + bool isInside = + jBar.IsBullish() && + jBar.time > iDemandZone.from && + jBar.low > iDemandZone.lower && + jBar.low < iDemandZone.upper; + if (isInside) + { + // + // TODO: Remove this ... + // XCBullishMomentumBarObject *iObj; + // bool isCreated = mPOIDrawer.CreateBullishMomentumBar( + // jBar, + // iObj // + // ); + + // + AddRef( + jBar, + conditions.bullishMomentumBars // + ); + } + } + } + + // + // Bullish Rejection Bars ... + int bullishRejectionBarsCount = ArraySize(triggerState.rejectionBars); + if (IsValidSize(bullishRejectionBarsCount)) + { + // + for (int j = 0; j < bullishRejectionBarsCount; j++) + { + // + XOHCL jBar = triggerState.rejectionBars[j]; + + // + bool isInside = + jBar.GetLowShadow() > jBar.GetHighShadow() && + jBar.time > iDemandZone.from && + jBar.low > iDemandZone.lower && + jBar.low < iDemandZone.upper; + if (isInside) + { + // + // TODO: Remove this ... + XCBullishRejectionBarObject *iObj; + bool isCreated = mPOIDrawer.CreateBullishRejectionBar( + jBar, + iObj // + ); + + // + AddRef( + jBar, + conditions.bullishRejectionBars // + ); + } + } + } + } + + // + // Supply Zone ... + // for (int i = 0; i < demandZonesCount; i++) + // { + // // + // // Supply Zone ... + // XZone iSupplyZone = supplyAndDemandZoneState.supplyZones[i]; + // conditions.supplyZone = iSupplyZone; + + // // + // // Order Blocks ... + // int orderBlocksCount = ArraySize(orderBlocksState.bearishOrderBlocks); + // if (IsValidSize(orderBlocksCount)) + // { + // // + // for (int j = 0; j < orderBlocksCount; j++) + // { + // // + // XZone jZone = orderBlocksState.bearishOrderBlocks[j]; + + // // + // bool isInside = + // jZone.from > iSupplyZone.from && + // jZone.upper > iSupplyZone.lower && + // jZone.upper < iSupplyZone.upper; + // if (isInside) + // { + // // + // AddRef( + // jZone, + // conditions.bearishOrderBlocks // + // ); + // } + // } + // } + + // // + // // Resistance Zones ... + // int resistancesCount = ArraySize(fvgsState.resistanceZones); + // if (IsValidSize(resistancesCount)) + // { + // // + // for (int j = 0; j < resistancesCount; j++) + // { + // // + // XOHCL jBar = fvgsState.resistanceZones[j]; + + // // + // bool isInside = + // jBar.time > iSupplyZone.from && + // jBar.high > iSupplyZone.lower && + // jBar.high < iSupplyZone.upper; + // if (isInside) + // { + // // + // AddRef( + // jBar, + // conditions.resistances // + // ); + // } + // } + // } + + // // + // // Bearish FVGs ... + // int fvgsCount = ArraySize(fvgsState.bearishFVGs); + // if (IsValidSize(fvgsCount)) + // { + // // + // for (int j = 0; j < fvgsCount; j++) + // { + // // + // XZone jZone = fvgsState.bearishFVGs[j]; + + // // + // bool isInside = + // jZone.from > iSupplyZone.from && + // jZone.upper > iSupplyZone.lower && + // jZone.upper < iSupplyZone.upper; + // if (isInside) + // { + // // + // AddRef( + // jZone, + // conditions.bearishFVGs // + // ); + // } + // } + // } + + // // + // // Swing Highs ... + // int swingHighsCount = ArraySize(triggerState.swingHighs); + // if (IsValidSize(swingHighsCount)) + // { + // // + // for (int j = 0; j < swingHighsCount; j++) + // { + // // + // XOHCL jBar = triggerState.swingHighs[j]; + + // // + // bool isInside = + // jBar.time > iSupplyZone.from && + // jBar.high > iSupplyZone.lower && + // jBar.high < iSupplyZone.upper; + // if (isInside) + // { + // // + // AddRef( + // jBar, + // conditions.swingHighs // + // ); + // } + // } + // } + + // // + // // Bearish Momentum Bars ... + // int bearishMomentumBarsCount = ArraySize(triggerState.momentumBars); + // if (IsValidSize(bearishMomentumBarsCount)) + // { + // // + // for (int j = 0; j < bearishMomentumBarsCount; j++) + // { + // // + // XOHCL jBar = fvgsState.momentumBars[j]; + + // // + // bool isInside = + // jBar.IsBearish() && + // jBar.time > iSupplyZone.from && + // jBar.high > iSupplyZone.lower && + // jBar.high < iSupplyZone.upper; + // if (isInside) + // { + // // + // AddRef( + // jBar, + // conditions.bearishMomentumBars // + // ); + // } + // } + // } + + // // + // // Bearish Rejection Bars ... + // int bearishRejectionBarsCount = ArraySize(triggerState.rejectionBars); + // if (IsValidSize(bearishRejectionBarsCount)) + // { + // // + // for (int j = 0; j < bearishRejectionBarsCount; j++) + // { + // // + // XOHCL jBar = fvgsState.rejectionBars[j]; + + // // + // bool isInside = + // jBar.GetHighShadow() > jBar.GetLowShadow() && + // jBar.time > iSupplyZone.from && + // jBar.high > iSupplyZone.lower && + // jBar.high < iSupplyZone.upper; + // if (isInside) + // { + // // + // AddRef( + // jBar, + // conditions.bearishRejectionBars // + // ); + // } + // } + // } + // } + + // + bool isConditionReadyForDemand = + conditions.demandZone.IsValid() && + (ArraySize(conditions.supports) > 0 || + ArraySize(conditions.swingLows) > 0 || + ArraySize(conditions.bullishFVGs) > 0 || + ArraySize(conditions.bullishOrderBlocks) > 0 || + ArraySize(conditions.bullishMomentumBars) > 0 || + ArraySize(conditions.bullishRejectionBars) > 0); + + // + bool isConditionReadyForSupply = + conditions.supplyZone.IsValid() && + (ArraySize(conditions.swingHighs) > 0 || + ArraySize(conditions.bearishFVGs) > 0 || + ArraySize(conditions.resistances) > 0 || + ArraySize(conditions.bearishOrderBlocks) > 0 || + ArraySize(conditions.bearishMomentumBars) > 0 || + ArraySize(conditions.bearishRejectionBars) > 0); + + // + result = isConditionReadyForDemand || + isConditionReadyForSupply; diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index ac32b079..b91ce672 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -7860,12 +7860,6 @@ double GetPriceChanged( _length = 2; } - // - if (_factor < 0.01) - { - _factor = 0.01; - } - // double closes[]; int copiedCloses = CopyClose( @@ -7881,7 +7875,7 @@ double GetPriceChanged( } // - double change = (closes[0] - close[5]) / close[5] * 100; + double change = (closes[0] - closes[5]) / closes[5] * 100; result = change; // diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index a9d89520..828b596f 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -1644,4 +1644,71 @@ bool AddIfNotExists( return result; } +// +// State Extensions ... + +/** + * Check State has Bullish Trend or not ... + * + * @param state: XPOIState instance ... + * + * @return ( bool ) + */ +bool HasBullishTrend(XPOIState &state) +{ + // + bool result = false; + + // + // For Bullish Trends ... + int count = ArraySize(state.swingLows); + result = count >= 2; + if (!result) + { + return result; + } + + // + XOHCL lastSwing = state.swingLows[count - 1]; + XOHCL prevSwing = state.swingLows[count - 2]; + + // + result = lastSwing.low > prevSwing.low; + + // + return result; +} + +/** + * Check State has Bearish Trend or not ... + * + * @param state: XPOIState instance ... + * + * @return ( bool ) + */ +bool HasBearishTrend(XPOIState &state) +{ + // + bool result = false; + + // + // For Bullish Trends ... + int count = ArraySize(state.swingHighs); + result = count >= 2; + if (!result) + { + return result; + } + + // + XOHCL lastSwing = state.swingHighs[count - 1]; + XOHCL prevSwing = state.swingHighs[count - 2]; + + // + result = lastSwing.high < prevSwing.high; + + // + return result; +} + // \ No newline at end of file diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index e52eb3ad..e213b48b 100644 Binary files a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 and b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 differ