diff --git a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 index c8b3264d..a5238534 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -46,6 +46,7 @@ enum ENUM_X_CYCLE_EVENTS SAR_CHANGE_DETECTED, NEW_PEAK_DETECTED, NEW_VALE_DETECTED, + PIVOT_POINT_DETECTED, VWAP_ORDER_CHANGE_ETECTED, VWAP_STATE_CHANGE_DETCTED, CONSOLIDATION_BREAKED_DETECTED @@ -1727,6 +1728,72 @@ class XC121SMCCycleHelper : public XCBase ); } } + + // + // Check Valid Peaks and Vales ... + if (isNewPeak || isNewVale) + { + // + int count = 0; + double value = 0; + int repetition = 0; + int minRepetition = 40; + ENUM_TIMEFRAMES period = GetPeriod(); + int periodSeconds = PeriodSeconds(period); + ENUM_XPV_PIVOTS type = isNewPeak + ? XPV_PEAK + : XPV_VALE; + + // + XValueChange lastChange; + XValueChange prevChange; + + // + count = CountPeaksChanges(); + if (isNewPeak && count >= 2) + { + // + lastChange = mPeaksChanges[count - 1]; + prevChange = mPeaksChanges[count - 2]; + } + + // + count = CountValesChanges(); + if (isNewVale && count >= 2) + { + // + lastChange = mValesChanges[count - 1]; + prevChange = mValesChanges[count - 2]; + } + + // + value = prevChange.after; + int delayTime = ((int)lastChange.time - (int)prevChange.time); + repetition = delayTime / periodSeconds; + + // + bool isValidPivot = repetition >= minRepetition; + if (isValidPivot) + { + // + XPVPivotPoint pivotPoint; + pivotPoint.type = type; + pivotPoint.value = value; + pivotPoint.repetition = repetition; + + // + AddRef( + pivotPoint, + mPivotPoints // + ); + + // + Add( + PIVOT_POINT_DETECTED, + events // + ); + } + } } // @@ -1748,6 +1815,9 @@ class XC121SMCCycleHelper : public XCBase XConsolidationZone mConsolidationZones[]; // Holds Consolidation Zones ... XConsolidationZone mActioveConsolidationZone; // Holds Actiove Consolidation Zone ... + // + XPVPivotPoint mPivotPoints[]; // Holds Pivots ... + // // Actions ... diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index 13893c63..d589e1d5 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -67,6 +67,7 @@ enum ENUM_X_121_SMC_SL_TYPES X_121_SMC_SL_TYPE_SWING, X_121_SMC_SL_TYPE_MOMENTUM, X_121_SMC_SL_TYPE_REJECTION, + X_121_SMC_SL_TYPE_TENKAN_SEN, }; // @@ -446,6 +447,59 @@ struct XPVPivot // }; +// +// Pivots ... +struct XPVPivotPoint +{ + // + // Props ... + double value; + int repetition; + ENUM_XPV_PIVOTS type; + + // + // Constructor ... + XPVPivotPoint() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() { + // + value = 0; + repetition = 0; + type = XPV_NONE; + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() { + // + bool result = false; + + // + result = + // + value > 0 && + repetition > 0 && + type != XPV_NONE + // + ; + + // + return result; + } +}; + // // Each Market Cycle (Time Frame) Conditions // Model as this Structure ... diff --git a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 index 8784ce16..914e9f5e 100644 --- a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 @@ -977,12 +977,101 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // XPVPivot lastPivot = orderFlow[pivotsCount - 1]; // + double zoneVerificationDivider = 10; bool isPeakInsideSupplyZone = false; bool isValeInsideDemandZone = false; // XPOIState state = conditions.consolidationConditions.state; + // // + // // Detect Order Block ... + // XCOrderBlock *orderBlock = NULL; + + // // + // int bullishOBCount = state.CountBullishOrderBlocks(); + // if (IsValidSize(bullishOBCount)) + // { + // // + // for (int i = 0; i < bullishOBCount; i++) + // { + // // + // XCOrderBlock *iZone = state.bullishOrderBlocks[i]; + + // // + // bool isInside = vale >= iZone.Lower() && + // vale <= iZone.Upper() && + // bid <= iZone.Lower() + ((iZone.Upper() - iZone.Lower()) / zoneVerificationDivider); + // if (isInside) + // { + // // + // orderBlock = iZone; + // break; + // } + // } + // } + + // // + // int bearishOBCount = state.CountBearishOrderBlocks(); + // if (IsValidSize(bearishOBCount)) + // { + // // + // for (int i = 0; i < bearishOBCount; i++) + // { + // // + // XCOrderBlock *iZone = state.bearishOrderBlocks[i]; + + // // + // bool isInside = peak >= iZone.Lower() && + // peak <= iZone.Upper() && + // bid >= iZone.Upper() - ((iZone.Upper() - iZone.Lower()) / zoneVerificationDivider); + // if (isInside) + // { + // // + // orderBlock = iZone; + // break; + // } + // } + // } + + // // + // result = orderBlock != NULL && + // orderBlock.IsValid(); + // if (!result) + // { + // return result; + // } + + // // + // // Draw Order Block ... + // orderBlock.To(TimeCurrent()); + // if (orderBlock.IsBullish()) + // { + // // + // XCBullishOrderBlockObject *iObj; + // bool isCreated = mPOIDrawer.CreateBullishOrderBlock( + // orderBlock, + // iObj // + // ); + // if (isCreated) + // { + // AddObjectIfNotExists(iObj); + // } + // } + // else + // { + // // + // XCBearishOrderBlockObject *iObj; + // bool isCreated = mPOIDrawer.CreateBearishOrderBlock( + // orderBlock, + // iObj // + // ); + // if (isCreated) + // { + // AddObjectIfNotExists(iObj); + // } + // } + // XCSupplyZone *supplyZone; int supplyCount = state.CountSupplyZones(); @@ -995,7 +1084,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy XCSupplyZone *iZone = state.supplyZones[i]; isPeakInsideSupplyZone = peak >= iZone.Lower() && peak <= iZone.Upper() && - bid >= iZone.Lower() + ((iZone.Upper() - iZone.Lower()) / 2); + bid >= iZone.Lower() + ((iZone.Upper() - iZone.Lower()) / zoneVerificationDivider); if (isPeakInsideSupplyZone) { // @@ -1017,7 +1106,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy XCDemandZone *iZone = state.demandZones[i]; isValeInsideDemandZone = vale >= iZone.Lower() && vale <= iZone.Upper() && - bid <= iZone.Lower() + ((iZone.Upper() - iZone.Lower()) / 2); + bid <= iZone.Lower() + ((iZone.Upper() - iZone.Lower()) / zoneVerificationDivider); if (isValeInsideDemandZone) { // @@ -1051,35 +1140,35 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy return result; } - // // - // if (isPeakAttacked) - // { - // // - // supplyZone.To(TimeCurrent()); - // XCSupplyZoneObject *iObj; - // bool isCreated = mPOIDrawer.CreateSupplyZone( - // supplyZone, - // iObj // - // ); - // if (isCreated) - // { - // AddObjectIfNotExists(iObj); - // } - // } - // else - // { - // // - // demandZone.To(TimeCurrent()); - // XCDemandZoneObject *iObj; - // bool isCreated = mPOIDrawer.CreateDemandZone( - // demandZone, - // iObj // - // ); - // if (isCreated) - // { - // AddObjectIfNotExists(iObj); - // } - // } + // + if (isPeakAttacked) + { + // + supplyZone.To(TimeCurrent()); + XCSupplyZoneObject *iObj; + bool isCreated = mPOIDrawer.CreateSupplyZone( + supplyZone, + iObj // + ); + if (isCreated) + { + AddObjectIfNotExists(iObj); + } + } + else + { + // + demandZone.To(TimeCurrent()); + XCDemandZoneObject *iObj; + bool isCreated = mPOIDrawer.CreateDemandZone( + demandZone, + iObj // + ); + if (isCreated) + { + AddObjectIfNotExists(iObj); + } + } // bool isBullish = @@ -2269,6 +2358,22 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy { result = conditions.triggerConditions.x121Conditions.sarBuffer[0]; } + else if (type == X_121_SMC_SL_TYPE_TENKAN_SEN) + { + // + double hh = zBar.FindHighest( + 9, + MODE_HIGH // + ); + double ll = zBar.FindLowest( + 9, + MODE_LOW // + ); + double mid = (hh - ll) / 2; + result = isBullish + ? ll - mid + : hh + mid; + } else if (type == X_121_SMC_SL_TYPE_CURRENT_SAR_BOX || type == X_121_SMC_SL_TYPE_LAST_SAR_CHANGED_BAR || type == X_121_SMC_SL_TYPE_LAST_DIRECTIONAL_SAR)