diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index abff976c..6ab1a225 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -2513,6 +2513,647 @@ class XCPOIDrawer : public XCBase return result; } + /** + * Draw Specified POI State ... + * + * @param state: XPOIState instance Reference ... + * @param drawnObjects: CArrayObj instance for Holding Drawn Objects ... + * @param ignoreSwingHighs: Boolean ... + * @param ignoreSwingLows: Boolean ... + * @param ignoreSupportZones: Boolean ... + * @param ignoreResistanceZones: Boolean ... + * @param ignoreSupplyZones: Boolean ... + * @param ignoreDemandZones: Boolean ... + * @param ignoreBullishOrderBlocks: Boolean ... + * @param ignoreBearishOrderBlocks: Boolean ... + * @param ignoreBullishFairValueGaps: Boolean ... + * @param ignoreBearishFairValueGaps: Boolean ... + * @param ignoreBullishRejectionBars: Boolean ... + * @param ignoreBearishRejectionBars: Boolean ... + * @param ignoreBullishMomentumBars: Boolean ... + * @param ignoreBearishMomentumBars: Boolean ... + */ + int DrawState( + XPOIState &state, + XCBaseObject *&drawnObjects[], + bool ignoreSwingHighs = false, + bool ignoreSwingLows = false, + bool ignoreSupportZones = false, + bool ignoreResistanceZones = false, + bool ignoreSupplyZones = false, + bool ignoreDemandZones = false, + bool ignoreBullishOrderBlocks = false, + bool ignoreBearishOrderBlocks = false, + bool ignoreBullishFairValueGaps = false, + bool ignoreBearishFairValueGaps = false, + bool ignoreBullishRejectionBars = false, + bool ignoreBearishRejectionBars = false, + bool ignoreBullishMomentumBars = false, + bool ignoreBearishMomentumBars = false // + ) + { + // + int result = 0; + + // + if (!state.IsValid() || + !state.HasChild()) + { + return result; + } + + // + Clean(drawnObjects); + + // + // SwingHighs ... + if (!ignoreSwingHighs) + { + // + int count = state.CountSwingHighs(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = state.swingHighs[i]; + XCSwingHighObject *iObj; + + // + bool isCreated = CreateSwingHigh( + iSwing, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // SwingLows ... + if (!ignoreSwingLows) + { + // + int count = state.CountSwingLows(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = state.swingLows[i]; + XCSwingLowObject *iObj; + + // + bool isCreated = CreateSwingLow( + iSwing, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // SupportZones ... + if (!ignoreSupportZones) + { + // + int count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = state.supportZones[i]; + XCSupportZoneObject *iObj; + + // + bool isCreated = CreateSupportZone( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // ResistanceZones ... + if (!ignoreResistanceZones) + { + // + int count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = state.resistanceZones[i]; + XCResistanceZoneObject *iObj; + + // + bool isCreated = CreateResistanceZone( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // SupplyZones ... + if (!ignoreSupplyZones) + { + // + int count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *iZone = state.supplyZones[i]; + XCSupplyZoneObject *iObj; + + // + bool isCreated = CreateSupplyZone( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // DemandZones ... + if (!ignoreDemandZones) + { + // + int count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone *iZone = state.demandZones[i]; + XCDemandZoneObject *iObj; + + // + bool isCreated = CreateDemandZone( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // BullishOrderBlocks ... + if (!ignoreBullishOrderBlocks) + { + // + int count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = state.bullishOrderBlocks[i]; + XCBullishOrderBlockObject *iObj; + + // + bool isCreated = CreateBullishOrderBlock( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // BearishOrderBlocks ... + if (!ignoreBearishOrderBlocks) + { + // + int count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = state.bearishOrderBlocks[i]; + XCBearishOrderBlockObject *iObj; + + // + bool isCreated = CreateBearishOrderBlock( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // BullishFairValueGaps ... + if (!ignoreBullishFairValueGaps) + { + // + int count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = state.bullishFairValueGaps[i]; + XCBullishFairValueGapObject *iObj; + + // + bool isCreated = CreateBullishFairValueGap( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // BearishFairValueGaps ... + if (!ignoreBearishFairValueGaps) + { + // + int count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = state.bearishFairValueGaps[i]; + XCBearishFairValueGapObject *iObj; + + // + bool isCreated = CreateBearishFairValueGap( + iZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // BullishRejectionBars ... + if (!ignoreBullishRejectionBars) + { + // + int count = state.CountBullishRejectionBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iBar = state.bullishRejectionBars[i]; + XCBullishRejectionBarObject *iObj; + + // + bool isCreated = CreateBullishRejectionBar( + iBar, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // BearishRejectionBars ... + if (!ignoreBearishRejectionBars) + { + // + int count = state.CountBearishRejectionBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iBar = state.bearishRejectionBars[i]; + XCBearishRejectionBarObject *iObj; + + // + bool isCreated = CreateBearishRejectionBar( + iBar, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // BullishMomentumBars ... + if (!ignoreBullishMomentumBars) + { + // + int count = state.CountBullishMomentumBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iBar = state.bullishMomentumBars[i]; + XCBullishMomentumBarObject *iObj; + + // + bool isCreated = CreateBullishMomentumBar( + iBar, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // BearishMomentumBars ... + if (!ignoreBearishMomentumBars) + { + // + int count = state.CountBearishMomentumBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iBar = state.bearishMomentumBars[i]; + XCBearishMomentumBarObject *iObj; + + // + bool isCreated = CreateBearishMomentumBar( + iBar, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + result = ArraySize(drawnObjects); + + // + return result; + } + + /** + * Draw Specific Pivot ... + * + * @param pivot: XPVPivot instance Reference ... + * @param drawState: Boolean ... + * @param filterByPrice: Boolean ... + * @param ignoreSwingHighs: Boolean ... + * @param ignoreSwingLows: Boolean ... + * @param ignoreSupportZones: Boolean ... + * @param ignoreResistanceZones: Boolean ... + * @param ignoreSupplyZones: Boolean ... + * @param ignoreDemandZones: Boolean ... + * @param ignoreBullishOrderBlocks: Boolean ... + * @param ignoreBearishOrderBlocks: Boolean ... + * @param ignoreBullishFairValueGaps: Boolean ... + * @param ignoreBearishFairValueGaps: Boolean ... + * @param ignoreBullishRejectionBars: Boolean ... + * @param ignoreBearishRejectionBars: Boolean ... + * @param ignoreBullishMomentumBars: Boolean ... + * @param ignoreBearishMomentumBars: Boolean ... + */ + int DrawPivot( + XPVPivot &pivot, + XCBaseObject *&drawnObjects[], + bool drawState = true, + bool ignoreSwingHighs = false, + bool ignoreSwingLows = false, + bool ignoreSupportZones = false, + bool ignoreResistanceZones = false, + bool ignoreSupplyZones = false, + bool ignoreDemandZones = false, + bool ignoreBullishOrderBlocks = false, + bool ignoreBearishOrderBlocks = false, + bool ignoreBullishFairValueGaps = false, + bool ignoreBearishFairValueGaps = false, + bool ignoreBullishRejectionBars = false, + bool ignoreBearishRejectionBars = false, + bool ignoreBullishMomentumBars = false, + bool ignoreBearishMomentumBars = false // + ) + { + // + int result = 0; + + // + Clean(drawnObjects); + + // + if (!pivot.IsValid()) + { + return result; + } + + // + // Draw Pivot it self ... + XCXPVPivotObject *iPivotObj; + iPivotObj = new XCXPVPivotObject(); + bool isCreated = iPivotObj.Create( + ChartIdentification(), + SubWindowIdentification(), + pivot // + ); + if (!isCreated) + { + return result; + } + + // + color clrPivotColor = pivot.IsPeak() + ? clrAqua + : clrMagenta; + iPivotObj.PivotColor(clrPivotColor); + iPivotObj.PivotWidth(2); + + // + Add( + (XCBaseObject *)iPivotObj, + drawnObjects // + ); + + // + result = ArraySize(drawnObjects); + + // + if (!drawState) + { + return result; + } + + // + if (!pivot.state.IsValid()) + { + return result; + } + + // + XCBaseObject *stateObjects[]; + int stateCount = DrawState( + pivot.state, + stateObjects, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + + // + if (IsValidSize(stateCount)) + { + // + Copy( + stateObjects, + drawnObjects, + false // Doesn't Clean ... + ); + } + + // + result = ArraySize(drawnObjects); + + // + return result; + } + // protected: // diff --git a/Documents/BKP/1/x.oepv.tmp.mq5 b/Documents/BKP/1/x.oepv.tmp.mq5 new file mode 100644 index 00000000..4ff13044 --- /dev/null +++ b/Documents/BKP/1/x.oepv.tmp.mq5 @@ -0,0 +1,75 @@ + // + // Decision ... + + // + // Peak ... + bool isDecisionNewPeak = decisionConditions.x121Conditions.isNewPeak; + bool isDecisionNewPeakOverLast = decisionConditions.x121Conditions.isNewPeakOverLast; + bool isDecisionNewPeakUnderLast = decisionConditions.x121Conditions.isNewPeakUnderLast; + double decisionPeak = decisionConditions.x121Conditions.peaksBuffer[1]; + XPVPivotPoint decisionPeakPivots[]; + XPVPivotPoint decisionLastPeakPivot; + XPVPivotPoint decisionPrevPeakPivot; + int decisionPeakPivotsCount = decisionCycleHelper + .FillPeakPivotPoints(decisionPeakPivots); + bool hasDecisionPeak = decisionPeakPivotsCount >= 2; + if (hasDecisionPeak) + { + // + decisionLastPeakPivot = decisionPeakPivots[decisionPeakPivotsCount - 1]; + decisionPrevPeakPivot = decisionPeakPivots[decisionPeakPivotsCount - 2]; + } + + // + // Vale ... + bool isDecisionNewVale = decisionConditions.x121Conditions.isNewVale; + bool isDecisionNewValeOverLast = decisionConditions.x121Conditions.isNewValeOverLast; + bool isDecisionNewValeUnderLast = decisionConditions.x121Conditions.isNewValeUnderLast; + double decisionVale = decisionConditions.x121Conditions.valesBuffer[1]; + XPVPivotPoint decisionValePivots[]; + XPVPivotPoint decisionLastValePivot; + XPVPivotPoint decisionPrevValePivot; + int decisionValePivotsCount = decisionCycleHelper + .FillValePivotPoints(decisionValePivots); + bool hasDecisionVale = decisionValePivotsCount >= 2; + if (hasDecisionVale) + { + // + decisionLastValePivot = decisionValePivots[decisionValePivotsCount - 1]; + decisionPrevValePivot = decisionValePivots[decisionValePivotsCount - 2]; + } + + // + bool isDecisionBullish = + // + hasDecisionVale && + isDecisionNewVale && + isDecisionNewValeUnderLast && + decisionLastValePivot.value > decisionPrevValePivot.value + // + ; + + // + bool isDecisionBearish = + // + false && + hasDecisionPeak && + decisionLastPeakPivot.value + // + ; + + // + if (isDecisionBullish || + isDecisionBearish) + { + // + conditions.pivot = + isDecisionBullish + ? decisionVale + : decisionPeak; + conditions.dir = + isDecisionBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + conditions.cycle = X_CYCLE_DECISION; + } diff --git a/Documents/BKP/3/x-smc.signal.conditions.detector.mq5 b/Documents/BKP/3/x-smc.signal.conditions.detector.mq5 new file mode 100644 index 00000000..2a7f7e2c --- /dev/null +++ b/Documents/BKP/3/x-smc.signal.conditions.detector.mq5 @@ -0,0 +1,6565 @@ +//////////////////////////////////////////// + + +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: +// Description: provide all Signalling functions ... +// +// +// 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 + +// +// Imports ... +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +// Definitions ... +struct X121SMCStrategyXVWPBSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + // Constructor ... + X121SMCStrategyXVWPBSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + ExtensionClean(); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + /** + * Clean Additional Properties ... + */ + void ExtensionClean() + { + } + + // +}; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXVWPBSiganlSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXVWPBSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Setup Conditions ... + + // + // Detect Market Trend ... + // ENUM_X_DIRECTION trend; + // bool hasTrend = consolidationCycleHelper + // .DetectTrend(trend); + // bool hasBullishTrend = hasTrend && + // IsBullish(trend); + // bool hasBearishTrend = hasTrend && + // IsBearish(trend); + // result = hasBullishTrend || + // hasBearishTrend; + // if (!result) + // { + // return result; + // } + + // + // Detect VWAP Bearish ... + + // + double vwapFast = triggerConditions.x121Conditions.vwapFastBuffer[1]; + double vwapMid = triggerConditions.x121Conditions.vwapMidBuffer[1]; + double vwapSlow = triggerConditions.x121Conditions.vwapSlowBuffer[1]; + + // + double vwaps[3] = { + vwapFast, + vwapMid, + vwapSlow, + }; + double vwapMax = GetMax(vwaps); + double vwapMin = GetMin(vwaps); + + // + bool isCloseOverVwapMax = + // + ask > vwapMax && + bid > vwapMax && + (cBar.low > vwapMax || + cBar.close > vwapMax) + // + ; + + // + bool isCloseUnderVwapMin = + // + ask < vwapMin && + bid < vwapMin && + (cBar.high < vwapMin || + cBar.close < vwapMin) + // + ; + + // + bool isVWapBullishState = triggerConditions.x121Conditions.isVWapBullishState; + bool isVWapSwitchedToBullishState = triggerConditions.x121Conditions.isVWapSwitchedToBullishState; + + // + bool isVWapBearishState = triggerConditions.x121Conditions.isVWapBearishState; + bool isVWapSwitchedToBearishState = triggerConditions.x121Conditions.isVWapSwitchedToBearishState; + + // + bool isVWapBullishOrdered = triggerConditions.x121Conditions.isVWapBullishOrdered; + bool isVWapSwitchedToBullishOrdered = triggerConditions.x121Conditions.isVWapSwitchedToBullishOrdered; + + // + bool isVWapBearishOrdered = triggerConditions.x121Conditions.isVWapBearishOrdered; + bool isVWapSwitchedToBearishOrdered = triggerConditions.x121Conditions.isVWapSwitchedToBearishOrdered; + + // + // Summary VWap ... + + // + bool isVwapBullishFormed = + // + isVWapSwitchedToBullishState + // isCloseOverVwapMax + // // + // && + // + // ( + // // + // // (isVWapBullishOrdered && + // // isVWapSwitchedToBullishState) + // // // + // // || + // // // + // // (isVWapBullishState && + // // isVWapSwitchedToBullishOrdered) + // // + // ) + // + ; + + // + bool isVwapBearishFormed = + // + isVWapSwitchedToBearishState + // isCloseUnderVwapMin + // // + // && + // + // ( + // // + // // (isVWapBearishOrdered && + // // isVWapSwitchedToBearishState) + // // // + // // || + // // // + // // (isVWapBearishState && + // // isVWapSwitchedToBearishOrdered) + // // + // ) + // + ; + + // + isBullish = + // hasBullishTrend && + isVwapBullishFormed; + + // + isBearish = + // hasBearishTrend && + isVwapBearishFormed; + + // + result = isBullish || + isBearish; + + // + // if (!result) + // { + // return result; + // } + + // // + // double sar = triggerConditions.x121Conditions.sarBuffer[1]; + + // // + // bool isSarBullish = triggerConditions.x121Conditions.isSarBullish; + // bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish; + + // // + // bool isSarBearish = triggerConditions.x121Conditions.isSarBearish; + // bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish; + + // // + // bool isSarBullishFormed = isSarBullish || + // isSarSwitchedToBullish; + + // // + // bool isSarBearishFormed = isSarBearish || + // isSarSwitchedToBearish; + + // // + // isBullish = + // isBullish && + // isSarBullishFormed; + + // // + // isBearish = + // isBearish && + // isSarBearishFormed; + + // // + // result = isBullish || + // isBearish; + // if (!result) + // { + // return result; + // } + + // // + // // Detect Pull Backs ... + + // // + // bool isSignalBarBullishPullBackFormed = + // cBar.IsBearish() && + // pBar.IsBullish() && + // cBar.low > pBar.low; + + // // + // bool isSignalBarBearishPullBackFormed = + // cBar.IsBullish() && + // pBar.IsBearish() && + // cBar.high < pBar.high; + + // // + // // Summary Pull Backs ... + + // // + // bool isBullishBarFormed = + // isSignalBarBullishPullBackFormed; + + // // + // bool isBearishhBarFormed = + // isSignalBarBearishPullBackFormed; + + // // + // isBullish = + // isBullish && + // isBullishBarFormed; + + // // + // isBearish = + // isBearish && + // isBearishhBarFormed; + + // // + // result = isBullish || + // isBearish; + // if (!result) + // { + // return result; + // } + + // // + // isBullish = + // // + // false + // // + // ; + + // // + // isBearish = + // // + // false + // // + // ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Clean Conditions for Regenerate ... + + // + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCXVWPBSiganlTrigger( + // + X121SMCStrategyXVWPBSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Trigger Conditions ... + + // + double vwapFast = triggerConditions.x121Conditions.vwapFastBuffer[1]; + double vwapMid = triggerConditions.x121Conditions.vwapMidBuffer[1]; + double vwapSlow = triggerConditions.x121Conditions.vwapSlowBuffer[1]; + + // + double vwaps[3] = { + vwapFast, + vwapMid, + vwapSlow, + }; + double vwapMax = GetMax(vwaps); + double vwapMin = GetMin(vwaps); + + // + bool isNewPeak = triggerConditions.x121Conditions.isNewPeak; + bool isNewPeakOverLast = triggerConditions.x121Conditions.isNewPeakOverLast; + bool isNewPeakUnderLast = triggerConditions.x121Conditions.isNewPeakUnderLast; + + // + bool isNewVale = triggerConditions.x121Conditions.isNewVale; + bool isNewValeOverLast = triggerConditions.x121Conditions.isNewValeOverLast; + bool isNewValeUnderLast = triggerConditions.x121Conditions.isNewValeUnderLast; + + // + double triggerPeak = triggerConditions.x121Conditions.peaksBuffer[1]; + double decisionPeak = decisionConditions.x121Conditions.peaksBuffer[1]; + double analysePeak = analyseConditions.x121Conditions.peaksBuffer[1]; + double verificationPeak = verificationConditions.x121Conditions.peaksBuffer[1]; + double consolidationPeak = consolidationConditions.x121Conditions.peaksBuffer[1]; + + // + double triggerVale = triggerConditions.x121Conditions.valesBuffer[1]; + double decisionVale = decisionConditions.x121Conditions.valesBuffer[1]; + double analyseVale = analyseConditions.x121Conditions.valesBuffer[1]; + double verificationVale = verificationConditions.x121Conditions.valesBuffer[1]; + double consolidationVale = consolidationConditions.x121Conditions.valesBuffer[1]; + + // + bool isPeaksSameFormed = + // + ( + // + triggerPeak == decisionPeak + // + ) + // + || + // + ( + // + triggerPeak == decisionPeak && + triggerPeak == analysePeak + // + ) + // + || + // + ( + // + triggerPeak == decisionPeak && + triggerPeak == analysePeak && + triggerPeak == verificationPeak + // + ) + // + || + // + ( + // + triggerPeak == decisionPeak && + triggerPeak == analysePeak && + triggerPeak == verificationPeak && + triggerPeak == consolidationPeak + // + ) + // + ; + + // + bool isValesSameFormed = + // + ( + // + triggerVale == decisionVale + // + ) + // + || + // + ( + // + triggerVale == decisionVale && + triggerVale == analyseVale + // + ) + // + || + // + ( + // + triggerVale == decisionVale && + triggerVale == analyseVale && + triggerVale == verificationVale + // + ) + // + || + // + ( + // + triggerVale == decisionVale && + triggerVale == analyseVale && + triggerVale == verificationVale && + triggerVale == consolidationVale + // + ) + // + ; + + // + isBullish = + // isValesSameFormed && + IsBullish(setupDir); + + // + isBearish = + // isPeaksSameFormed && + IsBearish(setupDir); + + // + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Check Last VWap State Change ... + XValueChange vwapStateChnges[]; + int vwapStateChngesCount = triggerCycleHelper + .FillVWapStateChanges(vwapStateChnges); + XValueChange lastVWapStateChnged; + bool hasLastVWapStateChanged = false; + if (IsValidSize(vwapStateChngesCount) && + vwapStateChngesCount >= 2) + { + // + lastVWapStateChnged = vwapStateChnges[vwapStateChngesCount - 2]; + hasLastVWapStateChanged = lastVWapStateChnged.IsValid(); + } + + // + double donOpenUpper = triggerConditions.x121Conditions.donOpenUpperBuffer[1]; + double donOpenLower = triggerConditions.x121Conditions.donOpenLowerBuffer[1]; + + // + double donCloseUpper = triggerConditions.x121Conditions.donCloseUpperBuffer[1]; + double donCloseLower = triggerConditions.x121Conditions.donCloseLowerBuffer[1]; + + // + bool isDonUpperBullish = donCloseUpper > donOpenUpper; + bool isDonUpperBearish = donCloseUpper < donOpenUpper; + + // + bool isDonLowerBullish = donCloseLower > donOpenLower; + bool isDonLowerBearish = donCloseLower < donOpenLower; + + // + bool isDonBullishFormed = + // + (isDonUpperBullish || + isDonLowerBullish) + // + ; + + // + bool isDonBearishFormed = + // + (isDonUpperBearish || + isDonLowerBearish) + // + ; + + // + isBullish = + (isNewValeOverLast || + isNewPeakOverLast) && + isDonBullishFormed && + hasLastVWapStateChanged && + (isBullish && + IsBullish(lastVWapStateChnged.dir)); + + // + isBearish = + (isNewPeakUnderLast || + isNewValeUnderLast) && + isDonBearishFormed && + hasLastVWapStateChanged && + (isBearish && + IsBearish(lastVWapStateChnged.dir)); + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + return result; + } + + // + // Selecting SL ... + + // + double longSL = 0; + double shortSL = 0; + double entry = GetEntry( + conditions.symbol, + setupDir // + ); + + // + double longDistance = MathAbs(vwapMax - MathMax(triggerVale, donCloseLower)) / 2; + double shortDistance = MathAbs(vwapMin - MathMin(triggerPeak, donCloseUpper)) / 2; + + // + longSL = entry - longDistance; + shortSL = entry + shortDistance; + + // + conditions.triggerTime = cTime; + conditions.sl = isBullish + ? vwapMin + : vwapMax; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + return result; +} + +// + + +////////////////////////////////////////// + +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: +// Description: provide all Signalling functions ... +// +// +// 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 + +// +// Imports ... +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +// Definitions ... +struct X121SMCStrategyXTWPVSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + + // + // Constructor ... + X121SMCStrategyXTWPVSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + ExtensionClean(); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + /** + * Clean Additional Properties ... + */ + void ExtensionClean() + { + } + + // +}; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXTWPVSiganlSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXTWPVSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Setup Conditions ... + + // + // Detect Market Trend ... + // ENUM_X_DIRECTION trend; + // bool hasTrend = verificationCycleHelper + // .DetectTrend(trend); + // bool hasBullishTrend = hasTrend && + // IsBullish(trend); + // bool hasBearishTrend = hasTrend && + // IsBearish(trend); + // result = hasBullishTrend || + // hasBearishTrend; + // if (!result) + // { + // return result; + // } + + // + // Check Exists Valid Peaks or Vales ... + + // + // Peaks ... + XPVPivotPoint validPeaks[]; + XPVPivotPoint lastValidPeak; + int validPeaksCount = triggerCycleHelper + .FillPeakPivotPoints(validPeaks); + bool hasValidPeaks = IsValidSize(validPeaksCount); + if (hasValidPeaks) + { + lastValidPeak = validPeaks[validPeaksCount - 1]; + } + + // + // Vales ... + XPVPivotPoint validVales[]; + XPVPivotPoint lastValidVale; + int validValesCount = triggerCycleHelper + .FillValePivotPoints(validVales); + bool hasValidVales = IsValidSize(validValesCount); + if (hasValidVales) + { + lastValidVale = validVales[validValesCount - 1]; + } + + // + // Looking For New Peak or Vale ... + + // + double peak = triggerConditions.x121Conditions.peaksBuffer[1]; + double cale = triggerConditions.x121Conditions.valesBuffer[1]; + + // + bool isNewPeak = triggerConditions.x121Conditions.isNewPeak; + bool isNewPeakOverLast = triggerConditions.x121Conditions.isNewPeakOverLast; + bool isNewPeakUnderLast = triggerConditions.x121Conditions.isNewPeakUnderLast; + + // + bool isNewVale = triggerConditions.x121Conditions.isNewVale; + bool isNewValeOverLast = triggerConditions.x121Conditions.isNewValeOverLast; + bool isNewValeUnderLast = triggerConditions.x121Conditions.isNewValeUnderLast; + + // + isBullish = + // + isNewPeak && + hasValidPeaks && + isNewPeakUnderLast && + lastValidPeak.IsValid() + // + ; + + // + isBearish = + // + isNewVale && + hasValidVales && + isNewValeOverLast && + lastValidVale.IsValid() + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Check Sar Change ... + + // + double sar = triggerConditions.x121Conditions.sarBuffer[1]; + bool isSarBullish = triggerConditions.x121Conditions.isSarBullish; + bool isSarBearish = triggerConditions.x121Conditions.isSarBearish; + + // + XValueChange lastSarChange; + bool hasLastSarChange = triggerCycleHelper + .GetLastSarChange(lastSarChange); + + // + isBullish = + // + isBullish && + isSarBullish && + hasLastSarChange && + sar > lastSarChange.before && + ask > lastSarChange.before && + bid > lastSarChange.before + // + ; + + // + isBearish = + // + isBearish && + isSarBearish && + hasLastSarChange && + sar < lastSarChange.before && + ask < lastSarChange.before && + bid < lastSarChange.before + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCXTWPVSiganlTrigger( + // + X121SMCStrategyXTWPVSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Trigger Conditions ... + + // + // Check VWap State ... + + // + bool isVWapBullishState = triggerConditions.x121Conditions.isVWapBullishState; + bool isVWapBearishState = triggerConditions.x121Conditions.isVWapBearishState; + + // + isBullish = + IsBullish(setupDir) && + isVWapBullishState; + + // + isBearish = + IsBearish(setupDir) && + isVWapBearishState; + + // + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Waitings For Sar Switched to Direction ... + + // + double sar = triggerConditions.x121Conditions.sarBuffer[1]; + + // + bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish; + bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish; + + // + isBullish = + // + isBullish && + isSarSwitchedToBullish + // + ; + + // + isBearish = + // + isBearish && + isSarSwitchedToBearish + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + return result; + } + + // + // Detect Nearest FVG or Supply Zone For Traget ... + + // + // Select Source State ... + XPOIState state = triggerState; + + // + double target = CalculateTarget( + cBar, + state, + setupDir // + ); + + // + result = target > 0; + if (!result) + { + return result; + } + + // + conditions.target = target; + conditions.triggerTime = cTime; + conditions.sl = isBullish + ? sar + : sar; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + return result; +} + +// + +////////////////////////////////////////// + +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Lib +// ------------------------------------------------- +// Name: +// Description: provide all Signalling functions ... +// +// +// 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 + +// +// Imports ... +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +// Definitions ... +struct X121SMCStrategyXPVSUPDEMSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + XCTicksZone *ticksZone; + XCSupplyZone *supplyZones[]; + XCDemandZone *demandZones[]; + datetime activeZoneFoundedAt; + XCSupplyZone *activeSupplyZone; + XCDemandZone *activeDemandZone; + + // + // Constructor ... + X121SMCStrategyXPVSUPDEMSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + ExtensionClean(); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + /** + * Clean Additional Properties ... + */ + void ExtensionClean() + { + // + ticksZone = NULL; + activeSupplyZone = NULL; + activeDemandZone = NULL; + activeZoneFoundedAt = NULL; + + // + Clean(supplyZones); + Clean(demandZones); + } + + /** + * Count Supply Zones ... + * + * @return ( int ) + */ + int CountSupplyZones() + { + return ArraySize(supplyZones); + } + + /** + * Count Demand Zones ... + * + * @return ( int ) + */ + int CountDemandZones() + { + return ArraySize(demandZones); + } + + /** + * Check Has Supply Zones ... + * + * @return ( bool ) + */ + bool HasSupplyZones() + { + return IsValidSize(CountSupplyZones()); + } + + /** + * Check Has Demand Zones ... + * + * @return ( bool ) + */ + bool HasDemandZones() + { + return IsValidSize(CountDemandZones()); + } + + /** + * Check Has Active Supply or Demand Zone ... + * + * @param _dir: ENUM_X_DIRECTION member Reference for Specify Active Zone ... + * + * @return ( bool ) + */ + bool HasActiveZone(ENUM_X_DIRECTION &_dir) + { + // + bool result = false; + + // + _dir = X_DIRECTION_NONE; + + // + // Check Supplies ... + bool hasActiveSupplyZone = activeSupplyZone != NULL && + activeSupplyZone.IsValid(); + + // + // Check Demnds ... + bool hasActiveDemandZone = activeDemandZone != NULL && + activeDemandZone.IsValid(); + + // + result = hasActiveSupplyZone || + hasActiveDemandZone; + if (!result) + { + return result; + } + + // + _dir = hasActiveDemandZone + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; + } + + /** + * Retrieve Active Zone Reference if Exists ... + * + * @return ( bool ) + */ + bool GetActiveZone(XCBarZone *&activeZone) + { + // + bool result = false; + + // + activeZone = NULL; + + // + ENUM_X_DIRECTION activeZoneDir; + result = HasActiveZone(activeZoneDir); + if (!result) + { + return result; + } + + // + if (IsBullish(activeZoneDir)) + { + // + activeDemandZone.To(TimeCurrent()); + activeZone = activeDemandZone; + } + else + { + // + activeSupplyZone.To(TimeCurrent()); + activeZone = activeSupplyZone; + } + + // + return result; + } + + /** + * Clean Active Zone ... + */ + void CleanActiveZone() + { + // + activeSupplyZone = NULL; + activeDemandZone = NULL; + activeZoneFoundedAt = NULL; + } + + /** + * Check Ticks Zone is Initialized or not ... + * @return ( bool ) + */ + bool HasTicksZone() + { + // + bool result = false; + + // + result = + // + ticksZone != NULL && + ticksZone.IsValid() && + IsValidSize(ticksZone.Count()) + // + ; + + // + return result; + } + + // +}; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXPVSUPDEMSiganlSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXPVSUPDEMSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Setup Conditions ... + + // + // Detect Market Trend ... + ENUM_X_DIRECTION trend; + bool hasTrend = consolidationCycleHelper + .DetectTrend(trend); + bool hasBullishTrend = hasTrend && + IsBullish(trend); + bool hasBearishTrend = hasTrend && + IsBearish(trend); + result = hasBullishTrend || + hasBearishTrend; + if (!result) + { + return result; + } + + // + // Select Source State ... + XPOIState state = consolidationState; + + // + // Detect Supply and Demand Zones ... + + // + // Supply ... + bool hasSupplyZones = conditions.HasSupplyZones(); + if (!hasSupplyZones) + { + // + int count = state.CountSupplyZones(); + for (int i = count - 1; i >= 0; i--) + { + // + XCSupplyZone *iZone = state.supplyZones[i]; + + // + bool isValid = + // + ask < iZone.Lower() && + bid < iZone.Lower() && + cBar.high < iZone.Lower() + // + ; + if (isValid) + { + // + Add( + iZone, + conditions.supplyZones // + ); + } + } + + // + hasSupplyZones = conditions.HasSupplyZones(); + result = hasSupplyZones; + if (!result) + { + return result; + } + } + + // + // Demand ... + bool hasDemandZones = conditions.HasDemandZones(); + if (!hasDemandZones) + { + // + int count = state.CountDemandZones(); + for (int i = count - 1; i >= 0; i--) + { + // + XCDemandZone *iZone = state.demandZones[i]; + + // + bool isValid = + // + ask > iZone.Upper() && + bid > iZone.Upper() && + cBar.low > iZone.Upper() + // + ; + if (isValid) + { + // + Add( + iZone, + conditions.demandZones // + ); + } + } + + // + hasDemandZones = conditions.HasDemandZones(); + result = hasDemandZones; + if (!result) + { + return result; + } + } + + // + // Waits For Price to Go Inside a Zone ... + ENUM_X_DIRECTION activeZoneDir = X_DIRECTION_NONE; + bool hasActiveZone = conditions.HasActiveZone(activeZoneDir); + if (!hasActiveZone) + { + // + // Looking Up For Active Zone ... + + // + // Supply ... + if (hasSupplyZones) + { + // + int count = conditions.CountSupplyZones(); + for (int i = count - 1; i >= 0; i--) + { + // + XCSupplyZone *iZone = conditions.supplyZones[i]; + + // + bool isValid = + // + ask <= iZone.Upper() && + bid <= iZone.Upper() && + ask >= iZone.Lower() && + bid >= iZone.Lower() && + cBar.high <= iZone.Upper() && + cBar.low >= iZone.Lower() + // + ; + if (isValid) + { + // + conditions.activeSupplyZone = iZone; + break; + } + } + } + + // + hasActiveZone = conditions.HasActiveZone(activeZoneDir); + if (!hasActiveZone) + { + // + // Demand ... + if (hasDemandZones) + { + // + int count = conditions.CountDemandZones(); + for (int i = count - 1; i >= 0; i--) + { + // + XCDemandZone *iZone = conditions.demandZones[i]; + + // + bool isValid = + // + ask <= iZone.Upper() && + bid <= iZone.Upper() && + ask >= iZone.Lower() && + bid >= iZone.Lower() && + cBar.high <= iZone.Upper() && + cBar.low >= iZone.Lower() + // + ; + if (isValid) + { + // + conditions.activeDemandZone = iZone; + break; + } + } + } + } + + // + hasActiveZone = conditions.HasActiveZone(activeZoneDir); + result = hasActiveZone; + if (!result) + { + return result; + } + + // + conditions.activeZoneFoundedAt = cTime; + } + + // + // Now we Have to Calculate Active Zones Ticks ... + + // + bool isValidDemandZone = + hasActiveZone && + hasBullishTrend && + IsBullish(activeZoneDir); + + // + bool isValidSupplyZone = + hasActiveZone && + hasBearishTrend && + IsBearish(activeZoneDir); + + // + result = isValidDemandZone || + isValidSupplyZone; + if (!result) + { + // + conditions.CleanActiveZone(); + return result; + } + + // + // Select Active Zone ... + XCBarZone *activeZone = NULL; + result = conditions.GetActiveZone(activeZone); + if (!result) + { + return result; + } + + // + // Extract Active Zone Start Bar ... + XOHCL fromBar; + datetime fromTime = activeZone.BarTime(); + result = triggerCycleHelper.GetBar( + fromBar, + fromTime // + ); + if (!result) + { + return result; + } + + // + bool hasTicksZone = conditions.HasTicksZone(); + if (!hasTicksZone) + { + // + // Istantiate Ticks Zone ... + conditions.ticksZone = new XCTicksZone(); + conditions.ticksZone.Levels(40); + } + + // + // Update Ticks Zone ... + result = conditions.ticksZone.Init( + fromBar, + cBar // + ); + if (!result) + { + return result; + } + + // + // Regenrate Conditions ... + hasTicksZone = conditions.HasTicksZone(); + result = hasTicksZone; + if (!result) + { + return result; + } + + // + // Make Sure we Have a Direction for Setup ... + isBullish = IsBullish(activeZoneDir); + isBearish = IsBearish(activeZoneDir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Check New Peaks or Vales Happens inside Zero Tick or Volume Percent Zone and + // also Active Zone ... + double peak = triggerConditions.x121Conditions.peaksBuffer[1]; + double vale = triggerConditions.x121Conditions.valesBuffer[1]; + bool isNewPeakOverLast = triggerConditions.x121Conditions.isNewPeakOverLast; + bool isNewValeUnderLast = triggerConditions.x121Conditions.isNewValeUnderLast; + + // + bool isPeakInsideActiveZone = + // + peak <= activeZone.Upper() && + peak >= activeZone.Lower() + // + ; + bool isValeInsideActiveZone = + // + vale <= activeZone.Upper() && + vale >= activeZone.Lower() + // + ; + + // + bool isPeakInsideZeroZone = false; + bool isValeInsideZeroZone = false; + int tzCount = conditions.ticksZone.Count(); + if (IsValidSize(tzCount)) + { + // + for (int i = 0; i < tzCount; i++) + { + // + XCTickZone *iTZ = conditions.ticksZone.GetZone(i); + + // + if (isBearish && + !isPeakInsideZeroZone) + { + // + isPeakInsideZeroZone = + // + peak <= iTZ.high && + peak >= iTZ.low && + (iTZ.percent == 0 || + iTZ.volumePercent == 0) + // + ; + } + + // + if (isBullish && + !isValeInsideZeroZone) + { + // + isValeInsideZeroZone = + // + vale <= iTZ.high && + vale >= iTZ.low && + (iTZ.percent == 0 || + iTZ.volumePercent == 0) + // + ; + } + + // + if (isPeakInsideZeroZone || + isValeInsideZeroZone) + { + break; + } + } + } + + // + isBullish = + // + isBullish && + isNewValeUnderLast && + isValeInsideZeroZone && + isValeInsideActiveZone + // + ; + + // + isBearish = + // + isBearish && + isNewPeakOverLast && + isPeakInsideZeroZone && + isPeakInsideActiveZone + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Clean Conditions for Regenerate ... + int activeZoneAge = (int)(cTime - conditions.activeZoneFoundedAt) / PeriodSeconds(conditions.period); + if (activeZoneAge >= 200) + { + conditions.Clean(); + } + + // + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCXPVSUPDEMSiganlTrigger( + // + X121SMCStrategyXPVSUPDEMSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Trigger Conditions ... + + // + // Select Active Zone Class ... + XCBarZone *activeZone = NULL; + result = conditions.GetActiveZone(activeZone); + if (!result) + { + return result; + } + + // + // Check Last Valid Peak or Last Valid Vales Breaks ... + // Beak Of Structure ... + + // + // Peak ... + double peak = triggerConditions.x121Conditions.peaksBuffer[1]; + XPVPivotPoint lastPeakPivot; + bool hasLastPeakPivot = triggerCycleHelper + .GetLastPeakPivotPoint(lastPeakPivot); + bool isLastPeakPivotBreaked = + // + lastPeakPivot.IsPeak() && + lastPeakPivot.IsValid() && + peak > lastPeakPivot.value + // + ; + + // + // Vale ... + double vale = triggerConditions.x121Conditions.valesBuffer[1]; + XPVPivotPoint lastValePivot; + bool hasLastValePivot = triggerCycleHelper + .GetLastValePivotPoint(lastValePivot); + bool isLastValePivotBreaked = + // + lastValePivot.IsVale() && + lastValePivot.IsValid() && + vale < lastValePivot.value + // + ; + + // + isBullish = + // + IsBullish(setupDir) && + isLastValePivotBreaked + // + ; + + // + isBearish = + // + IsBearish(setupDir) && + isLastPeakPivotBreaked + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + return result; + } + + // + conditions.triggerTime = cTime; + conditions.sl = isBullish + ? activeZone.Lower() + : activeZone.Upper(); + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + return result; +} + +// + +////////////////////////////////////////// + +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Lib +// ------------------------------------------------- +// Name: +// Description: provide all Signalling functions ... +// +// +// 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 + +// +// Imports ... +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +// Definitions ... +struct X121SMCStrategyXPVOBSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + XCOrderBlock *bullishOBs[]; + XCOrderBlock *bearishOBs[]; + + // + XCFVG *activeFVG; + XCFVG *bullishFVGs[]; + XCFVG *bearishFVGs[]; + + // + // Constructor ... + X121SMCStrategyXPVOBSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + activeFVG = NULL; + Clean(bullishOBs); + Clean(bearishOBs); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + // + int CountBullishOBs() + { + return ArraySize(bullishOBs); + } + + // + int CountBearishOBs() + { + return ArraySize(bearishOBs); + } + + // + bool HasBullishOB() + { + return IsValidSize(CountBullishOBs()); + } + + // + bool HasBearishOB() + { + return IsValidSize(CountBearishOBs()); + } + + // + int CountBullishFVGs() + { + return ArraySize(bullishFVGs); + } + + // + int CountBearishFVGs() + { + return ArraySize(bearishFVGs); + } + + // + bool HasBullishFVG() + { + return IsValidSize(CountBullishFVGs()); + } + + // + bool HasBearishFVG() + { + return IsValidSize(CountBearishFVGs()); + } + + // +}; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXPVOBSiganlSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXPVOBSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Setup Conditions ... + + // + // Detect Market Trend ... + ENUM_X_DIRECTION trend; + bool hasTrend = consolidationCycleHelper + .DetectTrend(trend); + bool hasBullishTrend = hasTrend && + IsBullish(trend); + bool hasBearishTrend = hasTrend && + IsBearish(trend); + result = hasBullishTrend || + hasBearishTrend; + if (!result) + { + return result; + } + + // + // Select Source State ... + XPOIState state = decisionState; + + // + // Detect Imbalance ... + + // + bool hasBullishOB = conditions.HasBullishOB(); + if (!hasBullishOB) + { + // + int count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = state.bullishOrderBlocks[i]; + + // + // Validate Order Block ... + bool isValid = + // + cBar.low > iOB.Upper() + // + ; + if (isValid) + { + // + Add( + iOB, + conditions.bullishOBs // + ); + } + } + } + + // + hasBullishOB = conditions.HasBullishOB(); + } + + // + bool hasBearishOB = conditions.HasBearishOB(); + if (!hasBearishOB) + { + // + int count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = state.bearishOrderBlocks[i]; + + // + // Validate Order Block ... + bool isValid = + // + cBar.high < iOB.Lower() + // + ; + if (isValid) + { + // + Add( + iOB, + conditions.bearishOBs // + ); + } + } + } + + // + hasBearishOB = conditions.HasBearishOB(); + } + + // + result = hasBullishOB || + hasBearishOB; + if (!result) + { + return result; + } + + // + int fvgValidationLength = 5; + + // + bool hasBullishFVG = conditions.HasBullishFVG(); + if (!hasBullishFVG) + { + // + if (hasBullishOB) + { + // + int obsCount = conditions.CountBullishOBs(); + int count = state.CountBullishFairValueGaps(); + for (int i = 0; i < obsCount; i++) + { + // + XCOrderBlock *iOB = conditions.bullishOBs[i]; + + // + for (int j = 0; j < count; j++) + { + // + XCFVG *jFVG = state.bullishFairValueGaps[j]; + + // + bool isValid = + // + cBar.low > iOB.Upper() && + cBar.low > jFVG.Upper() && + // + jFVG.From() > iOB.From() && + (((int)(jFVG.From() - iOB.From())) / PeriodSeconds(state.period)) <= fvgValidationLength + // + ; + if (isValid) + { + // + Add( + jFVG, + conditions.bullishFVGs // + ); + } + } + } + } + + // + hasBullishFVG = conditions.HasBullishFVG(); + } + + // + bool hasBearishFVG = conditions.HasBearishFVG(); + if (!hasBearishFVG) + { + // + if (hasBullishOB) + { + // + int obsCount = conditions.CountBearishOBs(); + int count = state.CountBearishFairValueGaps(); + for (int i = 0; i < obsCount; i++) + { + // + XCOrderBlock *iOB = conditions.bearishOBs[i]; + + // + for (int j = 0; j < count; j++) + { + // + XCFVG *jFVG = state.bearishFairValueGaps[j]; + + // + bool isValid = + // + cBar.high < iOB.Lower() && + cBar.high < jFVG.Lower() && + // + jFVG.From() > iOB.From() && + (((int)(jFVG.From() - iOB.From())) / PeriodSeconds(state.period)) <= fvgValidationLength + // + ; + if (isValid) + { + // + Add( + jFVG, + conditions.bearishFVGs // + ); + } + } + } + } + + // + hasBearishFVG = conditions.HasBearishFVG(); + } + + // + result = (hasBullishOB && + hasBullishFVG) || + (hasBearishOB && + hasBearishFVG); + if (!result) + { + return result; + } + + // + // Detect new Peak or new Vale ... + + // + bool isNewPeak = triggerConditions.x121Conditions.isNewPeak; + double peak = triggerConditions.x121Conditions.peaksBuffer[1]; + bool isNewPeakOverLast = triggerConditions.x121Conditions.isNewPeakOverLast; + bool isNewPeakUnderLast = triggerConditions.x121Conditions.isNewPeakUnderLast; + + // + bool isNewVale = triggerConditions.x121Conditions.isNewVale; + double vale = triggerConditions.x121Conditions.valesBuffer[1]; + bool isNewValeOverLast = triggerConditions.x121Conditions.isNewValeOverLast; + bool isNewValeUnderLast = triggerConditions.x121Conditions.isNewValeUnderLast; + + // + result = isNewPeak || + isNewVale; + if (!result) + { + return result; + } + + // + // Detect Setup Conditions based on Peaks or Vales Occurance ... + + // + bool lookupForLong = isNewVale && + hasBullishOB && + hasBullishFVG && + hasBullishTrend; + + // + bool lookupForShort = isNewPeak && + hasBearishOB && + hasBearishFVG && + hasBearishTrend; + + // + result = lookupForLong || + lookupForShort; + if (!result) + { + return result; + } + + // + XCFVG *fvg = NULL; + double fvgZoneValidationRangePercent = 0; + if (lookupForLong) + { + // + // Long Conditions ... + // Vales must be Happens Inside Bullish Fair Value Gaps ... + int count = conditions.CountBullishFVGs(); + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = conditions.bullishFVGs[i]; + + // + bool isValid = + // + vale <= iFVG.Upper() && + vale >= iFVG.Lower() && + (fvgZoneValidationRangePercent <= 0 + ? true + : (vale < iFVG.Upper() - (iFVG.RangePercent() * fvgZoneValidationRangePercent))) + // + ; + if (isValid) + { + // + fvg = iFVG; + break; + } + } + + // + isBullish = + // + fvg != NULL && + fvg.IsValid() + // + ; + if (isBullish) + { + conditions.activeFVG = fvg; + } + } + else if (lookupForShort) + { + // + // Short Conditions ... + // Peaks Must be Happens Inside Bearish Fair Value Gaps ... + int count = conditions.CountBearishFVGs(); + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = conditions.bearishFVGs[i]; + + // + bool isValid = + // + peak <= iFVG.Upper() && + peak >= iFVG.Lower() && + (fvgZoneValidationRangePercent <= 0 + ? true + : (peak > iFVG.Lower() + (iFVG.RangePercent() * fvgZoneValidationRangePercent))) + // + ; + if (isValid) + { + // + fvg = iFVG; + break; + } + } + + // + isBearish = + // + fvg != NULL && + fvg.IsValid() + // + ; + if (isBearish) + { + conditions.activeFVG = fvg; + } + } + + // + result = isBullish || + isBearish; + if (!result) + { + // + if (lookupForLong) + { + // + conditions.activeFVG = NULL; + Clean(conditions.bullishOBs); + Clean(conditions.bullishFVGs); + } + else if (lookupForShort) + { + // + conditions.activeFVG = NULL; + Clean(conditions.bearishOBs); + Clean(conditions.bearishFVGs); + } + + // + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCXPVOBSiganlTrigger( + // + X121SMCStrategyXPVOBSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Trigger Conditions ... + XCFVG *iFVG = conditions.activeFVG; + result = iFVG != NULL && + iFVG.IsValid(); + if (!result) + { + return result; + } + + // + bool lookupLong = IsBullish(setupDir) && + iFVG.IsBullish(); + bool lookupShort = IsBearish(setupDir) && + iFVG.IsBearish(); + result = lookupLong || + lookupShort; + if (!result) + { + return result; + } + + // + // Check PEAKS and Vales ... + + // + // Trigger ... + + // + // Peaks and Vales ... + double triggerPeak = triggerConditions.x121Conditions.peaksBuffer[1]; + double triggerVale = triggerConditions.x121Conditions.valesBuffer[1]; + + // + bool isTriggerPeakInsideFVG = + // + triggerPeak <= iFVG.Upper() && + triggerPeak >= iFVG.Lower() + // + ; + bool isTriggerValeInsideFVG = + // + triggerVale <= iFVG.Upper() && + triggerVale >= iFVG.Lower() + // + ; + + // + // VWap ... + + // + bool isTriggerVWapFastBullish = triggerConditions.x121Conditions.isVWapFastBullish; + bool isTriggerVWapMidBullish = triggerConditions.x121Conditions.isVWapMidBullish; + bool isTriggerVWapSlowBullish = triggerConditions.x121Conditions.isVWapSlowBullish; + + // + bool isTriggerVWapFastOverMid = triggerConditions.x121Conditions.isVWapFastOverMid; + bool isTriggerVWapMidOverSlow = triggerConditions.x121Conditions.isVWapMidOverSlow; + + // + bool isTriggerVWapFastBearish = triggerConditions.x121Conditions.isVWapFastBearish; + bool isTriggerVWapMidBearish = triggerConditions.x121Conditions.isVWapMidBearish; + bool isTriggerVWapSlowBearish = triggerConditions.x121Conditions.isVWapSlowBearish; + + // + bool isTriggerVWapFastUnderMid = triggerConditions.x121Conditions.isVWapFastUnderMid; + bool isTriggerVWapMidUnderSlow = triggerConditions.x121Conditions.isVWapMidUnderSlow; + + // + bool isTriggerMarketBullish = + // + // State ... + ( + // + (isTriggerVWapFastBullish && + isTriggerVWapMidBullish && + isTriggerVWapSlowBullish) + // + || + // + (isTriggerVWapMidBullish && + isTriggerVWapSlowBullish) + // + ) + // + && + // + // Order ... + ( + // + (isTriggerVWapFastOverMid && + isTriggerVWapMidOverSlow) + // + || + // + isTriggerVWapMidOverSlow + // + ) + // + ; + + // + bool isTriggerMarketBearish = + // + // State ... + ( + // + (isTriggerVWapFastBearish && + isTriggerVWapMidBearish && + isTriggerVWapSlowBearish) + // + || + // + (isTriggerVWapMidBearish && + isTriggerVWapSlowBearish) + // + ) + // + && + // + // Order ... + ( + // + (isTriggerVWapFastUnderMid && + isTriggerVWapMidUnderSlow) + // + || + // + isTriggerVWapMidUnderSlow + // + ) + // + ; + + // + // Decision ... + + // + double decisionPeak = decisionConditions.x121Conditions.peaksBuffer[1]; + double decisionVale = decisionConditions.x121Conditions.valesBuffer[1]; + + // + bool isDecisionPeakInsideFVG = + // + decisionPeak <= iFVG.Upper() && + decisionPeak >= iFVG.Lower() + // + ; + bool isDecisionValeInsideFVG = + // + decisionVale <= iFVG.Upper() && + decisionVale >= iFVG.Lower() + // + ; + + // + // VWap ... + + // + bool isDecisionVWapFastBullish = decisionConditions.x121Conditions.isVWapFastBullish; + bool isDecisionVWapMidBullish = decisionConditions.x121Conditions.isVWapMidBullish; + bool isDecisionVWapSlowBullish = decisionConditions.x121Conditions.isVWapSlowBullish; + + // + bool isDecisionVWapFastOverMid = decisionConditions.x121Conditions.isVWapFastOverMid; + bool isDecisionVWapMidOverSlow = decisionConditions.x121Conditions.isVWapMidOverSlow; + + // + bool isDecisionVWapFastBearish = decisionConditions.x121Conditions.isVWapFastBearish; + bool isDecisionVWapMidBearish = decisionConditions.x121Conditions.isVWapMidBearish; + bool isDecisionVWapSlowBearish = decisionConditions.x121Conditions.isVWapSlowBearish; + + // + bool isDecisionVWapFastUnderMid = decisionConditions.x121Conditions.isVWapFastUnderMid; + bool isDecisionVWapMidUnderSlow = decisionConditions.x121Conditions.isVWapMidUnderSlow; + + // + bool isDecisionMarketBullish = + // + // State ... + ( + // + (isDecisionVWapFastBullish && + isDecisionVWapMidBullish && + isDecisionVWapSlowBullish) + // + || + // + (isDecisionVWapMidBullish && + isDecisionVWapSlowBullish) + // + ) + // + && + // + // Order ... + ( + // + (isDecisionVWapFastOverMid && + isDecisionVWapMidOverSlow) + // + || + // + isDecisionVWapMidOverSlow + // + ) + // + ; + + // + bool isDecisionMarketBearish = + // + // State ... + ( + // + (isDecisionVWapFastBearish && + isDecisionVWapMidBearish && + isDecisionVWapSlowBearish) + // + || + // + (isDecisionVWapMidBearish && + isDecisionVWapSlowBearish) + // + ) + // + && + // + // Order ... + ( + // + (isDecisionVWapFastUnderMid && + isDecisionVWapMidUnderSlow) + // + || + // + isDecisionVWapMidUnderSlow + // + ) + // + ; + + // + // Analyse ... + + // + double analysePeak = analyseConditions.x121Conditions.peaksBuffer[1]; + double analyseVale = analyseConditions.x121Conditions.valesBuffer[1]; + + // + bool isAnalysePeakInsideFVG = + // + analysePeak <= iFVG.Upper() && + analysePeak >= iFVG.Lower() + // + ; + bool isAnalyseValeInsideFVG = + // + analyseVale <= iFVG.Upper() && + analyseVale >= iFVG.Lower() + // + ; + + // + // VWap ... + + // + bool isAnalyseVWapFastBullish = analyseConditions.x121Conditions.isVWapFastBullish; + bool isAnalyseVWapMidBullish = analyseConditions.x121Conditions.isVWapMidBullish; + bool isAnalyseVWapSlowBullish = analyseConditions.x121Conditions.isVWapSlowBullish; + + // + bool isAnalyseVWapFastOverMid = analyseConditions.x121Conditions.isVWapFastOverMid; + bool isAnalyseVWapMidOverSlow = analyseConditions.x121Conditions.isVWapMidOverSlow; + + // + bool isAnalyseVWapFastBearish = analyseConditions.x121Conditions.isVWapFastBearish; + bool isAnalyseVWapMidBearish = analyseConditions.x121Conditions.isVWapMidBearish; + bool isAnalyseVWapSlowBearish = analyseConditions.x121Conditions.isVWapSlowBearish; + + // + bool isAnalyseVWapFastUnderMid = analyseConditions.x121Conditions.isVWapFastUnderMid; + bool isAnalyseVWapMidUnderSlow = analyseConditions.x121Conditions.isVWapMidUnderSlow; + + // + bool isAnalyseMarketBullish = + // + // State ... + ( + // + (isAnalyseVWapFastBullish && + isAnalyseVWapMidBullish && + isAnalyseVWapSlowBullish) + // + || + // + (isAnalyseVWapMidBullish && + isAnalyseVWapSlowBullish) + // + ) + // + && + // + // Order ... + ( + // + (isAnalyseVWapFastOverMid && + isAnalyseVWapMidOverSlow) + // + || + // + isAnalyseVWapMidOverSlow + // + ) + // + ; + + // + bool isAnalyseMarketBearish = + // + // State ... + ( + // + (isAnalyseVWapFastBearish && + isAnalyseVWapMidBearish && + isAnalyseVWapSlowBearish) + // + || + // + (isAnalyseVWapMidBearish && + isAnalyseVWapSlowBearish) + // + ) + // + && + // + // Order ... + ( + // + (isAnalyseVWapFastUnderMid && + isAnalyseVWapMidUnderSlow) + // + || + // + isAnalyseVWapMidUnderSlow + // + ) + // + ; + + // + // Verification ... + + // + double verificationPeak = verificationConditions.x121Conditions.peaksBuffer[1]; + double verificationVale = verificationConditions.x121Conditions.valesBuffer[1]; + + // + bool isVerificationPeakInsideFVG = + // + verificationPeak <= iFVG.Upper() && + verificationPeak >= iFVG.Lower() + // + ; + bool isVerificationValeInsideFVG = + // + verificationVale <= iFVG.Upper() && + verificationVale >= iFVG.Lower() + // + ; + + // + // VWap ... + + // + bool isVerificationVWapFastBullish = verificationConditions.x121Conditions.isVWapFastBullish; + bool isVerificationVWapMidBullish = verificationConditions.x121Conditions.isVWapMidBullish; + bool isVerificationVWapSlowBullish = verificationConditions.x121Conditions.isVWapSlowBullish; + + // + bool isVerificationVWapFastOverMid = verificationConditions.x121Conditions.isVWapFastOverMid; + bool isVerificationVWapMidOverSlow = verificationConditions.x121Conditions.isVWapMidOverSlow; + + // + bool isVerificationVWapFastBearish = verificationConditions.x121Conditions.isVWapFastBearish; + bool isVerificationVWapMidBearish = verificationConditions.x121Conditions.isVWapMidBearish; + bool isVerificationVWapSlowBearish = verificationConditions.x121Conditions.isVWapSlowBearish; + + // + bool isVerificationVWapFastUnderMid = verificationConditions.x121Conditions.isVWapFastUnderMid; + bool isVerificationVWapMidUnderSlow = verificationConditions.x121Conditions.isVWapMidUnderSlow; + + // + bool isVerificationMarketBullish = + // + // State ... + ( + // + (isVerificationVWapFastBullish && + isVerificationVWapMidBullish && + isVerificationVWapSlowBullish) + // + || + // + (isVerificationVWapMidBullish && + isVerificationVWapSlowBullish) + // + ) + // + && + // + // Order ... + ( + // + (isVerificationVWapFastOverMid && + isVerificationVWapMidOverSlow) + // + || + // + isVerificationVWapMidOverSlow + // + ) + // + ; + + // + bool isVerificationMarketBearish = + // + // State ... + ( + // + (isVerificationVWapFastBearish && + isVerificationVWapMidBearish && + isVerificationVWapSlowBearish) + // + || + // + (isVerificationVWapMidBearish && + isVerificationVWapSlowBearish) + // + ) + // + && + // + // Order ... + ( + // + (isVerificationVWapFastUnderMid && + isVerificationVWapMidUnderSlow) + // + || + // + isVerificationVWapMidUnderSlow + // + ) + // + ; + + // + // Consolidation ... + + // + double consolidationPeak = consolidationConditions.x121Conditions.peaksBuffer[1]; + double consolidationVale = consolidationConditions.x121Conditions.valesBuffer[1]; + + // + bool isConsolidationPeakInsideFVG = + // + consolidationPeak <= iFVG.Upper() && + consolidationPeak >= iFVG.Lower() + // + ; + bool isConsolidationValeInsideFVG = + // + consolidationVale <= iFVG.Upper() && + consolidationVale >= iFVG.Lower() + // + ; + + // + // VWap ... + + // + bool isConsolidationVWapFastBullish = consolidationConditions.x121Conditions.isVWapFastBullish; + bool isConsolidationVWapMidBullish = consolidationConditions.x121Conditions.isVWapMidBullish; + bool isConsolidationVWapSlowBullish = consolidationConditions.x121Conditions.isVWapSlowBullish; + + // + bool isConsolidationVWapFastOverMid = consolidationConditions.x121Conditions.isVWapFastOverMid; + bool isConsolidationVWapMidOverSlow = consolidationConditions.x121Conditions.isVWapMidOverSlow; + + // + bool isConsolidationVWapFastBearish = consolidationConditions.x121Conditions.isVWapFastBearish; + bool isConsolidationVWapMidBearish = consolidationConditions.x121Conditions.isVWapMidBearish; + bool isConsolidationVWapSlowBearish = consolidationConditions.x121Conditions.isVWapSlowBearish; + + // + bool isConsolidationVWapFastUnderMid = consolidationConditions.x121Conditions.isVWapFastUnderMid; + bool isConsolidationVWapMidUnderSlow = consolidationConditions.x121Conditions.isVWapMidUnderSlow; + + // + bool isConsolidationMarketBullish = + // + // State ... + ( + // + (isConsolidationVWapFastBullish && + isConsolidationVWapMidBullish && + isConsolidationVWapSlowBullish) + // + || + // + (isConsolidationVWapMidBullish && + isConsolidationVWapSlowBullish) + // + ) + // + && + // + // Order ... + ( + // + (isConsolidationVWapFastOverMid && + isConsolidationVWapMidOverSlow) + // + || + // + isConsolidationVWapMidOverSlow + // + ) + // + ; + + // + bool isConsolidationMarketBearish = + // + // State ... + ( + // + (isConsolidationVWapFastBearish && + isConsolidationVWapMidBearish && + isConsolidationVWapSlowBearish) + // + || + // + (isConsolidationVWapMidBearish && + isConsolidationVWapSlowBearish) + // + ) + // + && + // + // Order ... + ( + // + (isConsolidationVWapFastUnderMid && + isConsolidationVWapMidUnderSlow) + // + || + // + isConsolidationVWapMidUnderSlow + // + ) + // + ; + + // + // Sar ... + + // + bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish; + bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish; + + // + // Summarize Conditions ... + + // + bool isSamePeak = + triggerPeak == decisionPeak && + triggerPeak == analysePeak && + triggerPeak == verificationPeak; + + // + bool isPeaksInsideFVG = + // + isTriggerPeakInsideFVG && + isDecisionPeakInsideFVG && + isAnalysePeakInsideFVG && + isVerificationPeakInsideFVG + // + ; + + // + bool isSameVale = + triggerVale == decisionVale && + triggerVale == analyseVale && + triggerVale == verificationVale; + + // + bool isValesInsideFVG = + // + isTriggerValeInsideFVG && + isDecisionValeInsideFVG && + isAnalyseValeInsideFVG && + isVerificationValeInsideFVG + // + ; + + // + bool isMarketReadyForLong = + // + // !isTriggerMarketBearish && + // !isDecisionMarketBearish && + // !isAnalyseMarketBearish && + isTriggerMarketBullish && + !isVerificationMarketBearish && + !isConsolidationMarketBearish + // + ; + + // + bool isMarketReadyForShort = + // + // !isTriggerMarketBullish && + // !isDecisionMarketBullish && + // !isAnalyseMarketBullish && + isTriggerMarketBearish && + !isVerificationMarketBullish && + !isConsolidationMarketBullish + // + ; + + // + // Create Trigger ... + + // + isBullish = + // isSameVale && + lookupLong && + isValesInsideFVG && + // isMarketReadyForLong && + isSarSwitchedToBullish && + triggerVale <= iFVG.Upper() && + triggerVale >= iFVG.Lower(); + + // + isBearish = + // isSamePeak && + lookupShort && + isPeaksInsideFVG && + // isMarketReadyForShort && + isSarSwitchedToBearish && + triggerPeak <= iFVG.Upper() && + triggerPeak >= iFVG.Lower(); + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + return result; + } + + // + conditions.triggerTime = cTime; + conditions.sl = isBullish + ? iFVG.Lower() + : iFVG.Upper(); + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + return result; +} + +// + +////////////////////////////////////////// + +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Lib +// ------------------------------------------------- +// Name: +// Description: provide all Signalling functions ... +// +// +// 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 + +// +// Imports ... +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +// Definitions ... +struct X121SMCStrategyXPVDPSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + double peak; + double vale; + + // + // Constructor ... + X121SMCStrategyXPVDPSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + ExtensionClean(); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + /** + * Clean Additional Properties ... + */ + void ExtensionClean() + { + // + peak = 0; + vale = 0; + } + + // +}; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXPVDPSiganlSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXPVDPSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Setup Conditions ... + + // + // Detect Market Trend ... + ENUM_X_DIRECTION trend; + bool hasTrend = consolidationCycleHelper + .DetectTrend(trend); + bool hasBullishTrend = hasTrend && + IsBullish(trend); + bool hasBearishTrend = hasTrend && + IsBearish(trend); + result = hasBullishTrend || + hasBearishTrend; + if (!result) + { + return result; + } + + // + // Select Source State ... + XPOIState state = decisionState; + + // + // Detect High Equals to Peaks or Low Equals to Vale ... + + // + // Peak ... + double peak = triggerConditions.x121Conditions.peaksBuffer[1]; + bool isNewPeak = triggerConditions.x121Conditions.isNewPeak; + bool isNewPeakOverLast = triggerConditions.x121Conditions.isNewPeakOverLast; + bool isNewPeakUnderLast = triggerConditions.x121Conditions.isNewPeakUnderLast; + + // + // Vale ... + double vale = triggerConditions.x121Conditions.valesBuffer[1]; + bool isNewVale = triggerConditions.x121Conditions.isNewVale; + bool isNewValeOverLast = triggerConditions.x121Conditions.isNewValeOverLast; + bool isNewValeUnderLast = triggerConditions.x121Conditions.isNewValeUnderLast; + + // + bool isHighEqualsToPeak = + isNewPeak && + peak == cBar.high; + + // + bool isLowEqualsToVale = + isNewVale && + vale == cBar.low; + + // + result = isHighEqualsToPeak || + isLowEqualsToVale; + if (!result) + { + return result; + } + + // + // Now We Have To Check DONChain Status ... + + // + double donCUpper = triggerConditions.x121Conditions.donCloseUpperBuffer[1]; + double donCUpperPrev = triggerConditions.x121Conditions.donCloseUpperBuffer[2]; + + // + double donCLower = triggerConditions.x121Conditions.donCloseLowerBuffer[1]; + double donCLowerPrev = triggerConditions.x121Conditions.donCloseLowerBuffer[2]; + + // + double donOUpper = triggerConditions.x121Conditions.donOpenUpperBuffer[1]; + double donOUpperPrev = triggerConditions.x121Conditions.donOpenUpperBuffer[2]; + + // + double donOLower = triggerConditions.x121Conditions.donOpenLowerBuffer[1]; + double donOLowerPrev = triggerConditions.x121Conditions.donOpenLowerBuffer[2]; + + // + bool isDonUpperBullish = donCUpper > donOUpper; + bool isDonUpperBullishPrev = donCUpperPrev > donOUpperPrev; + + // + bool isDonUpperBearish = donCUpper < donOUpper; + bool isDonUpperBearishPrev = donCUpperPrev < donOUpperPrev; + + // + bool isDonUpperSwitchedToBullish = isDonUpperBullish && + !isDonUpperBullishPrev; + + // + bool isDonUpperSwitchedToBearish = isDonUpperBearish && + !isDonUpperBearishPrev; + + // + bool isDonLowerBullish = donCLower > donOLower; + bool isDonLowerBullishPrev = donCLowerPrev > donOLowerPrev; + + // + bool isDonLowerBearish = donCLower < donOLower; + bool isDonLowerBearishPrev = donCLowerPrev < donOLowerPrev; + + // + bool isDonLowerSwitchedToBullish = isDonLowerBullish && + !isDonLowerBullishPrev; + + // + bool isDonLowerSwitchedToBearish = isDonLowerBearish && + !isDonLowerBearishPrev; + + // + // Calculate State ... + + // + bool isDonInBullishState = + // + // Upper ... + (isDonUpperBullish || + isDonUpperSwitchedToBullish) + // + && + // + // Lower ... + (isDonLowerBullish || + isDonLowerSwitchedToBullish) + // + ; + + // + bool isDonInBearishState = + // + // Upper ... + (isDonUpperBearish || + isDonUpperSwitchedToBearish) + // + && + // + // Lower ... + (isDonLowerBearish || + isDonLowerSwitchedToBearish) + // + ; + + // + // Summary DonChain State ... + + // + isBullish = + // + hasBullishTrend + // + && + // + isDonInBullishState + // + && + // + (isHighEqualsToPeak || + isLowEqualsToVale) + // + ; + + // + isBearish = + // + hasBearishTrend + // + && + // + isDonInBearishState + // + && + // + (isHighEqualsToPeak || + isLowEqualsToVale) + // + ; + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Check VWap Conditions ... + + // + double vwapFast = triggerConditions.x121Conditions.vwapFastBuffer[1]; + double vwapMid = triggerConditions.x121Conditions.vwapMidBuffer[1]; + double vwapSlow = triggerConditions.x121Conditions.vwapSlowBuffer[1]; + + // + double vwaps[3] = { + vwapFast, + vwapMid, + vwapSlow, + }; + double vwapMax = GetMax(vwaps); + double vwapMin = GetMin(vwaps); + + // + bool isCloseOverVwapMax = + // + ask > vwapMax && + bid > vwapMax && + (cBar.low > vwapMax || + cBar.close > vwapMax) + // + ; + + // + bool isCloseUnderVwapMin = + // + ask < vwapMin && + bid < vwapMin && + (cBar.high < vwapMin || + cBar.close < vwapMin) + // + ; + + // + bool isVWapFastBullish = triggerConditions.x121Conditions.isVWapFastBullish; + bool isVWapFastBearish = triggerConditions.x121Conditions.isVWapFastBearish; + bool isVWapMidBullish = triggerConditions.x121Conditions.isVWapMidBullish; + bool isVWapMidBearish = triggerConditions.x121Conditions.isVWapMidBearish; + bool isVWapSlowBullish = triggerConditions.x121Conditions.isVWapSlowBullish; + bool isVWapSlowBearish = triggerConditions.x121Conditions.isVWapSlowBearish; + bool isVWapFastOverMid = triggerConditions.x121Conditions.isVWapFastOverMid; + bool isVWapMidOverSlow = triggerConditions.x121Conditions.isVWapMidOverSlow; + bool isVWapFastUnderMid = triggerConditions.x121Conditions.isVWapFastUnderMid; + bool isVWapMidUnderSlow = triggerConditions.x121Conditions.isVWapMidUnderSlow; + + // + bool isVwapBullishFormed = + // + // Order ... + (isVWapFastOverMid || + isVWapMidOverSlow || + (isVWapFastOverMid && + isVWapMidOverSlow)) + // + && + // State ... + ((isVWapFastBullish && + isVWapMidBullish) || + (isVWapMidBullish && + isVWapSlowBullish) || + (isVWapFastBullish && + isVWapMidBullish && + isVWapSlowBullish)) + // + ; + + // + bool isVwapBearishFormed = + // + // Order ... + (isVWapFastUnderMid || + isVWapMidUnderSlow || + (isVWapFastUnderMid && + isVWapMidUnderSlow)) + // + && + // State ... + ((isVWapFastBearish && + isVWapMidBearish) || + (isVWapMidBearish && + isVWapSlowBearish) || + (isVWapFastBearish && + isVWapMidBearish && + isVWapSlowBearish)) + // + ; + + // + // Summar VWap State ... + + // + isBullish = + isBullish && + isCloseOverVwapMax && + isVwapBullishFormed; + + // + isBearish = + isBearish && + isCloseUnderVwapMin && + isVwapBearishFormed; + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Check Sar State ... + double sar = triggerConditions.x121Conditions.sarBuffer[1]; + + // + bool isSarBullish = triggerConditions.x121Conditions.isSarBullish; + bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish; + + // + bool isSarBearish = triggerConditions.x121Conditions.isSarBearish; + bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish; + + // + // Summary Sar ... + + // + bool isSarBullishFormed = isSarBullish || + isSarSwitchedToBullish; + + // + bool isSarBearishFormed = isSarBearish || + isSarSwitchedToBearish; + + // + isBullish = + isBullish && + isSarBullishFormed; + + // + isBearish = + isBearish && + isSarBearishFormed; + + // + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCXPVDPSiganlTrigger( + // + X121SMCStrategyXPVDPSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Trigger Conditions ... + + // + double vwapFast = triggerConditions.x121Conditions.vwapFastBuffer[1]; + double vwapMid = triggerConditions.x121Conditions.vwapMidBuffer[1]; + double vwapSlow = triggerConditions.x121Conditions.vwapSlowBuffer[1]; + + // + double vwaps[3] = { + vwapFast, + vwapMid, + vwapSlow, + }; + double vwapMax = GetMax(vwaps); + double vwapMin = GetMin(vwaps); + + // + double sar = triggerConditions.x121Conditions.sarBuffer[1]; + + // + isBullish = + // + IsBullish(setupDir) + // + ; + + // + isBearish = + // + IsBearish(setupDir) + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + return result; + } + + // + conditions.triggerTime = cTime; + conditions.sl = isBullish + ? MathMin(sar, vwapMin) + : MathMin(sar, vwapMax); + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + return result; +} + +// + +////////////////////////////////////////// + +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: +// Description: provide all Signalling functions ... +// +// +// 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 + +// +// Imports ... +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +// Definitions ... +struct X121SMCStrategyTestSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + // Constructor ... + X121SMCStrategyTestSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + ExtensionClean(); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + /** + * Clean Additional Properties ... + */ + void ExtensionClean() + { + } + + // +}; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCTestSiganlSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyTestSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Setup Conditions ... + + // + isBullish = + // + false + // + ; + + // + isBearish = + // + false + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Clean Conditions for Regenerate ... + + // + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCTestSiganlTrigger( + // + X121SMCStrategyTestSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Trigger Conditions ... + + // + isBullish = + // + false + // + ; + + // + isBearish = + // + false + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + return result; + } + + // + conditions.triggerTime = cTime; + conditions.sl = isBullish + ? 0 + : 0; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + return result; +} + +// + +////////////////////////////////////////// + + +////////////////////////////////////////// + + +////////////////////////////////////////// \ No newline at end of file diff --git a/Documents/BKP/3/x-smc.signal.detectors.mq5 b/Documents/BKP/3/x-smc.signal.detectors.mq5 new file mode 100644 index 00000000..c0bf4049 --- /dev/null +++ b/Documents/BKP/3/x-smc.signal.detectors.mq5 @@ -0,0 +1,911 @@ +///////////////////////////////////////////////////////////////////////// + + // + // Detect Signal Conditions ... + bool hasSignal = false; + + // + bool useTestSignal = false; + bool useXPVOBSignal = false; + bool useXPVDPSignal = false; + bool useXVWPBSignal = false; + bool useXTWPVSignal = true; + bool useXPVSUPDEMSignal = false; + + // + bool hasTestSignal = false; + bool hasXPVOBSignal = false; + bool hasXPVDPSignal = false; + bool hasXVWPBSignal = false; + bool hasXTWPVSignal = false; + bool hasXPVSUPDEMSignal = false; + + // + // Test Signal ... + if (useTestSignal && !hasSignal) + { + // + hasTestSignal = DetectTestSignal(conditions); + hasSignal = hasTestSignal; + } + + // + // XPVOB Signal ... + if (useXPVOBSignal && !hasSignal) + { + // + hasXPVOBSignal = DetectXPVOBSignal(conditions); + hasSignal = hasXPVOBSignal; + } + + // + // XPVDP Signal ... + if (useXPVDPSignal && !hasSignal) + { + // + hasXPVDPSignal = DetectXPVDPSignal(conditions); + hasSignal = hasXPVDPSignal; + } + + // + // XVWPB Signal ... + if (useXVWPBSignal && !hasSignal) + { + // + hasXVWPBSignal = DetectXVWPBSignal(conditions); + hasSignal = hasXVWPBSignal; + } + + // + // XTWPV Signal ... + if (useXTWPVSignal && !hasSignal) + { + // + hasXTWPVSignal = DetectXTWPVSignal(conditions); + hasSignal = hasXTWPVSignal; + } + + // + // XPVSUPDEM Signal ... + if (useXPVSUPDEMSignal && !hasSignal) + { + // + hasXPVSUPDEMSignal = DetectXPVSUPDEMSignal(conditions); + hasSignal = hasXPVSUPDEMSignal; + } + +//////////////////////////////////////////////////////////////////////// + + + // + // Test Signal ... + X121SMCStrategyTestSignalConditions mTestConditions; + bool DetectTestSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XTEST; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mTestConditions.setupTime; + bool isSetuped = mTestConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mTestConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCTestSiganlSetup( + symbol, + period, + mTestConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + setupDir = mTestConditions.dir; + setupTime = mTestConditions.setupTime; + } + + // ClearDraws(); + // ENUM_X_DIRECTION activeZoneDir; + // bool hasTicksZone = mTestConditions.HasTicksZone(); + // bool hasActiveZone = mTestConditions.HasActiveZone(activeZoneDir); + // if (hasActiveZone) + // { + // // + // if (IsBullish(activeZoneDir)) + // { + // // + // mTestConditions.activeDemandZone.To(cTime); + // XCDemandZoneObject *iObj; + // bool isCreated = mPOIDrawer.CreateDemandZone( + // mTestConditions.activeDemandZone, + // iObj // + // ); + // if (isCreated) + // { + // AddObjectIfNotExists(iObj); + // } + // } + // else + // { + // // + // mTestConditions.activeSupplyZone.To(cTime); + // XCSupplyZoneObject *iObj; + // bool isCreated = mPOIDrawer.CreateSupplyZone( + // mTestConditions.activeSupplyZone, + // iObj // + // ); + // if (isCreated) + // { + // AddObjectIfNotExists(iObj); + // } + // } + // } + // if (hasTicksZone) + // { + // // + // XCTicksZoneObject *iObj; + // bool isCreated = mPOIDrawer.CreateTicksZone( + // mTestConditions.ticksZone, + // iObj // + // ); + // if (isCreated) + // { + // AddObjectIfNotExists(iObj); + // } + // } + + // + result = isSetuped; + if (!result) + { + return result; + } + + // + // Detect Trigger Conditions ... + bool canTrigger = mTestConditions.CanTrigger(); + datetime triggerTime = mTestConditions.triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCTestSiganlTrigger( + mTestConditions, + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + return result; + } + + // + triggerTime = mTestConditions.triggerTime; + } + + // + // Check Signal Direction ... + + // + isBullish = IsBullish(setupDir); + isBearish = IsBearish(setupDir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.signalDir = setupDir; + conditions.provider = providerStr; + conditions.sl = mTestConditions.sl; + conditions.target = mTestConditions.target; + + // + mTestConditions.Clean(); + + // + return result; + } + + // + // XPVOB Signal ... + X121SMCStrategyXPVOBSignalConditions mXPVOBConditions; + bool DetectXPVOBSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XPVOB; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mXPVOBConditions.setupTime; + bool isSetuped = mXPVOBConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mXPVOBConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCXPVOBSiganlSetup( + symbol, + period, + mXPVOBConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = isSetuped; + if (!result) + { + return result; + } + + // + setupDir = mXPVOBConditions.dir; + setupTime = mXPVOBConditions.setupTime; + } + + // + // Draw Conditions Active FVG ... + // if (isSetuped) + // { + // // + // XCFVG *iFVG = mXPVOBConditions.activeFVG; + // if (iFVG != NULL && iFVG.IsValid()) + // { + // // + // ClearDraws(); + // iFVG.To(cTime); + // if (IsBullish(setupDir) && iFVG.IsBullish()) + // { + // // + // XCBullishFairValueGapObject *iObj; + // bool isCreated = mPOIDrawer.CreateBullishFairValueGap( + // iFVG, + // iObj // + // ); + // if (isCreated) + // { + // AddObjectIfNotExists(iObj); + // } + // } + // else if (IsBearish(setupDir) && iFVG.IsBearish()) + // { + // // + // XCBearishFairValueGapObject *iObj; + // bool isCreated = mPOIDrawer.CreateBearishFairValueGap( + // iFVG, + // iObj // + // ); + // if (isCreated) + // { + // AddObjectIfNotExists(iObj); + // } + // } + // } + // } + + // + // Detect Trigger Conditions ... + bool canTrigger = mXPVOBConditions.CanTrigger(); + datetime triggerTime = mXPVOBConditions.triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCXPVOBSiganlTrigger( + mXPVOBConditions, + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + return result; + } + + // + triggerTime = mXPVOBConditions.triggerTime; + } + + // + // Check Signal Direction ... + + // + isBullish = IsBullish(setupDir); + isBearish = IsBearish(setupDir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.signalDir = setupDir; + conditions.provider = providerStr; + conditions.sl = mXPVOBConditions.sl; + conditions.target = mXPVOBConditions.target; + + // + mXPVOBConditions.Clean(); + + // + return result; + } + + // + // XPVDP Signal ... + X121SMCStrategyXPVDPSignalConditions mXPVDPConditions; + bool DetectXPVDPSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XPVDP; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mXPVDPConditions.setupTime; + bool isSetuped = mXPVDPConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mXPVDPConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCXPVDPSiganlSetup( + symbol, + period, + mXPVDPConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + setupDir = mXPVDPConditions.dir; + setupTime = mXPVDPConditions.setupTime; + } + result = isSetuped; + if (!result) + { + return result; + } + + // + // Detect Trigger Conditions ... + bool canTrigger = mXPVDPConditions.CanTrigger(); + datetime triggerTime = mXPVDPConditions.triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCXPVDPSiganlTrigger( + mXPVDPConditions, + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + return result; + } + + // + triggerTime = mXPVDPConditions.triggerTime; + } + + // + // Check Signal Direction ... + + // + isBullish = IsBullish(setupDir); + isBearish = IsBearish(setupDir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.signalDir = setupDir; + conditions.provider = providerStr; + conditions.sl = mXPVDPConditions.sl; + conditions.target = mXPVDPConditions.target; + + // + mXPVDPConditions.Clean(); + + // + return result; + } + + // + // XVWPB Signal ... + X121SMCStrategyXVWPBSignalConditions mXVWPBConditions; + bool DetectXVWPBSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XVWPB; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mXVWPBConditions.setupTime; + bool isSetuped = mXVWPBConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mXVWPBConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCXVWPBSiganlSetup( + symbol, + period, + mXVWPBConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + setupDir = mXVWPBConditions.dir; + setupTime = mXVWPBConditions.setupTime; + } + result = isSetuped; + if (!result) + { + return result; + } + + // + // Detect Trigger Conditions ... + bool canTrigger = mXVWPBConditions.CanTrigger(); + datetime triggerTime = mXVWPBConditions.triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCXVWPBSiganlTrigger( + mXVWPBConditions, + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + return result; + } + + // + triggerTime = mXVWPBConditions.triggerTime; + } + + // + // Check Signal Direction ... + + // + isBullish = IsBullish(setupDir); + isBearish = IsBearish(setupDir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.signalDir = setupDir; + conditions.provider = providerStr; + conditions.sl = mXVWPBConditions.sl; + conditions.target = mXVWPBConditions.target; + + // + mXVWPBConditions.Clean(); + + // + return result; + } + + // + // XTWPV Signal ... + X121SMCStrategyXTWPVSignalConditions mXTWPVConditions; + bool DetectXTWPVSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XTWPV; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mXTWPVConditions.setupTime; + bool isSetuped = mXTWPVConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mXTWPVConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCXTWPVSiganlSetup( + symbol, + period, + mXTWPVConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + setupDir = mXTWPVConditions.dir; + setupTime = mXTWPVConditions.setupTime; + } + result = isSetuped; + if (!result) + { + return result; + } + + // + // Detect Trigger Conditions ... + bool canTrigger = mXTWPVConditions.CanTrigger(); + datetime triggerTime = mXTWPVConditions.triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCXTWPVSiganlTrigger( + mXTWPVConditions, + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + return result; + } + + // + triggerTime = mXTWPVConditions.triggerTime; + } + + // + // Check Signal Direction ... + + // + isBullish = IsBullish(setupDir); + isBearish = IsBearish(setupDir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.signalDir = setupDir; + conditions.provider = providerStr; + conditions.sl = mXTWPVConditions.sl; + conditions.target = mXTWPVConditions.target; + + // + mXTWPVConditions.Clean(); + + // + return result; + } + + // + // XPVSUPDEM Signal ... + X121SMCStrategyXPVSUPDEMSignalConditions mXPVSUPDEMConditions; + bool DetectXPVSUPDEMSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XPVSUPDEM; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mXPVSUPDEMConditions.setupTime; + bool isSetuped = mXPVSUPDEMConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mXPVSUPDEMConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCXPVSUPDEMSiganlSetup( + symbol, + period, + mXPVSUPDEMConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + setupDir = mXPVSUPDEMConditions.dir; + setupTime = mXPVSUPDEMConditions.setupTime; + } + + // ClearDraws(); + // ENUM_X_DIRECTION activeZoneDir; + // bool hasTicksZone = mXPVSUPDEMConditions.HasTicksZone(); + // bool hasActiveZone = mXPVSUPDEMConditions.HasActiveZone(activeZoneDir); + // if (hasActiveZone) + // { + // // + // if (IsBullish(activeZoneDir)) + // { + // // + // mXPVSUPDEMConditions.activeDemandZone.To(cTime); + // XCDemandZoneObject *iObj; + // bool isCreated = mPOIDrawer.CreateDemandZone( + // mXPVSUPDEMConditions.activeDemandZone, + // iObj // + // ); + // if (isCreated) + // { + // AddObjectIfNotExists(iObj); + // } + // } + // else + // { + // // + // mXPVSUPDEMConditions.activeSupplyZone.To(cTime); + // XCSupplyZoneObject *iObj; + // bool isCreated = mPOIDrawer.CreateSupplyZone( + // mXPVSUPDEMConditions.activeSupplyZone, + // iObj // + // ); + // if (isCreated) + // { + // AddObjectIfNotExists(iObj); + // } + // } + // } + // if (hasTicksZone) + // { + // // + // XCTicksZoneObject *iObj; + // bool isCreated = mPOIDrawer.CreateTicksZone( + // mXPVSUPDEMConditions.ticksZone, + // iObj // + // ); + // if (isCreated) + // { + // AddObjectIfNotExists(iObj); + // } + // } + + // + result = isSetuped; + if (!result) + { + return result; + } + + // + // Detect Trigger Conditions ... + bool canTrigger = mXPVSUPDEMConditions.CanTrigger(); + datetime triggerTime = mXPVSUPDEMConditions.triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCXPVSUPDEMSiganlTrigger( + mXPVSUPDEMConditions, + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + return result; + } + + // + triggerTime = mXPVSUPDEMConditions.triggerTime; + } + + // + // Check Signal Direction ... + + // + isBullish = IsBullish(setupDir); + isBearish = IsBearish(setupDir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.signalDir = setupDir; + conditions.provider = providerStr; + conditions.sl = mXPVSUPDEMConditions.sl; + conditions.target = mXPVSUPDEMConditions.target; + + // + mXPVSUPDEMConditions.Clean(); + + // + return result; + } + + +/////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/Documents/BKP/4/tmp.pivot.draws.mq5 b/Documents/BKP/4/tmp.pivot.draws.mq5 new file mode 100644 index 00000000..51d415ea --- /dev/null +++ b/Documents/BKP/4/tmp.pivot.draws.mq5 @@ -0,0 +1,73 @@ + // + ClearDraws(); + XPVPivot peakPivot; + bool hasActivePeakPivot = + mTriggerCycleHelper + .GetActivePeakPivot(peakPivot); + if (hasActivePeakPivot) + { + // + XCBaseObject *iPivotObjs[]; + int drawnCount = mPOIDrawer.DrawPivot( + peakPivot, + iPivotObjs // + ); + + // + if (IsValidSize(drawnCount)) + { + AddObjectsIfNotExists(iPivotObjs); + } + } + + // + XPVPivot valePivot; + bool hasActiveValePivot = + mTriggerCycleHelper + .GetActiveValePivot(valePivot); + if (hasActiveValePivot) + { + // + XCBaseObject *iPivotObjs[]; + int drawnCount = mPOIDrawer.DrawPivot( + valePivot, + iPivotObjs // + ); + + // + if (IsValidSize(drawnCount)) + { + AddObjectsIfNotExists(iPivotObjs); + } + } + + // XPVPivot pivots[]; + // int pivotsCount = mTriggerCycleHelper.FillPivots(pivots); + // if (IsValidSize(pivotsCount)) + // { + // // + // for (int i = 0; i < pivotsCount; i++) + // { + // // + // XPVPivot iPivot = pivots[i]; + + // // + // XCBaseObject *iPivotObjects[]; + // mPOIDrawer.DrawPivot( + // iPivot, + // iPivotObjects, + // false // Don't Draw State ... + // ); + + // // + // int iPivotObjectsCount = ArraySize(iPivotObjects); + // if (IsValidSize(iPivotObjectsCount)) + // { + // // + // for (int j = 0; j < iPivotObjectsCount; j++) + // { + // AddObjectIfNotExists(iPivotObjects[j]); + // } + // } + // } + // } diff --git a/Experts/x-saherelm.x-121.smc.ea.mq5 b/Experts/x-saherelm.x-121.smc.ea.mq5 index 7e2c18a1..e379a612 100644 --- a/Experts/x-saherelm.x-121.smc.ea.mq5 +++ b/Experts/x-saherelm.x-121.smc.ea.mq5 @@ -44,20 +44,20 @@ input string eaSymbols = "EURUSDb,GBPUSDb,USDJPYb,USDCHFb"; // Trading Symbols // // Signalling ... input group "Signalling"; -input bool eaAllowLong = true; // Allow Long Signals -input bool eaAllowShort = true; // Allow Short Signals -input int eaMaxAllowedLongs = 5; // Max Allowed Long Signals -input int eaMaxAllowedShorts = 5; // Max Allowed Short Signals -input bool eaUseMaxAllowedSignalsPerSymbol = true; // Use Max Allowed Signal Types Per Symbol -input double eaLastPositionProfitForAcceptNextInPoint = 0; // Last Position Profit In Points for Accept new Signal -input int eaDelaysBetweenTwoSignalsInBar = 7; // Delay between two Signals in Bars -input double eaMaxAllowedSpread = 25; // Max Allowed Spread for Signalling -input int eaMinRequiredVerificationForSpreadPass = 20; // Minimum Spread Verification for Signalling +input bool eaAllowLong = true; // Allow Long Signals +input bool eaAllowShort = true; // Allow Short Signals +input int eaMaxAllowedLongs = 5; // Max Allowed Long Signals +input int eaMaxAllowedShorts = 5; // Max Allowed Short Signals +input bool eaUseMaxAllowedSignalsPerSymbol = true; // Use Max Allowed Signal Types Per Symbol +input double eaLastPositionProfitForAcceptNextInPoint = 30; // Last Position Profit In Points for Accept new Signal +input int eaDelaysBetweenTwoSignalsInBar = 50; // Delay between two Signals in Bars +input double eaMaxAllowedSpread = 25; // Max Allowed Spread for Signalling +input int eaMinRequiredVerificationForSpreadPass = 20; // Minimum Spread Verification for Signalling // // Risk Management ... input group "Risk Management"; -input double eaR2R = 6; // Signallers Risk to Reward Ratio +input double eaR2R = 3; // Signallers Risk to Reward Ratio input double eaVolume = 0.05; // Static Volume input double eaRiskPercentPerBalance = 0.1; // Risk Percent Per Balance in Each Trade input bool eaDynamicRiskManagement = false; // Dynamic Risk Management @@ -65,7 +65,7 @@ input bool eaUseDynamicVolume = false; // Use Dy input double eaDynamicVolumeStep = 0.01; // Increase Volume Step input double eaDynamicVolumeBalanceFactor = 200; // Balance Factor for Generate Dynamic Volume input double eaMaxAllowedDrawdownToOpenTrades = 3; // Max Allowed Drawdown for Open Trades -input int eaMaxAllowedSLToPauseSignallingPerSymbol = 2; // Max Allowed SL for Pause Signalling Per Symbol +input int eaMaxAllowedSLToPauseSignallingPerSymbol = 1; // Max Allowed SL for Pause Signalling Per Symbol input int eaPauseSignallingAfterReachesMaxAllowedSLInSecconds = 14400; // Pause Signalling Per Symbol afte Max Allowed SL Reached In Seconds // diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index a915367e..4eb91978 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -3761,6 +3761,488 @@ struct XPOIState // }; + +// +// +// + +// +// Pivot Types ... +enum ENUM_XPV_PIVOTS +{ + XPV_NONE, + XPV_PEAK, + XPV_VALE, +}; + +// +// Model a Pivot structure ... +struct XPVPivot +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double upper; + double lower; + + // + datetime from; + datetime to; + + // + int repetition; + + // + ENUM_XPV_PIVOTS type; + + // + // Combined all States ... + XPOIState state; + + // + XPVPivot() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + upper = 0; + lower = 0; + + // + to = NULL; + from = NULL; + symbol = NULL; + period = NULL; + + // + repetition = 0; + + // + type = XPV_NONE; + + // + state.Clean(); + } + + /** + * Validation ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(to) && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && + repetition > 0 && + type != XPV_NONE && + (upper > 0 || lower > 0) + // + ; + + // + return result; + } + + /** + * Check Pivot is Peak ... + * + * @return ( bool ) + */ + bool IsPeak() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_PEAK; + + // + return result; + } + + /** + * Check Pivot is Vale ... + * + * @return ( bool ) + */ + bool IsVale() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_VALE; + + // + return result; + } + + /** + * Calculate Lower for Peaks ... + * + * @return ( double ) + */ + double CalculateLower() + { + // + double result = 0; + + // + if (!IsValid() || + !IsPeak()) + { + return result; + } + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + int toIndex = iBarShift( + symbol, + period, + to // + ); + + // + int count = + fromIndex - toIndex; + + // + int llIDX = iLowest( + symbol, + period, + MODE_LOW, + count, + toIndex // + ); + + // + result = + iLow( + symbol, + period, + llIDX // + ); + + // + return result; + } + + /** + * Calculate Upper for Vales ... + * + * @return ( double ) + */ + double CalculateUpper() + { + // + double result = 0; + + // + if (!IsValid() || + !IsVale()) + { + return result; + } + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + int toIndex = iBarShift( + symbol, + period, + to // + ); + + // + int count = + fromIndex - toIndex; + + // + int hhIDX = iHighest( + symbol, + period, + MODE_HIGH, + count, + toIndex // + ); + + // + result = + iHigh( + symbol, + period, + hhIDX // + ); + + // + return result; + } + + /** + * Calculate Range of Pivot ... + * + * @return ( double ) + */ + double CalculateRange() + { + // + double result = 0; + + // + if (!IsValid() || + upper <= 0 || + lower <= 0) + { + return result; + } + + // + result = upper - lower; + + // + return result; + } + + /** + * Calculate Middle of Pivot ... + * Used for + * @return ( double ) + */ + double CalculateMid() + { + // + double result = 0; + + // + double range = CalculateRange(); + if (range <= 0) + { + return result; + } + + // + result = lower + (range / 2); + + // + return result; + } + + /** + * Calculate Liquidity Percent for Specified Direction ... + * + * @param forDirection: ENUM_X_DIRECTION member, Specified Liquidity ... + * @param price: Double, Specified Price ... + * + * @return ( double ) + */ + double CalculateLiquidityPercent( + ENUM_X_DIRECTION forDirection, + double price = 0 // + ) + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = state + .CalculateLiquidityPercent( + forDirection, + price // + ); + + // + return result; + } + + // + + /** + * Get Unique Identifier ... + * + * @return ( string ) + */ + string GetTag() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + string hash = symbol + "_" + + ToString(period) + "_" + + ToString(upper) + "," + + ToString(lower) + "_" + + ToString(from) + "," + + ToString(to); + hash = ToMD5(hash); + + // + string typeStr = + type == XPV_PEAK + ? "Peak" + : "Vale"; + + // + result = + // + "XPV_" + + typeStr + "_" + + symbol + "_" + + ToString(period) + + "_" + hash + // + ; + + // + return result; + } + + // +}; + +// +// Pivots ... +struct XPVPivotPoint +{ + // + // Props ... + double value; + int repetition; + datetime time; + ENUM_XPV_PIVOTS type; + + // + // Constructor ... + XPVPivotPoint() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + value = 0; + time = NULL; + repetition = 0; + type = XPV_NONE; + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + value > 0 && + IsValid(time) && + repetition > 0 && + type != XPV_NONE + // + ; + + // + return result; + } + + /** + * Check current Pivot Point is Peak or not ... + * + * @return ( bool ) + */ + bool IsPeak() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_PEAK; + + // + return result; + } + + /** + * Check current Pivot Point is Vale or not ... + * + * @return ( bool ) + */ + bool IsVale() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_VALE; + + // + return result; + } + + // +}; + +// +// +// + // // Consolidation Zone ... struct XConsolidationZone @@ -4589,6 +5071,900 @@ string ToString(ENUM_XPOI_EVENTS value) return result; } +// +// +// + +/** + * Find Oldest Pivot Index ... + * + * @param pivots: XPVPivot instance ... + * @return ( int ) + */ +int FindOldestPivotIndex( + XPVPivot &pivots[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(pivots); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = pivots[i]; + + // + bool isOldest = true; + for (int j = 0; j < count; j++) + { + // + XPVPivot jPivot = pivots[j]; + + // + isOldest = iPivot.from <= jPivot.from; + if (!isOldest) + { + break; + } + } + + // + if (isOldest) + { + // + result = i; + break; + } + } + + // + return result; +} + +/** + * Sort Pivots Based On From Date ... + * + * @param pivots: XPVPivot instance Collection reference ... + */ +void SortPivots( + XPVPivot &pivots[] // +) +{ + // + XPVPivot tmp[]; + Copy( + pivots, + tmp // + ); + + // + Clean(pivots); + + // + while (ArraySize(tmp) > 0) + { + // + if (ArraySize(tmp) == 1) + { + // + AddRef( + tmp[0], + pivots // + ); + + // + ArrayRemove( + tmp, + 0, + 1); + } + else + { + // + int idx = FindOldestPivotIndex(tmp); + if (IsValidIndex(idx)) + { + // + AddRef( + tmp[idx], + pivots // + ); + + // + ArrayRemove( + tmp, + idx, + 1 // + ); + } + } + } + + // + Clean(tmp); +} + +bool IsPivotBreaked( + XPVPivot &pivot, + XPVPivot &pivots[] // +) +{ + // + bool result = false; + + // + result = pivot.IsValid(); + if (!result) + { + return result; + } + + // + int count = ArraySize(pivots); + result = IsValidSize(pivots); + if (!result) + { + return result; + } + + // + // For Peaks Highs Must not Broked ... + // For Vales Lows Must not Broked ... + bool isPeak = pivot.IsPeak(); + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = pivots[i]; + + // + result = isPeak + ? iPivot.upper > pivot.upper + : iPivot.lower < pivot.lower; + if (result) + { + break; + } + } + + // + return result; +} + +/** + * Filter Broken Pivots for Detect Order Flow ... + * + * @param pivots: XPVPivot instance Collection reference ... + */ +void FilterBrokenPivots( + XPVPivot &pivots[] // +) +{ + // + XPVPivot tmp[]; + Copy( + pivots, + tmp // + ); + + // + Clean(pivots); + + // + while (ArraySize(tmp) > 0) + { + // + if (ArraySize(tmp) == 1) + { + // + AddRef( + tmp[0], + pivots // + ); + + // + ArrayRemove( + tmp, + 0, + 1 // + ); + } + else + { + // + XPVPivot pivot = tmp[0]; + + // + ArrayRemove( + tmp, + 0, + 1 // + ); + + // + bool isBreaked = IsPivotBreaked( + pivot, + tmp // + ); + if (!isBreaked) + { + // + AddRef( + pivot, + pivots // + ); + } + } + } + + // + Clean(tmp); +} + +/** + * Calculate Order Flow Direction ... + * + * @param orderFlow: XPVPivot instance Collection reference ... + * @param dir: ENUM_X_DIRECTION member reference, Hold's Calculated Direction ... + * + * @return ( bool ) + */ +bool DetectPivotDirection( + XPVPivot &orderFlow[], + ENUM_X_DIRECTION &dir // +) +{ + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + int count = ArraySize(orderFlow); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + // For Bullish Direction all Exists lowers must be Greater or Equal Prev ... + bool isBullish = false; + bool canLookupForBullish = true; + + // + // For Bearish Direction all Exists uppers must be Lesser or Equal Prev ... + bool isBearish = false; + bool canLookupForBearish = true; + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = orderFlow[i]; + + // + XPVPivot tmp[]; + Copy( + orderFlow, + tmp // + ); + ArrayRemove( + tmp, + 0, + i + 1 // + ); + + // + int tmpCount = ArraySize(tmp); + if (IsValidSize(tmpCount)) + { + // + for (int j = 0; j < tmpCount; j++) + { + // + XPVPivot jPivot = tmp[j]; + + // + // Check Bullish Direction ... + isBullish = + canLookupForBullish && + jPivot.lower >= iPivot.lower; + if (!isBullish) + { + canLookupForBullish = false; + } + + // + // Check Bearish Direction ... + isBearish = + canLookupForBearish && + jPivot.upper <= iPivot.upper; + if (!isBearish) + { + canLookupForBearish = false; + } + + // + if (!canLookupForBullish && + !canLookupForBearish) + { + break; + } + } + } + Clean(tmp); + } + + // + if (isBullish && + !isBearish) + { + dir = X_DIRECTION_BULLISH; + } + else if (isBearish && + !isBullish) + { + dir = X_DIRECTION_BEARISH; + } + + // + result = dir != X_DIRECTION_NONE; + + // + return result; +} + +/** + * Detect all POIs which inside a Pivot ... + * + * @param pivot: XPVPivot instance, Specified Pivot ... + * @param source: XPOIState instance, Reference to Source State ... + * @param state: XPOIState instance, Reference to Detected Pivots ... + * @param lookupSwingHighs: Boolean ... + * @param lookupSwingLows: Boolean ... + * @param lookupSupportZones: Boolean ... + * @param lookupResistanceZones: Boolean ... + * @param lookupSupplyZones: Boolean ... + * @param lookupDemandZones: Boolean ... + * @param lookupBullishOrderBlocks: Boolean ... + * @param lookupBearishOrderBlocks: Boolean ... + * @param lookupBullishFairValueGaps: Boolean ... + * @param lookupBearishFairValueGaps: Boolean ... + * @param lookupBullishRejectionBars: Boolean ... + * @param lookupBearishRejectionBars: Boolean ... + * @param lookupBullishMomentumBars: Boolean ... + * @param lookupBearishMomentumBars: Boolean ... + */ +void DetectPivotPOIs( + XPVPivot &pivot, + XPOIState &source, + XPOIState &state, + bool lookupSwingHighs = true, + bool lookupSwingLows = true, + bool lookupSupportZones = true, + bool lookupResistanceZones = true, + bool lookupSupplyZones = true, + bool lookupDemandZones = true, + bool lookupBullishOrderBlocks = true, + bool lookupBearishOrderBlocks = true, + bool lookupBullishFairValueGaps = true, + bool lookupBearishFairValueGaps = true, + bool lookupBullishRejectionBars = true, + bool lookupBearishRejectionBars = true, + bool lookupBullishMomentumBars = true, + bool lookupBearishMomentumBars = true // +) +{ + // + state.Clean(); + + // + if (!pivot.IsValid()) + { + return; + } + + // + int count = 0; + + // + state.symbol = pivot.symbol; + state.period = pivot.period; + state.time = TimeCurrent(); + + // + // Swings ... + + // + // Swing High ... + if (lookupSwingHighs) + { + // + count = ArraySize(source.swingHighs); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = source.swingHighs[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper; + if (isInside) + { + // + Add( + iSwing, + state.swingHighs // + ); + } + } + } + } + + // + // Swing Low ... + if (lookupSwingLows) + { + // + count = ArraySize(source.swingLows); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = source.swingLows[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low >= pivot.lower; + if (isInside) + { + // + Add( + iSwing, + state.swingLows // + ); + } + } + } + } + + // + // Support and Resistance Zones ... + + // + // Support Zones ... + if (lookupSupportZones) + { + // + count = ArraySize(source.supportZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = source.supportZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.supportZones // + ); + } + } + } + } + + // + // Resistance Zones ... + if (lookupResistanceZones) + { + // + count = ArraySize(source.resistanceZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = source.resistanceZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.resistanceZones // + ); + } + } + } + } + + // + // Supply and Demand Zones ... + + // + // Supply Zones ... + if (lookupSupplyZones) + { + // + count = ArraySize(source.supplyZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *iZone = source.supplyZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.supplyZones // + ); + } + } + } + } + + // + // Demand Zones ... + if (lookupDemandZones) + { + // + count = ArraySize(source.demandZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone *iZone = source.demandZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.demandZones // + ); + } + } + } + } + + // + // Order Blocks ... + + // + // Bullish Order Blocks ... + if (lookupBullishOrderBlocks) + { + // + count = ArraySize(source.bullishOrderBlocks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bullishOrderBlocks[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.bullishOrderBlocks // + ); + } + } + } + } + + // + // Bearish Order Blocks ... + if (lookupBearishOrderBlocks) + { + // + count = ArraySize(source.bearishOrderBlocks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bearishOrderBlocks[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.bearishOrderBlocks // + ); + } + } + } + } + + // + // Fair Value Gaps ... + + // + // Bullish Fair Value Gaps ... + if (lookupBullishFairValueGaps) + { + // + count = ArraySize(source.bullishFairValueGaps); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bullishFairValueGaps[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.bullishFairValueGaps // + ); + } + } + } + } + + // + // Bearish Fair Value Gaps ... + if (lookupBearishFairValueGaps) + { + // + count = ArraySize(source.bearishFairValueGaps); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bearishFairValueGaps[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.bearishFairValueGaps // + ); + } + } + } + } + + // + // Rejection Bars ... + + // + // Bullish Rejection Bars ... + if (lookupBullishRejectionBars) + { + // + count = ArraySize(source.bullishRejectionBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iRejection = source.bullishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low <= pivot.upper && + iBar.low >= pivot.lower; + if (isInside) + { + // + Add( + iRejection, + state.bullishRejectionBars // + ); + } + } + } + } + + // + // Bearish Rejection Bars ... + if (lookupBearishRejectionBars) + { + // + count = ArraySize(source.bearishRejectionBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iRejection = source.bearishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper && + iBar.high >= pivot.lower; + if (isInside) + { + // + Add( + iRejection, + state.bearishRejectionBars // + ); + } + } + } + } + + // + // Momentum Bars ... + + // + // Bullish Momentum Bars ... + if (lookupBullishMomentumBars) + { + // + count = ArraySize(source.bullishMomentumBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iMomentum = source.bullishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low <= pivot.upper && + iBar.low >= pivot.lower; + if (isInside) + { + // + Add( + iMomentum, + state.bullishMomentumBars // + ); + } + } + } + } + + // + // Bearish Momenum Bars ... + if (lookupBearishMomentumBars) + { + // + count = ArraySize(source.bearishMomentumBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iMomentum = source.bearishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper && + iBar.high >= pivot.lower; + if (isInside) + { + // + Add( + iMomentum, + state.bearishMomentumBars // + ); + } + } + } + } +} + /** * Add Value Change instance to Exists Collection if it's not Exists ... * @@ -4792,6 +6168,461 @@ void CombineStates( } } +/** + * Check Price Above Specified Zone ... + * + * @param bar: XOHCL instance Reference ... + * + * @return ( bool ) + */ +bool IsPriceAboveZone( + XOHCL &bar, + XCZone *zone // +) +{ + // + bool result = false; + + // + result = + zone != NULL && + bar.IsValid() && + zone.IsValidBoundary(); + if (!result) + { + return result; + } + + // + double ask = GetAsk(bar.symbol); + double bid = GetBid(bar.symbol); + + // + result = + // + ask > zone.Upper() && + bid > zone.Upper() && + bar.low > zone.Upper() + // + ; + + // + return result; +} + +/** + * Check Price Below Specified Zone ... + * + * @param bar: XOHCL instance Reference ... + * + * @return ( bool ) + */ +bool IsPriceBelowZone( + XOHCL &bar, + XCZone *zone // +) +{ + // + bool result = false; + + // + result = + zone != NULL && + bar.IsValid() && + zone.IsValidBoundary(); + if (!result) + { + return result; + } + + // + double ask = GetAsk(bar.symbol); + double bid = GetBid(bar.symbol); + + // + result = + // + ask < zone.Lower() && + bid < zone.Lower() && + bar.low < zone.Lower() + // + ; + + // + return result; +} + +/** + * Check Price Inside Specified Zone ... + * + * @param bar: XOHCL instance Reference ... + * + * @return ( bool ) + */ +bool IsPriceInsideZone( + XOHCL &bar, + XCZone *zone // +) +{ + // + bool result = false; + + // + result = + zone != NULL && + bar.IsValid() && + zone.IsValidBoundary(); + if (!result) + { + return result; + } + + // + double ask = GetAsk(bar.symbol); + double bid = GetBid(bar.symbol); + + // + result = + // + ask <= zone.Upper() && + bid <= zone.Upper() && + bar.low <= zone.Upper() + // + && + // + ask >= zone.Lower() && + bid >= zone.Lower() && + bar.low >= zone.Lower() + // + ; + + // + return result; +} + +/** + * Calculate Target for Specified Direction ... + * + * @param bar: XOHCL instance Reference ... + * @param state: XPOIState instance Reference ... + * @param forDir: ENUM_S_DIRECTION member ... + * + * @return ( double ) + */ +double CalculateTarget( + XOHCL &bar, + XPOIState &state, + ENUM_X_DIRECTION forDir // +) +{ + // + double result = 0; + + // + if (!state.IsValid() || + !state.HasChild() || + !HasDirection(forDir)) + { + return result; + } + + // + XCFVG *iFVG = NULL; + XCOrderBlock *iOB = NULL; + XCSupplyZone *iSupply = NULL; + XCDemandZone *iDemand = NULL; + XCSupportZone *iSupport = NULL; + XCResistanceZone *iResistance = NULL; + + // + bool hasOB = false; + bool hasFVG = false; + bool hasSupply = false; + bool hasDemand = false; + bool hasSupport = false; + bool hasResistance = false; + + // + int count = 0; + + // + if (IsBearish(forDir)) + { + // + // FVG ... + count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bullishFairValueGaps[i]; + + // + bool isValid = IsPriceAboveZone( + bar, + iZone // + ); + if (isValid) + { + // + iFVG = iZone; + hasFVG = true; + break; + } + } + } + + // + // OB ... + count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bullishOrderBlocks[i]; + + // + bool isValid = IsPriceAboveZone( + bar, + iZone // + ); + if (isValid) + { + // + iOB = iZone; + hasOB = true; + break; + } + } + } + + // + // SUPPORT ... + count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupportZone *iZone = state.supportZones[i]; + + // + bool isValid = IsPriceAboveZone( + bar, + iZone // + ); + if (isValid) + { + // + iSupport = iZone; + hasSupport = true; + break; + } + } + } + + // + // DEMAND ... + count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCDemandZone *iZone = state.demandZones[i]; + + // + bool isValid = IsPriceAboveZone( + bar, + iZone // + ); + if (isValid) + { + // + iDemand = iZone; + hasDemand = true; + break; + } + } + } + + // + // Summary ... + result = + hasFVG + ? iFVG.Upper() + : hasOB + ? iOB.Upper() + : hasSupport + ? iSupport.Upper() + : hasDemand + ? iDemand.Upper() + : 0; + if (hasFVG) + { + result = MathMax(result, iFVG.Upper()); + } + if (hasOB) + { + result = MathMax(result, iOB.Upper()); + } + if (hasSupport) + { + result = MathMax(result, iSupport.Upper()); + } + if (hasDemand) + { + result = MathMax(result, iDemand.Upper()); + } + } + + // + if (IsBullish(forDir)) + { + // + // FVG ... + count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCFVG *iZone = state.bearishFairValueGaps[i]; + + // + bool isValid = IsPriceBelowZone( + bar, + iZone // + ); + if (isValid) + { + // + iFVG = iZone; + hasFVG = true; + break; + } + } + } + + // + // OB ... + count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCOrderBlock *iZone = state.bearishOrderBlocks[i]; + + // + bool isValid = IsPriceBelowZone( + bar, + iZone // + ); + if (isValid) + { + // + iOB = iZone; + hasOB = true; + break; + } + } + } + + // + // RESISTANCE ... + count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCResistanceZone *iZone = state.resistanceZones[i]; + + // + bool isValid = IsPriceBelowZone( + bar, + iZone // + ); + if (isValid) + { + // + iResistance = iZone; + hasResistance = true; + break; + } + } + } + + // + // SUPPLY ... + count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = count - 1; i >= 0; i--) + { + // + XCSupplyZone *iZone = state.supplyZones[i]; + + // + bool isValid = IsPriceBelowZone( + bar, + iZone // + ); + if (isValid) + { + // + iSupply = iZone; + hasSupply = true; + break; + } + } + } + + // + // Summary ... + result = + hasFVG + ? iFVG.Lower() + : hasOB + ? iOB.Lower() + : hasSupport + ? iSupport.Lower() + : hasDemand + ? iDemand.Lower() + : 0; + if (hasFVG) + { + result = MathMin(result, iFVG.Lower()); + } + if (hasOB) + { + result = MathMin(result, iOB.Lower()); + } + if (hasSupport) + { + result = MathMin(result, iSupport.Lower()); + } + if (hasDemand) + { + result = MathMin(result, iDemand.Lower()); + } + } + + // + return result; +} + // typedef void (*TOnPOIEvent)(ENUM_XPOI_EVENTS event, XCBasePOI *param // diff --git a/Libraries/x-saherelm.x-trade.lib.mq5 b/Libraries/x-saherelm.x-trade.lib.mq5 index 28e2d13e..cf9eb5df 100644 --- a/Libraries/x-saherelm.x-trade.lib.mq5 +++ b/Libraries/x-saherelm.x-trade.lib.mq5 @@ -929,6 +929,10 @@ struct XSignal double tpLevelForBreakEven; // TP Level for Break Even ... bool riskFreeOnBreakEven; // Risk Free Signal On Break Even ... + // + // Traget ... + double target; // Force Risk Free On Target ... + // // SL Trail ... bool trailSL; // Do SL Trail ... @@ -1486,6 +1490,9 @@ struct XSignal provider = NULL; conditions = NULL; + // + target = 0; + // trailSL = false; riskFreeOnBreakEven = false; diff --git a/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 b/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 index 1557a52b..5964f433 100644 --- a/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 @@ -621,11 +621,12 @@ class XCX121SMCBaseStrategy : public XCBaseAlert int end = -1; int start = -1; result = CalculateTicksParams( - start, + start, end, minRequiredTicksVerification // ); - if (!result) { + if (!result) + { return result; } @@ -726,6 +727,61 @@ class XCX121SMCBaseStrategy : public XCBaseAlert // // Draw Functions ... + /** + * Draw Specified Signal ... + * + * @param signal: XSignal instance ... + */ + void DrawSignal(XSignal &signal) + { + // + if (!signal.IsValid()) + { + return; + } + + // + // DrawConditions(conditions); + + // + string name = signal.GetTag(); + RemoveObject(name); + + // + XCSignalObject *iObj; + iObj = new XCSignalObject(); + + // + bool isCreated = iObj.Create( + ChartIdentification(), + name, + SubWindowIdentification(), + signal // + ); + if (!isCreated) + { + return; + } + + // + iObj.TPWidth(1); + iObj.TPColor(clrGreen); + iObj.TPWidth(STYLE_DOT); + + // + iObj.SLWidth(1); + iObj.SLColor(clrRed); + iObj.SLWidth(STYLE_DOT); + + // + iObj.EntryWidth(1); + iObj.EntryColor(clrYellow); + iObj.EntryWidth(STYLE_DOT); + + // + mDrawnObjects.Add(iObj); + } + /** * Clear all Drawn Objects ... */ @@ -785,562 +841,6 @@ class XCX121SMCBaseStrategy : public XCBaseAlert } } - /** - * Draw Specified Signal ... - * - * @param signal: XSignal instance ... - */ - void DrawSignal(XSignal &signal) - { - // - if (!signal.IsValid()) - { - return; - } - - // - // DrawConditions(conditions); - - // - string name = signal.GetTag(); - RemoveObject(name); - - // - XCSignalObject *iObj; - iObj = new XCSignalObject(); - - // - bool isCreated = iObj.Create( - ChartIdentification(), - name, - SubWindowIdentification(), - signal // - ); - if (!isCreated) - { - return; - } - - // - iObj.TPWidth(1); - iObj.TPColor(clrGreen); - iObj.TPWidth(STYLE_DOT); - - // - iObj.SLWidth(1); - iObj.SLColor(clrRed); - iObj.SLWidth(STYLE_DOT); - - // - iObj.EntryWidth(1); - iObj.EntryColor(clrYellow); - iObj.EntryWidth(STYLE_DOT); - - // - mDrawnObjects.Add(iObj); - } - - /** - * Draw Specified State on Chart ... - * - * @param state: XPOIState instance ... - */ - void DrawState( - XPOIState &state, - bool forceUpdateTo = false, - bool drawSwingHighs = true, - bool drawSwingLows = true, - bool drawSupportZones = true, - bool drawResistanceZones = true, - bool drawSupplyZones = true, - bool drawDemandZones = true, - bool drawBullishOrderBlocks = true, - bool drawBearishOrderBlocks = true, - bool drawBullishFairValueGaps = true, - bool drawBearishFairValueGaps = true, - bool drawBullishRejectionBars = true, - bool drawBearishRejectionBars = true, - bool drawBullishMomentumBars = true, - bool drawBearishMomentumBars = true, - bool drawTicksZone = true // - ) - { - // - int count = 0; - datetime cTime = TimeCurrent(); - - // - // Swings ... - - // - // Swing Highs ... - if (drawSwingHighs) - { - // - count = ArraySize(state.swingHighs); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSwing item = state.swingHighs[i]; - - // - XCSwingHighObject *iObj; - bool isCreated = mPOIDrawer.CreateSwingHigh( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Swing Lows ... - if (drawSwingLows) - { - // - count = ArraySize(state.swingLows); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSwing item = state.swingLows[i]; - - // - XCSwingLowObject *iObj; - bool isCreated = mPOIDrawer.CreateSwingLow( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Support and Resistance Zones ... - - // - // Support Zones ... - if (drawSupportZones) - { - // - count = ArraySize(state.supportZones); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSupportZone item = state.supportZones[i]; - if (forceUpdateTo) - { - item.To(cTime); - } - - // - XCSupportZoneObject *iObj; - bool isCreated = mPOIDrawer.CreateSupportZone( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Resistance Zones ... - if (drawResistanceZones) - { - // - count = ArraySize(state.resistanceZones); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCResistanceZone item = state.resistanceZones[i]; - if (forceUpdateTo) - { - item.To(cTime); - } - - // - XCResistanceZoneObject *iObj; - bool isCreated = mPOIDrawer.CreateResistanceZone( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Supply and Demand Zones ... - - // - // Supply Zones ... - if (drawSupplyZones) - { - // - count = ArraySize(state.supplyZones); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSupplyZone item = state.supplyZones[i]; - if (forceUpdateTo) - { - item.To(cTime); - } - - // - XCSupplyZoneObject *iObj; - bool isCreated = mPOIDrawer.CreateSupplyZone( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Demand Zones ... - if (drawDemandZones) - { - // - count = ArraySize(state.demandZones); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCDemandZone item = state.demandZones[i]; - if (forceUpdateTo) - { - item.To(cTime); - } - - // - XCDemandZoneObject *iObj; - bool isCreated = mPOIDrawer.CreateDemandZone( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Order Blocks ... - - // - // Bullish Order Blocks ... - if (drawBullishOrderBlocks) - { - // - count = ArraySize(state.bullishOrderBlocks); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock item = state.bullishOrderBlocks[i]; - if (forceUpdateTo) - { - item.To(cTime); - } - - // - XCBullishOrderBlockObject *iObj; - bool isCreated = mPOIDrawer.CreateBullishOrderBlock( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Bearish Order Blocks ... - if (drawBearishOrderBlocks) - { - // - count = ArraySize(state.bearishOrderBlocks); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock item = state.bearishOrderBlocks[i]; - if (forceUpdateTo) - { - item.To(cTime); - } - - // - XCBearishOrderBlockObject *iObj; - bool isCreated = mPOIDrawer.CreateBearishOrderBlock( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Fair Value Gaps ... - - // - // Bullish Fair Value Gaps ... - if (drawBullishFairValueGaps) - { - // - count = ArraySize(state.bullishFairValueGaps); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG item = state.bullishFairValueGaps[i]; - if (forceUpdateTo) - { - item.To(cTime); - } - - // - XCBullishFairValueGapObject *iObj; - bool isCreated = mPOIDrawer.CreateBullishFairValueGap( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Bearish Fair Value Gaps ... - if (drawBearishFairValueGaps) - { - // - count = ArraySize(state.bearishFairValueGaps); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG item = state.bearishFairValueGaps[i]; - if (forceUpdateTo) - { - item.To(cTime); - } - - // - XCBearishFairValueGapObject *iObj; - bool isCreated = mPOIDrawer.CreateBearishFairValueGap( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Rejection Bars ... - - // - // Bullish Rejection Bars ... - if (drawBullishRejectionBars) - { - // - count = ArraySize(state.bullishRejectionBars); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCRejectionBar item = state.bullishRejectionBars[i]; - - // - XCBullishRejectionBarObject *iObj; - bool isCreated = mPOIDrawer.CreateBullishRejectionBar( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Bearish Rejection Bars ... - if (drawBearishRejectionBars) - { - // - count = ArraySize(state.bearishRejectionBars); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCRejectionBar item = state.bearishRejectionBars[i]; - - // - XCBearishRejectionBarObject *iObj; - bool isCreated = mPOIDrawer.CreateBearishRejectionBar( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Momentum Bars ... - - // - // Bullish Momentum Bars ... - if (drawBullishMomentumBars) - { - // - count = ArraySize(state.bullishMomentumBars); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCMomentumBar item = state.bullishMomentumBars[i]; - - // - XCBullishMomentumBarObject *iObj; - bool isCreated = mPOIDrawer.CreateBullishMomentumBar( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Bearish Momentum Bars ... - if (drawBearishMomentumBars) - { - // - count = ArraySize(state.bearishMomentumBars); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCMomentumBar item = state.bearishMomentumBars[i]; - - // - XCBearishMomentumBarObject *iObj; - bool isCreated = mPOIDrawer.CreateBearishMomentumBar( - item, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - } - - // - // Ticks Zone ... - if (drawTicksZone && - state.ticksZone != NULL) - { - // - XCTicksZone *iZone = state.ticksZone; - - // - if (forceUpdateTo) - { - iZone.To(cTime); - } - - // - XCTicksZoneObject *iObj; - bool isCreated = mPOIDrawer.CreateTicksZone( - iZone, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - } - /** * Add Specified Object to Drawn Objects if not Exists ... */ @@ -1377,6 +877,25 @@ class XCX121SMCBaseStrategy : public XCBaseAlert } } + /** + * Add Specified Objects to Drawn Objects if not Exists ... + */ + void AddObjectsIfNotExists(XCBaseObject *&objects[]) + { + // + int count = ArraySize(objects); + if (!IsValidSize(count)) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + AddObjectIfNotExists(objects[i]); + } + } + // // Private ... private: 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 127c510a..79e3c890 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -33,6 +33,7 @@ enum ENUM_X_CYCLES { + X_CYCLE_NONE, X_CYCLE_TRIGGER, X_CYCLE_DECISION, X_CYCLE_ANALYSE, @@ -41,6 +42,18 @@ enum ENUM_X_CYCLES X_CYCLE_VISION, }; +string ToString(ENUM_X_CYCLES value) +{ + // + string result = EnumToString(value); + + // + StringReplace(result, "X_CYCLE_", ""); + + // + return result; +} + enum ENUM_X_CYCLE_EVENTS { SAR_CHANGE_DETECTED, @@ -50,8 +63,10 @@ enum ENUM_X_CYCLE_EVENTS VWAP_ORDER_CHANGE_ETECTED, VWAP_STATE_CHANGE_DETCTED, CONSOLIDATION_BREAKED_DETECTED, - PIVOT_STARTED, - PIVOT_ENDED, + PEAK_PIVOT_STARTED, + PEAK_PIVOT_ENDED, + VALE_PIVOT_STARTED, + VALE_PIVOT_ENDED, }; class XC121SMCCycleHelper : public XCBase @@ -144,6 +159,35 @@ class XC121SMCCycleHelper : public XCBase mConsolidationLoopback = value; } + /** + * Get Valid Pivot Points Repetition Length ... + * min => 7 + * + * @return ( int ) + */ + int ValidPivotRepetition() + { + return mValidPivotRepetition; + } + + /** + * Set Valid Pivot Points Repetition Length ... + * + * @param value: Integer ... + * min => 7 + */ + void ValidPivotRepetition(int value) + { + // + if (value < 7) + { + value = 7; + } + + // + mValidPivotRepetition = value; + } + // // Actions ... @@ -191,7 +235,7 @@ class XC121SMCCycleHelper : public XCBase symbol, period // ); - mPOIDetector.MaxNumberOfRequiredPOIs(0); + mPOIDetector.MaxNumberOfRequiredPOIs(10); mPOIDetector.Init(); // @@ -457,6 +501,12 @@ class XC121SMCCycleHelper : public XCBase // if (result) { + // + if (!IsValidSize(ArraySize(mPivots))) + { + Detect(barIndex); + } + // Calculate( barIndex, @@ -572,315 +622,6 @@ class XC121SMCCycleHelper : public XCBase return result; } - /** - * Detect XPV Based POI(s) ... - * - * @param barIndex: Start Bar Index ... - * @param minRepetition: minimum Repeate of POI for Validation ... - * @param requiredPivots: Number of Min Requirement POI(s) ... - * @param pivotHelper: XC121SMCCycleHelper instance Pointer ... - * @param orderFlow: XPVPivot instance Array Reference ... - * @param orderFlowDirection: ENUM_X_DIRECTION member Reference which represents OrderFlow Direction ... - * @param maxAllowedLoopbackBars: Integer, Max Allowed Loopback Bars ... - * - * @return ( bool ) - */ - bool DetectOrderFlow( - int barIndex, - XPVPivot &orderFlow[], // OrderFlows ... - ENUM_X_DIRECTION &orderFlowDirection, // Order Flow Direction ... - int minRepetition = 0, - int requiredPivots = 0, - int maxAllowedLoopbackBars = 576 // - ) - { - // - bool result = false; - - // - orderFlowDirection = X_DIRECTION_NONE; - - // - if (maxAllowedLoopbackBars <= 0) - { - maxAllowedLoopbackBars = 1000; - } - - // - if (minRepetition <= 0) - { - minRepetition = mX121Helper.GetDonChainLength(); - } - - // - if (requiredPivots <= 0) - { - requiredPivots = 3; - } - - // - int start = barIndex; - int end = start + maxAllowedLoopbackBars; - - // - Clean(orderFlow); - - // - result = minRepetition > 0 && - requiredPivots > 0; - if (!result) - { - return result; - } - - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - double peak = 0; - XPVPivot peaks[]; - int peakRepeate = 0; - int peakToBarIndex = 0; - int peakFromBarIndex = 0; - - // - double vale = 0; - XPVPivot vales[]; - int valeRepeate = 0; - int valeToBarIndex = 0; - int valeFromBarIndex = 0; - - // - bool canLookupPeak = true; - bool canLookupVale = true; - bool canLookup = true; - while (canLookup) - { - // - // Check Peak ... - double iPeak = mX121Helper.GetPeak(barIndex); - if (iPeak != peak) - { - // - if (peak != 0 && - peakRepeate >= minRepetition) - { - // - bool isExists = false; - int count = ArraySize(peaks); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XPVPivot iPivot = peaks[i]; - - // - if (iPivot.upper == iPeak) - { - // - isExists = true; - break; - } - } - } - if (!isExists) - { - // - XPVPivot iPivot; - - // - iPivot.lower = 0; - iPivot.upper = peak; - iPivot.symbol = symbol; - iPivot.period = period; - iPivot.type = XPV_PEAK; - iPivot.repetition = peakRepeate; - iPivot.to = iTime( - symbol, - period, - peakToBarIndex // - ); - iPivot.from = iTime( - symbol, - period, - peakFromBarIndex // - ); - - // - iPivot.lower = iPivot.CalculateLower(); - - // - bool isValid = iPivot.IsValid(); - if (isValid) - { - // - AddRef( - iPivot, - peaks // - ); - } - } - } - - // - peak = iPeak; - peakRepeate = 0; - peakFromBarIndex = 0; - peakToBarIndex = barIndex; - } - else if (iPeak == peak) - { - // - peakRepeate++; - peakFromBarIndex = barIndex; - } - - // - // Check Vale ... - double iVale = mX121Helper.GetVale(barIndex); - if (iVale != vale) - { - // - if (vale != 0 && - valeRepeate >= minRepetition) - { - // - bool isExists = false; - int count = ArraySize(vales); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XPVPivot iPivot = vales[i]; - - // - if (iPivot.lower == iVale) - { - // - isExists = true; - break; - } - } - } - if (!isExists) - { - // - XPVPivot iPivot; - - // - iPivot.upper = 0; - iPivot.lower = vale; - iPivot.symbol = symbol; - iPivot.period = period; - iPivot.type = XPV_VALE; - iPivot.repetition = valeRepeate; - iPivot.to = iTime( - symbol, - period, - valeToBarIndex // - ); - iPivot.from = iTime( - symbol, - period, - valeFromBarIndex // - ); - - // - iPivot.upper = iPivot.CalculateUpper(); - - // - bool isValid = iPivot.IsValid(); - if (isValid) - { - // - AddRef( - iPivot, - vales // - ); - } - } - } - - // - vale = iVale; - valeRepeate = 0; - valeFromBarIndex = 0; - valeToBarIndex = barIndex; - } - else if (iVale == vale) - { - // - valeRepeate++; - valeFromBarIndex = barIndex; - } - - // - canLookupPeak = ArraySize(peaks) < requiredPivots; - canLookupVale = ArraySize(vales) < requiredPivots; - canLookup = barIndex < end && - (canLookupPeak || - canLookupVale); - if (canLookup) - { - barIndex++; - } - } - - // - result = IsValidSize(ArraySize(peaks)) || - IsValidSize(ArraySize(vales)); - if (!result) - { - return result; - } - - // - // Detect Order Flow ... - Copy( - peaks, - orderFlow, - false // - ); - Copy( - vales, - orderFlow, - false // - ); - int count = ArraySize(orderFlow); - result = IsValidSize(orderFlow); - if (!result) - { - return result; - } - - // - // Sort Pivots ... - SortPivots(orderFlow); - - // - // Filter Broken Order Flows ... - FilterBrokenPivots(orderFlow); - - // - // Detect Order Flow Direction ... - result = DetectPivotDirection( - orderFlow, - orderFlowDirection // - ); - if (!result) - { - return result; - } - - // - return result; - } - /** * Detect Cycle Trend Based On Pivots ... * @@ -1616,18 +1357,6 @@ class XC121SMCCycleHelper : public XCBase return result; } - /** - * Get Current Active Pivot ... - * - * @param pivot: XPVPivot instance reference ... - */ - void GetActivePivot(XPVPivot &pivot) - { - // - mActivePivot.to = TimeCurrent(); - pivot = mActivePivot; - } - /** * Count Calculated Pivots ... * @@ -1666,6 +1395,86 @@ class XC121SMCCycleHelper : public XCBase return result; } + /** + * Retrieve Last Pivot ... + * + * @param pivot: XPVPivot instance Reference ... + * + * @return ( bool ) + */ + bool GetLastPivot(XPVPivot &pivot) + { + // + bool result = false; + + // + pivot.Clean(); + + // + XPVPivot pivots[]; + int count = FillPivots(pivots); + if (IsValidSize(count)) + { + pivot = pivots[count - 1]; + } + + // + result = pivot.IsValid(); + + // + return result; + } + + /** + * Retrieve Active Peak Pivot ... + * + * @param pivot: XPVPivot instance Reference ... + * + * @return ( bool ) + */ + bool GetActivePeakPivot(XPVPivot &pivot) + { + // + bool result = false; + + // + pivot.Clean(); + + // + pivot = mActivePeakPivot; + + // + result = pivot.IsValid(); + + // + return result; + } + + /** + * Retrieve Active Vale Pivot ... + * + * @param pivot: XPVPivot instance Reference ... + * + * @return ( bool ) + */ + bool GetActiveValePivot(XPVPivot &pivot) + { + // + bool result = false; + + // + pivot.Clean(); + + // + pivot = mActiveValePivot; + + // + result = pivot.IsValid(); + + // + return result; + } + // // Virtuals ... @@ -1675,6 +1484,7 @@ class XC121SMCCycleHelper : public XCBase virtual void Default() { // + ValidPivotRepetition(21); ConsolidationLoopback(10); MaxAllowedSavedChanges(50); } @@ -2118,7 +1928,7 @@ class XC121SMCCycleHelper : public XCBase int repetition = 0; ENUM_TIMEFRAMES period = GetPeriod(); int periodSeconds = PeriodSeconds(period); - int minRepetition = mX121Helper.GetDonChainLength(); + int minRepetition = ValidPivotRepetition(); ENUM_XPV_PIVOTS type = isNewPeak ? XPV_PEAK : XPV_VALE; @@ -2180,67 +1990,340 @@ class XC121SMCCycleHelper : public XCBase } } - // // - // // Calculate Pivots ... - // if (isNewPeak || isNewVale) - // { - // // - // if (!mActivePivot.IsValid()) - // { - // // - // mActivePivot.symbol = symbol; - // mActivePivot.period = period; + // + // Calculate XPVPivot ... + int pvValidation = ValidPivotRepetition(); + if (IsValidSize(pvValidation)) + { + // + // Peak ... + mActivePeakPivot.symbol = symbol; + mActivePeakPivot.period = period; + mActivePeakPivot.type = XPV_PEAK; - // // - // mActivePivot.upper = peak; - // mActivePivot.lower = vale; + // + if (mActivePeakPivot.upper == 0 && peak > 0) + { + // + mActivePeakPivot.upper = peak; + mActivePeakPivot.lower = vale; + mActivePeakPivot.from = changeBar.time; - // // - // mActivePivot.from = cTime; - // mActivePivot.to = cTime; + // + Add( + PEAK_PIVOT_STARTED, + events // + ); + } + else if (mActivePeakPivot.upper > 0 && mActivePeakPivot.upper == peak) + { + // + mActivePeakPivot.repetition++; + mActivePeakPivot.to = changeBar.time; + } + else if (mActivePeakPivot.upper > 0 && mActivePeakPivot.upper != peak) + { + // + if (mActivePeakPivot.repetition >= pvValidation) + { + // + AddRef( + mActivePeakPivot, + mPivots // + ); - // // - // mActivePivot.type = - // isNewPeak - // ? XPV_VALE - // : XPV_PEAK; - // mActivePivot.repetition++; + // + Add( + PEAK_PIVOT_ENDED, + events // + ); - // // - // Add( - // PIVOT_STARTED, - // events // - // ); - // } - // else - // { - // // - // mActivePivot.to = cTime; + // + mActivePeakPivot.Clean(); + } + else + { + // + mActivePeakPivot.upper = peak; + mActivePeakPivot.lower = vale; + mActivePeakPivot.repetition = 0; + mActivePeakPivot.from = changeBar.time; - // // - // mActivePivot.repetition++; + // + Add( + PEAK_PIVOT_STARTED, + events // + ); + } + } - // // - // if (mActivePivot.to > mActivePivot.from) - // { - // FillPivotState(mActivePivot); - // } + // + // Vale ... + mActiveValePivot.symbol = symbol; + mActiveValePivot.period = period; + mActiveValePivot.type = XPV_VALE; - // // - // // Check Ticks Zone is Valid ... - // bool isTicksZoneValid = - // // - // mActivePivot.state.IsValid() && - // mActivePivot.state.ticksZone != NULL && - // mActivePivot.state.ticksZone.IsValid() - // // - // ; - // if (isTicksZoneValid) { - // // - // Print("Has Valid Ticks Zone ..."); - // } - // } - // } + // + // Peak ... + if (mActiveValePivot.lower == 0 && vale > 0) + { + // + mActiveValePivot.lower = vale; + mActiveValePivot.upper = peak; + mActiveValePivot.from = changeBar.time; + + // + Add( + VALE_PIVOT_STARTED, + events // + ); + } + else if (mActiveValePivot.lower > 0 && mActiveValePivot.lower == vale) + { + // + mActiveValePivot.repetition++; + mActiveValePivot.to = changeBar.time; + } + else if (mActiveValePivot.lower > 0 && mActiveValePivot.lower != vale) + { + // + if (mActiveValePivot.repetition >= pvValidation) + { + // + AddRef( + mActiveValePivot, + mPivots // + ); + + // + Add( + VALE_PIVOT_ENDED, + events // + ); + + // + mActiveValePivot.Clean(); + } + else + { + // + mActiveValePivot.lower = vale; + mActiveValePivot.upper = peak; + mActiveValePivot.repetition = 0; + mActiveValePivot.from = changeBar.time; + + // + Add( + VALE_PIVOT_STARTED, + events // + ); + } + } + } + } + + /** + * Detect Requirements ... + */ + void Detect(int barIndex) + { + // + if (isDetecting) + { + return; + } + + // + int start = barIndex; + int max = 576; + int validPivotRepetition = ValidPivotRepetition(); + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + // Try To Detect Valid Peaks or Vales ... + double peak = 0; + double vale = 0; + int peakRepetition = 0; + int valeRepetition = 0; + + // + int from = start; + int index = from; + int count = start + max; + + // + bool canContinue = true; + + // + // Loop Throug Peaks and Vales ... + while (canContinue) + { + // + datetime toTime = iTime( + symbol, + period, + index // + ); + + // + double iPeak = mX121Helper.GetPeak(index); + double iVale = mX121Helper.GetVale(index); + + // + // Peak ... + if (peak == 0 && iPeak > 0) + { + // + peak = iPeak; + peakRepetition = 0; + } + else if (peak > 0 && iPeak > 0 && peak == iPeak) + { + peakRepetition++; + } + else if (peak > 0 && iPeak > 0 && peak != iPeak) + { + // + if (peakRepetition >= validPivotRepetition) + { + // + datetime fromTime = iTime( + symbol, + period, + index - peakRepetition // + ); + + // + // Create XPVPivotPoint ... + XPVPivotPoint pivotPoint; + pivotPoint.value = iPeak; + pivotPoint.time = toTime; + pivotPoint.type = XPV_PEAK; + pivotPoint.repetition = peakRepetition; + if (pivotPoint.IsValid()) + { + // + AddRef( + pivotPoint, + mPivotPoints // + ); + } + + // + // Create XPVPivot ... + XPVPivot pivot; + pivot.symbol = symbol; + pivot.period = period; + pivot.from = fromTime; + pivot.to = toTime; + pivot.repetition = peakRepetition; + pivot.type = XPV_PEAK; + pivot.upper = peak; + pivot.lower = iVale; + FillPivotState(pivot); + + // + if (pivot.IsValid()) + { + // + AddRef( + pivot, + mPivots // + ); + } + } + + // + peak = iPeak; + peakRepetition = 0; + } + + // + // Vale ... + if (vale == 0 && iVale > 0) + { + // + vale = iVale; + valeRepetition = 0; + } + else if (vale > 0 && iVale > 0 && vale == iVale) + { + valeRepetition++; + } + else if (vale > 0 && iVale > 0 && vale != iVale) + { + // + if (valeRepetition >= validPivotRepetition) + { + // + datetime fromTime = iTime( + symbol, + period, + index - valeRepetition // + ); + + // + // Create XPVPivotPoint ... + XPVPivotPoint pivotPoint; + pivotPoint.value = iVale; + pivotPoint.time = toTime; + pivotPoint.type = XPV_VALE; + pivotPoint.repetition = valeRepetition; + if (pivotPoint.IsValid()) + { + // + AddRef( + pivotPoint, + mPivotPoints // + ); + } + + // + // Create XPVPivot ... + XPVPivot pivot; + pivot.symbol = symbol; + pivot.period = period; + pivot.from = fromTime; + pivot.to = toTime; + pivot.repetition = valeRepetition; + pivot.type = XPV_VALE; + pivot.upper = iPeak; + pivot.lower = vale; + FillPivotState(pivot); + + // + if (pivot.IsValid()) + { + // + AddRef( + pivot, + mPivots // + ); + } + } + + // + vale = iVale; + valeRepetition = 0; + } + + // + index++; + canContinue = index < count; + } + + // + int pivotsCount = ArraySize(mPivots); + if (IsValidSize(mPivots)) + { + ArrayReverse(mPivots); + } + + // + isDetecting = false; } // @@ -2263,12 +2346,14 @@ class XC121SMCCycleHelper : public XCBase XConsolidationZone mActioveConsolidationZone; // Holds Actiove Consolidation Zone ... // + int mValidPivotRepetition; // Valid Pivot Point's Repetition ... XPVPivotPoint mPivotPoints[]; // Holds Pivots ... // - XCXPVPivotObject mActivePivotObject; - XPVPivot mActivePivot; - XPVPivot mPivots[]; + bool isDetecting; + XPVPivot mActivePeakPivot; // Active Pivots ... + XPVPivot mActiveValePivot; // Active Pivots ... + XPVPivot mPivots[]; // Holds Active Pivot ... // // Actions ... diff --git a/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 b/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 index 4783928d..e698c291 100644 --- a/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 @@ -629,6 +629,16 @@ struct X121SMCTradeData return signal.tp; } + /** + * Get Model Target ... + * + * @return ( double ) + */ + double Target() + { + return signal.target; + } + /** * Get Position Spread on Open Time ... * @@ -2369,8 +2379,9 @@ class XC121SMCTradeHandler : public XCBaseAlert // // Check Deal Reason ... - bool isTP = deal.reason == DEAL_REASON_TP; - bool isSL = deal.reason == DEAL_REASON_SL; + bool isTP = deal.reason == DEAL_REASON_TP || + (deal.reason == DEAL_REASON_SL && deal.profit > 0); + bool isSL = deal.reason == DEAL_REASON_SL && deal.profit < 0; // // Prepare Specified Message Based on Deal Reason ... @@ -2494,7 +2505,7 @@ class XC121SMCTradeHandler : public XCBaseAlert // // Simulate TP/SL based on Closing Profit ... bool isTP = position.profit > 0; - bool isSL = position.profit < 0; + bool isSL = position.profit <= 0; // if (isTP || isSL) @@ -2890,7 +2901,8 @@ class XC121SMCTradeHandler : public XCBaseAlert mTrader.GetPositions( longs, shorts, - signal.symbol // + signal.symbol, + signal.provider // ); } else @@ -2899,7 +2911,8 @@ class XC121SMCTradeHandler : public XCBaseAlert mTrader.GetPositions( longs, shorts, - NULL // All Symbols ... + NULL, // All Symbols ... + signal.provider // ); } @@ -3394,6 +3407,40 @@ class XC121SMCTradeHandler : public XCBaseAlert } } } + + // + // Handle RF On Target ... + double target = iData.Target(); + bool canRF = + target > 0 && + target > entry && + (isLong + ? iPosition.sl < target + : iPosition.sl > target) && + iPosition.price > target + (10 * points); + if (canRF) + { + // + double sl = target; + double tp = iPosition.tp; + string comment = "RF On Target ..."; + bool isModified = mTrader.Modify( + iData.ticket, + sl, + tp, + comment // + ); + if (isModified) + { + // + string message = ToString(iData.Type()) + + " Position: " + + ToString(iData.ticket) + + " RF On Traget: " + ToString(target) + + " Successfully ..."; + Alert(message); + } + } } } diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index 1763304e..4fb0ae18 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -39,6 +39,7 @@ const string X121SMCXPVOBToken = "X121XPVOB"; const string X121SMCXPVDPToken = "X121XPVDP"; const string X121SMCXVWPBToken = "X121XVWPB"; const string X121SMCXTWPVToken = "X121XTWPV"; +const string X121SMCXOEPVToken = "X121XOEPV"; const string X121SMCXPVSupDemToken = "X121XPVSUPDEM"; // @@ -52,6 +53,7 @@ enum ENUM_X_121_SMC_PROVIDERS X_121_SMC_PROVIDER_XPVDP, X_121_SMC_PROVIDER_XVWPB, X_121_SMC_PROVIDER_XTWPV, + X_121_SMC_PROVIDER_XOEPV, X_121_SMC_PROVIDER_XPVSUPDEM, }; @@ -76,479 +78,6 @@ enum ENUM_X_121_SMC_SL_TYPES X_121_SMC_SL_TYPE_TENKAN_SEN, }; -// -// Pivot Types ... -enum ENUM_XPV_PIVOTS -{ - XPV_NONE, - XPV_PEAK, - XPV_VALE, -}; - -// -// Model a Pivot structure ... -struct XPVPivot -{ - // - string symbol; - ENUM_TIMEFRAMES period; - - // - double upper; - double lower; - - // - datetime from; - datetime to; - - // - int repetition; - - // - ENUM_XPV_PIVOTS type; - - // - // Combined all States ... - XPOIState state; - - // - XPVPivot() - { - Clean(); - } - - // - // Tools ... - - /** - * Cleanup ... - */ - void Clean() - { - // - upper = 0; - lower = 0; - - // - to = NULL; - from = NULL; - symbol = NULL; - period = NULL; - - // - repetition = 0; - - // - type = XPV_NONE; - - // - state.Clean(); - } - - /** - * Validation ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - // - IsValid(to) && - IsValid(from) && - IsValid(symbol) && - IsValid(period) && - repetition > 0 && - type != XPV_NONE && - (upper > 0 || lower > 0) - // - ; - - // - return result; - } - - /** - * Check Pivot is Peak ... - * - * @return ( bool ) - */ - bool IsPeak() - { - // - bool result = false; - - // - result = IsValid() && - type == XPV_PEAK; - - // - return result; - } - - /** - * Check Pivot is Vale ... - * - * @return ( bool ) - */ - bool IsVale() - { - // - bool result = false; - - // - result = IsValid() && - type == XPV_VALE; - - // - return result; - } - - /** - * Calculate Lower for Peaks ... - * - * @return ( double ) - */ - double CalculateLower() - { - // - double result = 0; - - // - if (!IsValid() || - !IsPeak()) - { - return result; - } - - // - int fromIndex = iBarShift( - symbol, - period, - from // - ); - - // - int toIndex = iBarShift( - symbol, - period, - to // - ); - - // - int count = - fromIndex - toIndex; - - // - int llIDX = iLowest( - symbol, - period, - MODE_LOW, - count, - toIndex // - ); - - // - result = - iLow( - symbol, - period, - llIDX // - ); - - // - return result; - } - - /** - * Calculate Upper for Vales ... - * - * @return ( double ) - */ - double CalculateUpper() - { - // - double result = 0; - - // - if (!IsValid() || - !IsVale()) - { - return result; - } - - // - int fromIndex = iBarShift( - symbol, - period, - from // - ); - - // - int toIndex = iBarShift( - symbol, - period, - to // - ); - - // - int count = - fromIndex - toIndex; - - // - int hhIDX = iHighest( - symbol, - period, - MODE_HIGH, - count, - toIndex // - ); - - // - result = - iHigh( - symbol, - period, - hhIDX // - ); - - // - return result; - } - - /** - * Calculate Range of Pivot ... - * - * @return ( double ) - */ - double CalculateRange() - { - // - double result = 0; - - // - if (!IsValid() || - upper <= 0 || - lower <= 0) - { - return result; - } - - // - result = upper - lower; - - // - return result; - } - - /** - * Calculate Middle of Pivot ... - * Used for - * @return ( double ) - */ - double CalculateMid() - { - // - double result = 0; - - // - double range = CalculateRange(); - if (range <= 0) - { - return result; - } - - // - result = lower + (range / 2); - - // - return result; - } - - /** - * Calculate Liquidity Percent for Specified Direction ... - * - * @param forDirection: ENUM_X_DIRECTION member, Specified Liquidity ... - * @param price: Double, Specified Price ... - * - * @return ( double ) - */ - double CalculateLiquidityPercent( - ENUM_X_DIRECTION forDirection, - double price = 0 // - ) - { - // - double result = 0; - - // - if (!IsValid()) - { - return result; - } - - // - result = state - .CalculateLiquidityPercent( - forDirection, - price // - ); - - // - return result; - } - - // - - /** - * Get Unique Identifier ... - * - * @return ( string ) - */ - string GetTag() - { - // - string result = NULL; - - // - if (!IsValid()) - { - return result; - } - - // - string hash = symbol + "_" + - ToString(period) + "_" + - ToString(upper) + "," + - ToString(lower) + "_" + - ToString(from) + "," + - ToString(to); - hash = ToMD5(hash); - - // - string typeStr = - type == XPV_PEAK - ? "Peak" - : "Vale"; - - // - result = - // - "XPV_" + - typeStr + "_" + - symbol + "_" + - ToString(period) + - "_" + hash - // - ; - - // - return result; - } - - // -}; - -// -// Pivots ... -struct XPVPivotPoint -{ - // - // Props ... - double value; - int repetition; - datetime time; - ENUM_XPV_PIVOTS type; - - // - // Constructor ... - XPVPivotPoint() - { - Clean(); - } - - // - // Tools ... - - /** - * Cleanup ... - */ - void Clean() - { - // - value = 0; - time = NULL; - repetition = 0; - type = XPV_NONE; - } - - /** - * Validate ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - // - value > 0 && - IsValid(time) && - repetition > 0 && - type != XPV_NONE - // - ; - - // - return result; - } - - /** - * Check current Pivot Point is Peak or not ... - * - * @return ( bool ) - */ - bool IsPeak() - { - // - bool result = false; - - // - result = IsValid() && - type == XPV_PEAK; - - // - return result; - } - - /** - * Check current Pivot Point is Vale or not ... - * - * @return ( bool ) - */ - bool IsVale() - { - // - bool result = false; - - // - result = IsValid() && - type == XPV_VALE; - - // - return result; - } - - // -}; - // // Each Market Cycle (Time Frame) Conditions // Model as this Structure ... @@ -762,6 +291,7 @@ struct X121SMCStrategyConditions // double sl; double tp; + double target; string provider; ENUM_X_DIRECTION signalDir; ENUM_X_DIRECTION marketStructureDir; @@ -1023,899 +553,6 @@ typedef void (*TOnX121SMCSignal)( // // Extentions ... -/** - * Find Oldest Pivot Index ... - * - * @param pivots: XPVPivot instance ... - * @return ( int ) - */ -int FindOldestPivotIndex( - XPVPivot &pivots[] // -) -{ - // - int result = -1; - - // - int count = ArraySize(pivots); - if (!IsValidSize(count)) - { - return result; - } - - // - for (int i = 0; i < count; i++) - { - // - XPVPivot iPivot = pivots[i]; - - // - bool isOldest = true; - for (int j = 0; j < count; j++) - { - // - XPVPivot jPivot = pivots[j]; - - // - isOldest = iPivot.from <= jPivot.from; - if (!isOldest) - { - break; - } - } - - // - if (isOldest) - { - // - result = i; - break; - } - } - - // - return result; -} - -/** - * Sort Pivots Based On From Date ... - * - * @param pivots: XPVPivot instance Collection reference ... - */ -void SortPivots( - XPVPivot &pivots[] // -) -{ - // - XPVPivot tmp[]; - Copy( - pivots, - tmp // - ); - - // - Clean(pivots); - - // - while (ArraySize(tmp) > 0) - { - // - if (ArraySize(tmp) == 1) - { - // - AddRef( - tmp[0], - pivots // - ); - - // - ArrayRemove( - tmp, - 0, - 1); - } - else - { - // - int idx = FindOldestPivotIndex(tmp); - if (IsValidIndex(idx)) - { - // - AddRef( - tmp[idx], - pivots // - ); - - // - ArrayRemove( - tmp, - idx, - 1 // - ); - } - } - } - - // - Clean(tmp); -} - -bool IsPivotBreaked( - XPVPivot &pivot, - XPVPivot &pivots[] // -) -{ - // - bool result = false; - - // - result = pivot.IsValid(); - if (!result) - { - return result; - } - - // - int count = ArraySize(pivots); - result = IsValidSize(pivots); - if (!result) - { - return result; - } - - // - // For Peaks Highs Must not Broked ... - // For Vales Lows Must not Broked ... - bool isPeak = pivot.IsPeak(); - - // - for (int i = 0; i < count; i++) - { - // - XPVPivot iPivot = pivots[i]; - - // - result = isPeak - ? iPivot.upper > pivot.upper - : iPivot.lower < pivot.lower; - if (result) - { - break; - } - } - - // - return result; -} - -/** - * Filter Broken Pivots for Detect Order Flow ... - * - * @param pivots: XPVPivot instance Collection reference ... - */ -void FilterBrokenPivots( - XPVPivot &pivots[] // -) -{ - // - XPVPivot tmp[]; - Copy( - pivots, - tmp // - ); - - // - Clean(pivots); - - // - while (ArraySize(tmp) > 0) - { - // - if (ArraySize(tmp) == 1) - { - // - AddRef( - tmp[0], - pivots // - ); - - // - ArrayRemove( - tmp, - 0, - 1 // - ); - } - else - { - // - XPVPivot pivot = tmp[0]; - - // - ArrayRemove( - tmp, - 0, - 1 // - ); - - // - bool isBreaked = IsPivotBreaked( - pivot, - tmp // - ); - if (!isBreaked) - { - // - AddRef( - pivot, - pivots // - ); - } - } - } - - // - Clean(tmp); -} - -/** - * Calculate Order Flow Direction ... - * - * @param orderFlow: XPVPivot instance Collection reference ... - * @param dir: ENUM_X_DIRECTION member reference, Hold's Calculated Direction ... - * - * @return ( bool ) - */ -bool DetectPivotDirection( - XPVPivot &orderFlow[], - ENUM_X_DIRECTION &dir // -) -{ - // - bool result = false; - - // - dir = X_DIRECTION_NONE; - - // - int count = ArraySize(orderFlow); - result = IsValidSize(count); - if (!result) - { - return result; - } - - // - // For Bullish Direction all Exists lowers must be Greater or Equal Prev ... - bool isBullish = false; - bool canLookupForBullish = true; - - // - // For Bearish Direction all Exists uppers must be Lesser or Equal Prev ... - bool isBearish = false; - bool canLookupForBearish = true; - - // - for (int i = 0; i < count; i++) - { - // - XPVPivot iPivot = orderFlow[i]; - - // - XPVPivot tmp[]; - Copy( - orderFlow, - tmp // - ); - ArrayRemove( - tmp, - 0, - i + 1 // - ); - - // - int tmpCount = ArraySize(tmp); - if (IsValidSize(tmpCount)) - { - // - for (int j = 0; j < tmpCount; j++) - { - // - XPVPivot jPivot = tmp[j]; - - // - // Check Bullish Direction ... - isBullish = - canLookupForBullish && - jPivot.lower >= iPivot.lower; - if (!isBullish) - { - canLookupForBullish = false; - } - - // - // Check Bearish Direction ... - isBearish = - canLookupForBearish && - jPivot.upper <= iPivot.upper; - if (!isBearish) - { - canLookupForBearish = false; - } - - // - if (!canLookupForBullish && - !canLookupForBearish) - { - break; - } - } - } - Clean(tmp); - } - - // - if (isBullish && - !isBearish) - { - dir = X_DIRECTION_BULLISH; - } - else if (isBearish && - !isBullish) - { - dir = X_DIRECTION_BEARISH; - } - - // - result = dir != X_DIRECTION_NONE; - - // - return result; -} - -/** - * Detect all POIs which inside a Pivot ... - * - * @param pivot: XPVPivot instance, Specified Pivot ... - * @param source: XPOIState instance, Reference to Source State ... - * @param state: XPOIState instance, Reference to Detected Pivots ... - * @param lookupSwingHighs: Boolean ... - * @param lookupSwingLows: Boolean ... - * @param lookupSupportZones: Boolean ... - * @param lookupResistanceZones: Boolean ... - * @param lookupSupplyZones: Boolean ... - * @param lookupDemandZones: Boolean ... - * @param lookupBullishOrderBlocks: Boolean ... - * @param lookupBearishOrderBlocks: Boolean ... - * @param lookupBullishFairValueGaps: Boolean ... - * @param lookupBearishFairValueGaps: Boolean ... - * @param lookupBullishRejectionBars: Boolean ... - * @param lookupBearishRejectionBars: Boolean ... - * @param lookupBullishMomentumBars: Boolean ... - * @param lookupBearishMomentumBars: Boolean ... - */ -void DetectPivotPOIs( - XPVPivot &pivot, - XPOIState &source, - XPOIState &state, - bool lookupSwingHighs = true, - bool lookupSwingLows = true, - bool lookupSupportZones = true, - bool lookupResistanceZones = true, - bool lookupSupplyZones = true, - bool lookupDemandZones = true, - bool lookupBullishOrderBlocks = true, - bool lookupBearishOrderBlocks = true, - bool lookupBullishFairValueGaps = true, - bool lookupBearishFairValueGaps = true, - bool lookupBullishRejectionBars = true, - bool lookupBearishRejectionBars = true, - bool lookupBullishMomentumBars = true, - bool lookupBearishMomentumBars = true // -) -{ - // - state.Clean(); - - // - if (!pivot.IsValid()) - { - return; - } - - // - int count = 0; - - // - state.symbol = pivot.symbol; - state.period = pivot.period; - state.time = TimeCurrent(); - - // - // Swings ... - - // - // Swing High ... - if (lookupSwingHighs) - { - // - count = ArraySize(source.swingHighs); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSwing *iSwing = source.swingHighs[i]; - - // - XOHCL iBar; - bool isFilled = iSwing.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isInside = iBar.high <= pivot.upper; - if (isInside) - { - // - Add( - iSwing, - state.swingHighs // - ); - } - } - } - } - - // - // Swing Low ... - if (lookupSwingLows) - { - // - count = ArraySize(source.swingLows); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSwing *iSwing = source.swingLows[i]; - - // - XOHCL iBar; - bool isFilled = iSwing.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isInside = iBar.low >= pivot.lower; - if (isInside) - { - // - Add( - iSwing, - state.swingLows // - ); - } - } - } - } - - // - // Support and Resistance Zones ... - - // - // Support Zones ... - if (lookupSupportZones) - { - // - count = ArraySize(source.supportZones); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSupportZone *iZone = source.supportZones[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - Add( - iZone, - state.supportZones // - ); - } - } - } - } - - // - // Resistance Zones ... - if (lookupResistanceZones) - { - // - count = ArraySize(source.resistanceZones); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCResistanceZone *iZone = source.resistanceZones[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - Add( - iZone, - state.resistanceZones // - ); - } - } - } - } - - // - // Supply and Demand Zones ... - - // - // Supply Zones ... - if (lookupSupplyZones) - { - // - count = ArraySize(source.supplyZones); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSupplyZone *iZone = source.supplyZones[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - Add( - iZone, - state.supplyZones // - ); - } - } - } - } - - // - // Demand Zones ... - if (lookupDemandZones) - { - // - count = ArraySize(source.demandZones); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCDemandZone *iZone = source.demandZones[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - Add( - iZone, - state.demandZones // - ); - } - } - } - } - - // - // Order Blocks ... - - // - // Bullish Order Blocks ... - if (lookupBullishOrderBlocks) - { - // - count = ArraySize(source.bullishOrderBlocks); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *iZone = source.bullishOrderBlocks[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - Add( - iZone, - state.bullishOrderBlocks // - ); - } - } - } - } - - // - // Bearish Order Blocks ... - if (lookupBearishOrderBlocks) - { - // - count = ArraySize(source.bearishOrderBlocks); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *iZone = source.bearishOrderBlocks[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - Add( - iZone, - state.bearishOrderBlocks // - ); - } - } - } - } - - // - // Fair Value Gaps ... - - // - // Bullish Fair Value Gaps ... - if (lookupBullishFairValueGaps) - { - // - count = ArraySize(source.bullishFairValueGaps); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG *iZone = source.bullishFairValueGaps[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - Add( - iZone, - state.bullishFairValueGaps // - ); - } - } - } - } - - // - // Bearish Fair Value Gaps ... - if (lookupBearishFairValueGaps) - { - // - count = ArraySize(source.bearishFairValueGaps); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG *iZone = source.bearishFairValueGaps[i]; - - // - bool isInside = - iZone.Upper() <= pivot.upper && - iZone.Lower() >= pivot.lower; - if (isInside) - { - // - Add( - iZone, - state.bearishFairValueGaps // - ); - } - } - } - } - - // - // Rejection Bars ... - - // - // Bullish Rejection Bars ... - if (lookupBullishRejectionBars) - { - // - count = ArraySize(source.bullishRejectionBars); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCRejectionBar *iRejection = source.bullishRejectionBars[i]; - - // - XOHCL iBar; - bool isFilled = iRejection.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isInside = iBar.low <= pivot.upper && - iBar.low >= pivot.lower; - if (isInside) - { - // - Add( - iRejection, - state.bullishRejectionBars // - ); - } - } - } - } - - // - // Bearish Rejection Bars ... - if (lookupBearishRejectionBars) - { - // - count = ArraySize(source.bearishRejectionBars); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCRejectionBar *iRejection = source.bearishRejectionBars[i]; - - // - XOHCL iBar; - bool isFilled = iRejection.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isInside = iBar.high <= pivot.upper && - iBar.high >= pivot.lower; - if (isInside) - { - // - Add( - iRejection, - state.bearishRejectionBars // - ); - } - } - } - } - - // - // Momentum Bars ... - - // - // Bullish Momentum Bars ... - if (lookupBullishMomentumBars) - { - // - count = ArraySize(source.bullishMomentumBars); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCMomentumBar *iMomentum = source.bullishMomentumBars[i]; - - // - XOHCL iBar; - bool isFilled = iMomentum.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isInside = iBar.low <= pivot.upper && - iBar.low >= pivot.lower; - if (isInside) - { - // - Add( - iMomentum, - state.bullishMomentumBars // - ); - } - } - } - } - - // - // Bearish Momenum Bars ... - if (lookupBearishMomentumBars) - { - // - count = ArraySize(source.bearishMomentumBars); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCMomentumBar *iMomentum = source.bearishMomentumBars[i]; - - // - XOHCL iBar; - bool isFilled = iMomentum.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isInside = iBar.high <= pivot.upper && - iBar.high >= pivot.lower; - if (isInside) - { - // - Add( - iMomentum, - state.bearishMomentumBars // - ); - } - } - } - } -} - -// -// Provider Extensions ... - /** * Validate a Signal Provider ... * @@ -1981,6 +618,11 @@ string ToString(ENUM_X_121_SMC_PROVIDERS value) result = X121SMCXTWPVToken; break; + // + case X_121_SMC_PROVIDER_XOEPV: + result = X121SMCXOEPVToken; + break; + // case X_121_SMC_PROVIDER_XPVSUPDEM: result = X121SMCXPVSupDemToken; @@ -2030,6 +672,10 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value) { result = X_121_SMC_PROVIDER_XTWPV; } + else if (Contains(X121SMCXOEPVToken, value)) + { + result = X_121_SMC_PROVIDER_XOEPV; + } else if (Contains(X121SMCXPVSupDemToken, value)) { result = X_121_SMC_PROVIDER_XPVSUPDEM; diff --git a/X121SMCEA/Signals/x-121.smc.test.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.test.signal.lib.mq5 index eac77ea9..57e1256e 100644 --- a/X121SMCEA/Signals/x-121.smc.test.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.test.signal.lib.mq5 @@ -37,6 +37,7 @@ struct X121SMCStrategyTestSignalConditions // double sl; + double target; ENUM_X_DIRECTION dir; ENUM_X_POSITION_TYPES type; @@ -64,6 +65,7 @@ struct X121SMCStrategyTestSignalConditions { // sl = 0; + target = 0; // dir = X_DIRECTION_NONE; diff --git a/X121SMCEA/Signals/x-121.smc.xoepv.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xoepv.signal.lib.mq5 new file mode 100644 index 00000000..894ce1ae --- /dev/null +++ b/X121SMCEA/Signals/x-121.smc.xoepv.signal.lib.mq5 @@ -0,0 +1,1058 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: +// Description: provide all Signalling functions ... +// +// +// 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 + +// +// Imports ... +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +// Definitions ... +struct X121SMCStrategyXOEPVSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + XCFVG *bullishOBs[]; + XCFVG *bearishOBs[]; + + // + // Constructor ... + X121SMCStrategyXOEPVSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + ExtensionClean(); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + /** + * Clean Additional Properties ... + */ + void ExtensionClean() + { + CleanOBs(); + } + + void CleanOBs() + { + // + Clean(bullishOBs); + Clean(bearishOBs); + } + + int CountBullishOBs() + { + return ArraySize(bullishOBs); + } + + bool HasBullishOBs() + { + return CountBullishOBs() >= 3; + } + + int CountBearishOBs() + { + return ArraySize(bearishOBs); + } + + bool HasBearishOBs() + { + return CountBearishOBs() >= 3; + } + + // +}; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXOEPVSiganlSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXOEPVSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Setup Conditions ... + + // + // Vision ... + + // + double visionVWapFast = visionConditions.x121Conditions.vwapFastBuffer[1]; + double visionVWapMid = visionConditions.x121Conditions.vwapMidBuffer[1]; + double visionVWapSlow = visionConditions.x121Conditions.vwapSlowBuffer[1]; + + // + double visionVWapFastPrev = visionConditions.x121Conditions.vwapFastBuffer[2]; + double visionVWapMidPrev = visionConditions.x121Conditions.vwapMidBuffer[2]; + double visionVWapSlowPrev = visionConditions.x121Conditions.vwapSlowBuffer[2]; + + // + double visionVWaps[3] = { + visionVWapFast, + visionVWapMid, + visionVWapSlow, + }; + double visionVWapMax = GetMax(visionVWaps); + double visionVWapMin = GetMin(visionVWaps); + + // + bool isVisionVWapFastCrossedOverMid = visionVWapFast > visionVWapMid && + !(visionVWapFastPrev > visionVWapMidPrev); + + // + bool isVisionVWapFastCrossedUnderMid = visionVWapFast < visionVWapMid && + !(visionVWapFastPrev < visionVWapMidPrev); + + // + bool isVisionVWapBullishState = visionConditions.x121Conditions.isVWapBullishState; + bool isVisionVWapSwitchedToBullishState = visionConditions.x121Conditions.isVWapSwitchedToBullishState; + + // + bool isVisionVWapBearishState = visionConditions.x121Conditions.isVWapBearishState; + bool isVisionVWapSwitchedToBearishState = visionConditions.x121Conditions.isVWapSwitchedToBearishState; + + // + bool isVisionVWapBullishOrdered = visionConditions.x121Conditions.isVWapBullishOrdered; + bool isVisionVWapSwitchedToBullishOrdered = visionConditions.x121Conditions.isVWapSwitchedToBullishOrdered; + + // + bool isVisionVWapBearishOrdered = visionConditions.x121Conditions.isVWapBearishOrdered; + bool isVisionVWapSwitchedToBearishOrdered = visionConditions.x121Conditions.isVWapSwitchedToBearishOrdered; + + // + bool isVisionVWapBullishFormed = + // + (isVisionVWapBullishOrdered || + isVisionVWapSwitchedToBullishOrdered) && + (isVisionVWapBullishState || + isVisionVWapSwitchedToBullishState) + // + ; + + // + bool isVisionVWapBearishFormed = + // + (isVisionVWapBearishOrdered || + isVisionVWapSwitchedToBearishOrdered) && + (isVisionVWapBearishState || + isVisionVWapSwitchedToBearishState) + // + ; + + // + // Consolidation ... + + // + double consolidationVWapFast = consolidationConditions.x121Conditions.vwapFastBuffer[1]; + double consolidationVWapMid = consolidationConditions.x121Conditions.vwapMidBuffer[1]; + double consolidationVWapSlow = consolidationConditions.x121Conditions.vwapSlowBuffer[1]; + + // + double consolidationVWapFastPrev = consolidationConditions.x121Conditions.vwapFastBuffer[2]; + double consolidationVWapMidPrev = consolidationConditions.x121Conditions.vwapMidBuffer[2]; + double consolidationVWapSlowPrev = consolidationConditions.x121Conditions.vwapSlowBuffer[2]; + + // + double consolidationVWaps[3] = { + consolidationVWapFast, + consolidationVWapMid, + consolidationVWapSlow, + }; + double consolidationVWapMax = GetMax(consolidationVWaps); + double consolidationVWapMin = GetMin(consolidationVWaps); + + // + bool isConsolidationVWapBullishState = consolidationConditions.x121Conditions.isVWapBullishState; + bool isConsolidationVWapSwitchedToBullishState = consolidationConditions.x121Conditions.isVWapSwitchedToBullishState; + + // + bool isConsolidationVWapBearishState = consolidationConditions.x121Conditions.isVWapBearishState; + bool isConsolidationVWapSwitchedToBearishState = consolidationConditions.x121Conditions.isVWapSwitchedToBearishState; + + // + bool isConsolidationVWapBullishOrdered = consolidationConditions.x121Conditions.isVWapBullishOrdered; + bool isConsolidationVWapSwitchedToBullishOrdered = consolidationConditions.x121Conditions.isVWapSwitchedToBullishOrdered; + + // + bool isConsolidationVWapBearishOrdered = consolidationConditions.x121Conditions.isVWapBearishOrdered; + bool isConsolidationVWapSwitchedToBearishOrdered = consolidationConditions.x121Conditions.isVWapSwitchedToBearishOrdered; + + // + bool isConsolidationVWapBullishFormed = + // + (isConsolidationVWapBullishOrdered || + isConsolidationVWapSwitchedToBullishOrdered) && + (isConsolidationVWapBullishState || + isConsolidationVWapSwitchedToBullishState) + // + ; + + // + bool isConsolidationVWapBearishFormed = + // + (isConsolidationVWapBearishOrdered || + isConsolidationVWapSwitchedToBearishOrdered) && + (isConsolidationVWapBearishState || + isConsolidationVWapSwitchedToBearishState) + // + ; + + // + // Verification ... + + // + double verificationVWapFast = verificationConditions.x121Conditions.vwapFastBuffer[1]; + double verificationVWapMid = verificationConditions.x121Conditions.vwapMidBuffer[1]; + double verificationVWapSlow = verificationConditions.x121Conditions.vwapSlowBuffer[1]; + + // + double verificationVWapFastPrev = verificationConditions.x121Conditions.vwapFastBuffer[2]; + double verificationVWapMidPrev = verificationConditions.x121Conditions.vwapMidBuffer[2]; + double verificationVWapSlowPrev = verificationConditions.x121Conditions.vwapSlowBuffer[2]; + + // + double verificationVWaps[3] = { + verificationVWapFast, + verificationVWapMid, + verificationVWapSlow, + }; + double verificationVWapMax = GetMax(verificationVWaps); + double verificationVWapMin = GetMin(verificationVWaps); + + // + bool isVerificationVWapBullishState = verificationConditions.x121Conditions.isVWapBullishState; + bool isVerificationVWapSwitchedToBullishState = verificationConditions.x121Conditions.isVWapSwitchedToBullishState; + + // + bool isVerificationVWapBearishState = verificationConditions.x121Conditions.isVWapBearishState; + bool isVerificationVWapSwitchedToBearishState = verificationConditions.x121Conditions.isVWapSwitchedToBearishState; + + // + bool isVerificationVWapBullishOrdered = verificationConditions.x121Conditions.isVWapBullishOrdered; + bool isVerificationVWapSwitchedToBullishOrdered = verificationConditions.x121Conditions.isVWapSwitchedToBullishOrdered; + + // + bool isVerificationVWapBearishOrdered = verificationConditions.x121Conditions.isVWapBearishOrdered; + bool isVerificationVWapSwitchedToBearishOrdered = verificationConditions.x121Conditions.isVWapSwitchedToBearishOrdered; + + // + bool isVerificationVWapBullishFormed = + // + (isVerificationVWapBullishOrdered || + isVerificationVWapSwitchedToBullishOrdered) && + (isVerificationVWapBullishState || + isVerificationVWapSwitchedToBullishState) + // + ; + + // + bool isVerificationVWapBearishFormed = + // + (isVerificationVWapBearishOrdered || + isVerificationVWapSwitchedToBearishOrdered) && + (isVerificationVWapBearishState || + isVerificationVWapSwitchedToBearishState) + // + ; + + // + // Analyse ... + + // + double analyseVWapFast = analyseConditions.x121Conditions.vwapFastBuffer[1]; + double analyseVWapMid = analyseConditions.x121Conditions.vwapMidBuffer[1]; + double analyseVWapSlow = analyseConditions.x121Conditions.vwapSlowBuffer[1]; + + // + double analyseVWapFastPrev = analyseConditions.x121Conditions.vwapFastBuffer[2]; + double analyseVWapMidPrev = analyseConditions.x121Conditions.vwapMidBuffer[2]; + double analyseVWapSlowPrev = analyseConditions.x121Conditions.vwapSlowBuffer[2]; + + // + double analyseVWaps[3] = { + analyseVWapFast, + analyseVWapMid, + analyseVWapSlow, + }; + double analyseVWapMax = GetMax(analyseVWaps); + double analyseVWapMin = GetMin(analyseVWaps); + + // + bool isAnalyseVWapBullishState = analyseConditions.x121Conditions.isVWapBullishState; + bool isAnalyseVWapSwitchedToBullishState = analyseConditions.x121Conditions.isVWapSwitchedToBullishState; + + // + bool isAnalyseVWapBearishState = analyseConditions.x121Conditions.isVWapBearishState; + bool isAnalyseVWapSwitchedToBearishState = analyseConditions.x121Conditions.isVWapSwitchedToBearishState; + + // + bool isAnalyseVWapBullishOrdered = analyseConditions.x121Conditions.isVWapBullishOrdered; + bool isAnalyseVWapSwitchedToBullishOrdered = analyseConditions.x121Conditions.isVWapSwitchedToBullishOrdered; + + // + bool isAnalyseVWapBearishOrdered = analyseConditions.x121Conditions.isVWapBearishOrdered; + bool isAnalyseVWapSwitchedToBearishOrdered = analyseConditions.x121Conditions.isVWapSwitchedToBearishOrdered; + + // + bool isAnalyseVWapBullishFormed = + // + (isAnalyseVWapBullishOrdered || + isAnalyseVWapSwitchedToBullishOrdered) && + (isAnalyseVWapBullishState || + isAnalyseVWapSwitchedToBullishState) + // + ; + + // + bool isAnalyseVWapBearishFormed = + // + (isAnalyseVWapBearishOrdered || + isAnalyseVWapSwitchedToBearishOrdered) && + (isAnalyseVWapBearishState || + isAnalyseVWapSwitchedToBearishState) + // + ; + + // + // Summary VWap ... + + // + isBullish = + // isVisionVWapBullishFormed && + isConsolidationVWapBullishFormed && + isVerificationVWapBullishFormed && + isAnalyseVWapBullishFormed; + + // + isBearish = + // isVisionVWapBearishFormed && + isConsolidationVWapBearishFormed && + isVerificationVWapBearishFormed && + isAnalyseVWapBearishFormed; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Clean Conditions for Regenerate ... + conditions.CleanOBs(); + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCXOEPVSiganlTrigger( + // + X121SMCStrategyXOEPVSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = IsBullish(setupDir); + bool isBearish = IsBearish(setupDir); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + double ll = cBar.FindLowest(9, MODE_LOW); + double hh = cBar.FindHighest(9, MODE_HIGH); + + // + int zoneValidationDivider = 10; + int validPivotRepetition = triggerCycleHelper.mX121Helper + .GetDonChainLength(); + + // + double selectedSL = 0; + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Trigger Conditions ... + + // + // Decision ... + + // + double decisionVWapFast = decisionConditions.x121Conditions.vwapFastBuffer[1]; + double decisionVWapMid = decisionConditions.x121Conditions.vwapMidBuffer[1]; + double decisionVWapSlow = decisionConditions.x121Conditions.vwapSlowBuffer[1]; + + // + double decisionVWapFastPrev = decisionConditions.x121Conditions.vwapFastBuffer[2]; + double decisionVWapMidPrev = decisionConditions.x121Conditions.vwapMidBuffer[2]; + double decisionVWapSlowPrev = decisionConditions.x121Conditions.vwapSlowBuffer[2]; + + // + double decisionVWaps[3] = { + decisionVWapFast, + decisionVWapMid, + decisionVWapSlow, + }; + double decisionVWapMax = GetMax(decisionVWaps); + double decisionVWapMin = GetMin(decisionVWaps); + + // + bool isDecisionVWapBullishState = decisionConditions.x121Conditions.isVWapBullishState; + bool isDecisionVWapSwitchedToBullishState = decisionConditions.x121Conditions.isVWapSwitchedToBullishState; + + // + bool isDecisionVWapBearishState = decisionConditions.x121Conditions.isVWapBearishState; + bool isDecisionVWapSwitchedToBearishState = decisionConditions.x121Conditions.isVWapSwitchedToBearishState; + + // + bool isDecisionVWapBullishOrdered = decisionConditions.x121Conditions.isVWapBullishOrdered; + bool isDecisionVWapSwitchedToBullishOrdered = decisionConditions.x121Conditions.isVWapSwitchedToBullishOrdered; + + // + bool isDecisionVWapBearishOrdered = decisionConditions.x121Conditions.isVWapBearishOrdered; + bool isDecisionVWapSwitchedToBearishOrdered = decisionConditions.x121Conditions.isVWapSwitchedToBearishOrdered; + + // + bool isDecisionVWapBullishFormed = + // + (isDecisionVWapBullishOrdered || + isDecisionVWapSwitchedToBullishOrdered) && + (isDecisionVWapBullishState || + isDecisionVWapSwitchedToBullishState) + // + ; + + // + bool isDecisionVWapBearishFormed = + // + (isDecisionVWapBearishOrdered || + isDecisionVWapSwitchedToBearishOrdered) && + (isDecisionVWapBearishState || + isDecisionVWapSwitchedToBearishState) + // + ; + + // + // Trigger ... + + // + double triggerVWapFast = triggerConditions.x121Conditions.vwapFastBuffer[1]; + double triggerVWapMid = triggerConditions.x121Conditions.vwapMidBuffer[1]; + double triggerVWapSlow = triggerConditions.x121Conditions.vwapSlowBuffer[1]; + + // + double triggerVWapFastPrev = triggerConditions.x121Conditions.vwapFastBuffer[2]; + double triggerVWapMidPrev = triggerConditions.x121Conditions.vwapMidBuffer[2]; + double triggerVWapSlowPrev = triggerConditions.x121Conditions.vwapSlowBuffer[2]; + + // + double triggerVWaps[3] = { + triggerVWapFast, + triggerVWapMid, + triggerVWapSlow, + }; + double triggerVWapMax = GetMax(triggerVWaps); + double triggerVWapMin = GetMin(triggerVWaps); + + // + bool isTriggerVWapBullishState = triggerConditions.x121Conditions.isVWapBullishState; + bool isTriggerVWapSwitchedToBullishState = triggerConditions.x121Conditions.isVWapSwitchedToBullishState; + + // + bool isTriggerVWapBearishState = triggerConditions.x121Conditions.isVWapBearishState; + bool isTriggerVWapSwitchedToBearishState = triggerConditions.x121Conditions.isVWapSwitchedToBearishState; + + // + bool isTriggerVWapBullishOrdered = triggerConditions.x121Conditions.isVWapBullishOrdered; + bool isTriggerVWapSwitchedToBullishOrdered = triggerConditions.x121Conditions.isVWapSwitchedToBullishOrdered; + + // + bool isTriggerVWapBearishOrdered = triggerConditions.x121Conditions.isVWapBearishOrdered; + bool isTriggerVWapSwitchedToBearishOrdered = triggerConditions.x121Conditions.isVWapSwitchedToBearishOrdered; + + // + bool isTriggerVWapBullishFormed = + // + (isTriggerVWapBullishState && + isTriggerVWapSwitchedToBullishOrdered) || + (isTriggerVWapBullishOrdered && + isTriggerVWapSwitchedToBullishState) + // + ; + + // + bool isTriggerVWapBearishFormed = + // + (isTriggerVWapBearishState && + isTriggerVWapSwitchedToBearishOrdered) || + (isTriggerVWapBearishOrdered && + isTriggerVWapSwitchedToBearishState) + // + ; + + // + isBullish = + // + isBullish && + isTriggerVWapBullishFormed && + isDecisionVWapBullishFormed + // + ; + + // + isBearish = + // + isBearish && + isTriggerVWapBearishFormed && + isDecisionVWapBearishFormed + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + return result; + } + + // + conditions.triggerTime = cTime; + conditions.sl = isBullish + ? triggerVWapMin + : triggerVWapMax; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + return result; +} + +// diff --git a/X121SMCEA/Signals/x-121.smc.xpvdp.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xpvdp.signal.lib.mq5 index 91cd77f5..c1008ead 100644 --- a/X121SMCEA/Signals/x-121.smc.xpvdp.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xpvdp.signal.lib.mq5 @@ -37,6 +37,7 @@ struct X121SMCStrategyXPVDPSignalConditions // double sl; + double target; ENUM_X_DIRECTION dir; ENUM_X_POSITION_TYPES type; @@ -68,6 +69,7 @@ struct X121SMCStrategyXPVDPSignalConditions { // sl = 0; + target = 0; // dir = X_DIRECTION_NONE; diff --git a/X121SMCEA/Signals/x-121.smc.xpvob.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xpvob.signal.lib.mq5 index df024e04..61cbd8d6 100644 --- a/X121SMCEA/Signals/x-121.smc.xpvob.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xpvob.signal.lib.mq5 @@ -37,6 +37,7 @@ struct X121SMCStrategyXPVOBSignalConditions // double sl; + double target; ENUM_X_DIRECTION dir; ENUM_X_POSITION_TYPES type; @@ -73,6 +74,7 @@ struct X121SMCStrategyXPVOBSignalConditions { // sl = 0; + target = 0; // dir = X_DIRECTION_NONE; diff --git a/X121SMCEA/Signals/x-121.smc.xpvsupdem.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xpvsupdem.signal.lib.mq5 index 5a84cfd8..c9cd5493 100644 --- a/X121SMCEA/Signals/x-121.smc.xpvsupdem.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xpvsupdem.signal.lib.mq5 @@ -37,6 +37,7 @@ struct X121SMCStrategyXPVSUPDEMSignalConditions // double sl; + double target; ENUM_X_DIRECTION dir; ENUM_X_POSITION_TYPES type; @@ -72,6 +73,7 @@ struct X121SMCStrategyXPVSUPDEMSignalConditions { // sl = 0; + target = 0; // dir = X_DIRECTION_NONE; diff --git a/X121SMCEA/Signals/x-121.smc.xtwpv.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xtwpv.signal.lib.mq5 index aba821bf..c76f66cc 100644 --- a/X121SMCEA/Signals/x-121.smc.xtwpv.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xtwpv.signal.lib.mq5 @@ -37,6 +37,7 @@ struct X121SMCStrategyXTWPVSignalConditions // double sl; + double target; ENUM_X_DIRECTION dir; ENUM_X_POSITION_TYPES type; @@ -47,6 +48,18 @@ struct X121SMCStrategyXTWPVSignalConditions datetime setupTime; datetime triggerTime; + // + int peakRepeat; + double farPeak; + double middlePeak; + double nearPeak; + + // + int valeRepeat; + double farVale; + double middleVale; + double nearVale; + // // Constructor ... X121SMCStrategyXTWPVSignalConditions() @@ -64,6 +77,7 @@ struct X121SMCStrategyXTWPVSignalConditions { // sl = 0; + target = 0; // dir = X_DIRECTION_NONE; @@ -160,6 +174,17 @@ struct X121SMCStrategyXTWPVSignalConditions */ void ExtensionClean() { + // + peakRepeat = 0; + farPeak = 0; + middlePeak = 0; + nearPeak = 0; + + // + valeRepeat = 0; + farVale = 0; + middleVale = 0; + nearVale = 0; } // @@ -368,28 +393,29 @@ bool DetectX121SMCXTWPVSiganlSetup( // Setup Conditions ... // - isBullish = - // - false - // - ; + // Detect Market Trend ... + // ENUM_X_DIRECTION trend; + // bool hasTrend = verificationCycleHelper + // .DetectTrend(trend); + // bool hasBullishTrend = hasTrend && + // IsBullish(trend); + // bool hasBearishTrend = hasTrend && + // IsBearish(trend); + // result = hasBullishTrend || + // hasBearishTrend; + // if (!result) + // { + // return result; + // } // - isBearish = - // - false - // - ; + // Check Exists Valid Peaks or Vales ... // result = isBullish || isBearish; if (!result) { - // - // Clean Conditions for Regenerate ... - - // return result; } @@ -613,17 +639,54 @@ bool DetectX121SMCXTWPVSiganlTrigger( // // Trigger Conditions ... + // + // Check VWap State ... + + // + bool isVWapBullishState = triggerConditions.x121Conditions.isVWapBullishState; + bool isVWapBearishState = triggerConditions.x121Conditions.isVWapBearishState; + + // + isBullish = + IsBullish(setupDir) && + isVWapBullishState; + + // + isBearish = + IsBearish(setupDir) && + isVWapBearishState; + + // + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Waitings For Sar Switched to Direction ... + + // + double sar = triggerConditions.x121Conditions.sarBuffer[1]; + + // + bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish; + bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish; + // isBullish = // - false + isBullish && + isSarSwitchedToBullish // ; // isBearish = // - false + isBearish && + isSarSwitchedToBearish // ; @@ -647,10 +710,32 @@ bool DetectX121SMCXTWPVSiganlTrigger( } // + // Detect Nearest FVG or Supply Zone For Traget ... + + // + // Select Source State ... + XPOIState state = triggerState; + + // + double target = CalculateTarget( + cBar, + state, + setupDir // + ); + + // + result = target > 0; + if (!result) + { + return result; + } + + // + conditions.target = target; conditions.triggerTime = cTime; conditions.sl = isBullish - ? 0 - : 0; + ? sar + : sar; conditions.type = isBullish ? X_POSITION_TYPE_LONG : X_POSITION_TYPE_SHORT; diff --git a/X121SMCEA/Signals/x-121.smc.xvwpb.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xvwpb.signal.lib.mq5 index 1b7a995a..130c7684 100644 --- a/X121SMCEA/Signals/x-121.smc.xvwpb.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xvwpb.signal.lib.mq5 @@ -37,6 +37,7 @@ struct X121SMCStrategyXVWPBSignalConditions // double sl; + double target; ENUM_X_DIRECTION dir; ENUM_X_POSITION_TYPES type; @@ -64,6 +65,7 @@ struct X121SMCStrategyXVWPBSignalConditions { // sl = 0; + target = 0; // dir = X_DIRECTION_NONE; diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index f5aabcb7..049e6ee9 100644 --- a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 @@ -28,11 +28,12 @@ // #include "../Signals/x-121.smc.test.signal.lib.mq5" +#include "../Signals/x-121.smc.xoepv.signal.lib.mq5" #include "../Signals/x-121.smc.xpvdp.signal.lib.mq5" #include "../Signals/x-121.smc.xpvob.signal.lib.mq5" #include "../Signals/x-121.smc.xpvsupdem.signal.lib.mq5" -#include "../Signals/x-121.smc.xvwpb.signal.lib.mq5" #include "../Signals/x-121.smc.xtwpv.signal.lib.mq5" +#include "../Signals/x-121.smc.xvwpb.signal.lib.mq5" // // Definitions ... @@ -160,11 +161,12 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // bool useTestSignal = false; - bool useXPVOBSignal = true; - bool useXPVDPSignal = true; - bool useXVWPBSignal = true; + bool useXPVOBSignal = false; + bool useXPVDPSignal = false; + bool useXVWPBSignal = false; bool useXTWPVSignal = true; - bool useXPVSUPDEMSignal = true; + bool useXOEPVSignal = false; + bool useXPVSUPDEMSignal = false; // bool hasTestSignal = false; @@ -172,6 +174,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy bool hasXPVDPSignal = false; bool hasXVWPBSignal = false; bool hasXTWPVSignal = false; + bool hasXOEPVSignal = false; bool hasXPVSUPDEMSignal = false; // @@ -219,6 +222,15 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy hasSignal = hasXTWPVSignal; } + // + // XOEPV Signal ... + if (useXOEPVSignal && !hasSignal) + { + // + hasXOEPVSignal = DetectXOEPVSignal(conditions); + hasSignal = hasXOEPVSignal; + } + // // XPVSUPDEM Signal ... if (useXPVSUPDEMSignal && !hasSignal) @@ -312,6 +324,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy signal.pushers = pushers; signal.provider = provider; signal.time = TimeCurrent(); + signal.target = conditions.target; // // Configure Signal Protecting ... @@ -725,6 +738,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy conditions.signalDir = setupDir; conditions.provider = providerStr; conditions.sl = mTestConditions.sl; + conditions.target = mTestConditions.target; // mTestConditions.Clean(); @@ -880,6 +894,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy conditions.signalDir = setupDir; conditions.provider = providerStr; conditions.sl = mXPVOBConditions.sl; + conditions.target = mXPVOBConditions.target; // mXPVOBConditions.Clean(); @@ -993,6 +1008,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy conditions.signalDir = setupDir; conditions.provider = providerStr; conditions.sl = mXPVDPConditions.sl; + conditions.target = mXPVDPConditions.target; // mXPVDPConditions.Clean(); @@ -1106,6 +1122,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy conditions.signalDir = setupDir; conditions.provider = providerStr; conditions.sl = mXVWPBConditions.sl; + conditions.target = mXVWPBConditions.target; // mXVWPBConditions.Clean(); @@ -1219,6 +1236,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy conditions.signalDir = setupDir; conditions.provider = providerStr; conditions.sl = mXTWPVConditions.sl; + conditions.target = mXTWPVConditions.target; // mXTWPVConditions.Clean(); @@ -1227,6 +1245,122 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy return result; } + // + // XOEPV Signal ... + X121SMCStrategyXOEPVSignalConditions mXOEPVConditions; + bool DetectXOEPVSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XOEPV; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mXOEPVConditions.setupTime; + bool isSetuped = mXOEPVConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mXOEPVConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCXOEPVSiganlSetup( + symbol, + period, + mXOEPVConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + setupDir = mXOEPVConditions.dir; + setupTime = mXOEPVConditions.setupTime; + } + + // + result = isSetuped; + if (!result) + { + return result; + } + + // + // Detect Trigger Conditions ... + bool canTrigger = mXOEPVConditions.CanTrigger(); + datetime triggerTime = mXOEPVConditions.triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCXOEPVSiganlTrigger( + mXOEPVConditions, + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + return result; + } + + // + triggerTime = mXOEPVConditions.triggerTime; + } + + // + // Check Signal Direction ... + + // + isBullish = IsBullish(setupDir); + isBearish = IsBearish(setupDir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.signalDir = setupDir; + conditions.provider = providerStr; + conditions.sl = mXOEPVConditions.sl; + conditions.target = mXOEPVConditions.target; + + // + mXOEPVConditions.Clean(); + + // + return result; + } + // // XPVSUPDEM Signal ... X121SMCStrategyXPVSUPDEMSignalConditions mXPVSUPDEMConditions; @@ -1384,6 +1518,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy conditions.signalDir = setupDir; conditions.provider = providerStr; conditions.sl = mXPVSUPDEMConditions.sl; + conditions.target = mXPVSUPDEMConditions.target; // mXPVSUPDEMConditions.Clean(); @@ -1452,9 +1587,12 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // // Initialize Cycle Helpers ... + // + bool isInited = false; + // mTriggerCycleHelper = new XC121SMCCycleHelper(); - mTriggerCycleHelper.Init( + isInited = mTriggerCycleHelper.Init( symbol, PERIOD_M1, x121Inputs // @@ -1462,7 +1600,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // mDecisionCycleHelper = new XC121SMCCycleHelper(); - mDecisionCycleHelper.Init( + isInited = mDecisionCycleHelper.Init( symbol, PERIOD_M5, x121Inputs // @@ -1470,7 +1608,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // mAnalyseCycleHelper = new XC121SMCCycleHelper(); - mAnalyseCycleHelper.Init( + isInited = mAnalyseCycleHelper.Init( symbol, PERIOD_M15, x121Inputs // @@ -1478,7 +1616,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // mVerificationCycleHelper = new XC121SMCCycleHelper(); - mVerificationCycleHelper.Init( + isInited = mVerificationCycleHelper.Init( symbol, PERIOD_M30, x121Inputs // @@ -1486,7 +1624,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // mConsolidationCycleHelper = new XC121SMCCycleHelper(); - mConsolidationCycleHelper.Init( + isInited = mConsolidationCycleHelper.Init( symbol, PERIOD_H1, x121Inputs // @@ -1494,7 +1632,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // mVisionCycleHelper = new XC121SMCCycleHelper(); - mVisionCycleHelper.Init( + isInited = mVisionCycleHelper.Init( symbol, PERIOD_H4, x121Inputs // @@ -1720,1114 +1858,6 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy return result; } - // - // Drawing Functions ... - - /** - * Custom Drawing State ... - * - * @param state: XPOIState instance reference, Specified Which state to Draw ... - * @param forceDrawSamePeriod: Boolean ... - */ - void CustomStateDrawing( - XPOIState &state, - bool filterByPrice = false, - bool forceDrawSamePeriod = false, - ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, - // - // Ignores List ... - bool ignoreSwingHighs = false, - bool ignoreSwingLows = false, - bool ignoreSupportZones = false, - bool ignoreResistanceZones = false, - bool ignoreSupplyZones = false, - bool ignoreDemandZones = false, - bool ignoreBullishOrderBlocks = false, - bool ignoreBearishOrderBlocks = false, - bool ignoreBullishFairValueGaps = false, - bool ignoreBearishFairValueGaps = false, - bool ignoreBullishRejectionBars = false, - bool ignoreBearishRejectionBars = false, - bool ignoreBullishMomentumBars = false, - bool ignoreBearishMomentumBars = false // - ) - { - // - XPOIState tmpState = state; - - // - if (forceDrawSamePeriod) - { - // - int count = 0; - ENUM_TIMEFRAMES period = GetPeriod(); - - // - count = state.CountSwingHighs(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSwing iSwing = state.swingHighs[i]; - - // - XOHCL iBar; - bool isFilled = iSwing.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.swingHighs, - i, - 1 // - ); - } - } - } - - // - count = state.CountSwingLows(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSwing iSwing = state.swingLows[i]; - - // - XOHCL iBar; - bool isFilled = iSwing.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.swingLows, - i, - 1 // - ); - } - } - } - - // - count = state.CountBullishMomentumBars(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCMomentumBar iMomentum = state.bullishMomentumBars[i]; - - // - XOHCL iBar; - bool isFilled = iMomentum.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bullishMomentumBars, - i, - 1 // - ); - } - } - } - - // - count = state.CountBearishMomentumBars(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCMomentumBar iMomentum = state.bearishMomentumBars[i]; - - // - XOHCL iBar; - bool isFilled = iMomentum.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bearishMomentumBars, - i, - 1 // - ); - } - } - } - - // - count = state.CountBullishRejectionBars(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCRejectionBar iRejection = state.bullishRejectionBars[i]; - - // - XOHCL iBar; - bool isFilled = iRejection.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bullishRejectionBars, - i, - 1 // - ); - } - } - } - - // - count = state.CountBearishRejectionBars(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCRejectionBar iRejection = state.bearishRejectionBars[i]; - - // - XOHCL iBar; - bool isFilled = iRejection.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bearishRejectionBars, - i, - 1 // - ); - } - } - } - - // - count = state.CountSupportZones(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSupportZone iZone = state.supportZones[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.supportZones, - i, - 1 // - ); - } - } - } - - // - count = state.CountResistanceZones(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCResistanceZone iZone = state.resistanceZones[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.resistanceZones, - i, - 1 // - ); - } - } - } - - // - count = state.CountSupplyZones(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSupplyZone iZone = state.supplyZones[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.supplyZones, - i, - 1 // - ); - } - } - } - - // - count = state.CountDemandZones(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCDemandZone iZone = state.demandZones[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.demandZones, - i, - 1 // - ); - } - } - } - - // - count = state.CountBullishOrderBlocks(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock iZone = state.bullishOrderBlocks[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bullishOrderBlocks, - i, - 1 // - ); - } - } - } - - // - count = state.CountBearishOrderBlocks(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock iZone = state.bearishOrderBlocks[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bearishOrderBlocks, - i, - 1 // - ); - } - } - } - - // - count = state.CountBullishFairValueGaps(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG iZone = state.bullishFairValueGaps[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillStartBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bullishFairValueGaps, - i, - 1 // - ); - } - } - } - - // - count = state.CountBearishFairValueGaps(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG iZone = state.bearishFairValueGaps[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillStartBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bearishFairValueGaps, - i, - 1 // - ); - } - } - } - - // - } - - // - if (filterByPrice) - { - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - XOHCL bar; - bool isInited = bar.Init( - symbol, - period, - 1 // - ); - - // - if (isInited) - { - // - // Support Zones ... - int supportZonesCount = ArraySize(tmpState.supportZones); - if (IsValidSize(supportZonesCount)) - { - // - XCSupportZone *supports[]; - for (int i = 0; i < supportZonesCount; i++) - { - // - XCSupportZone *iZone = tmpState.supportZones[i]; - - // - bool isValid = - // - (bar.low < iZone.Upper() && - bar.high > iZone.Upper()) || - (bar.high > iZone.Lower() && - bar.low < iZone.Lower()) || - (bar.low > iZone.Lower() && - bar.high < iZone.Upper()) - // - ; - if (isValid) - { - Add( - iZone, - supports // - ); - } - } - - // - Clean(tmpState.supportZones); - Copy( - supports, - tmpState.supportZones // - ); - } - - // - // Resistance Zones ... - int resistanceZonesCount = ArraySize(tmpState.resistanceZones); - if (IsValidSize(resistanceZonesCount)) - { - // - XCResistanceZone *resistances[]; - for (int i = 0; i < resistanceZonesCount; i++) - { - // - XCResistanceZone *iZone = tmpState.resistanceZones[i]; - - // - bool isValid = - // - (bar.low < iZone.Upper() && - bar.high > iZone.Upper()) || - (bar.high > iZone.Lower() && - bar.low < iZone.Lower()) || - (bar.low > iZone.Lower() && - bar.high < iZone.Upper()) - // - ; - if (isValid) - { - Add( - iZone, - resistances // - ); - } - } - - // - Clean(tmpState.resistanceZones); - Copy( - resistances, - tmpState.resistanceZones // - ); - } - - // - // Supply Zones ... - int supplyZonesCount = ArraySize(tmpState.supplyZones); - if (IsValidSize(supplyZonesCount)) - { - // - XCSupplyZone *supplies[]; - for (int i = 0; i < supplyZonesCount; i++) - { - // - XCSupplyZone *iZone = tmpState.supplyZones[i]; - - // - bool isValid = - // - (bar.low < iZone.Upper() && - bar.high > iZone.Upper()) || - (bar.high > iZone.Lower() && - bar.low < iZone.Lower()) || - (bar.low > iZone.Lower() && - bar.high < iZone.Upper()) - // - ; - if (isValid) - { - Add( - iZone, - supplies // - ); - } - } - - // - Clean(tmpState.supplyZones); - Copy( - supplies, - tmpState.supplyZones // - ); - } - - // - // Demand Zones ... - int demandZonesCount = ArraySize(tmpState.demandZones); - if (IsValidSize(demandZonesCount)) - { - // - XCDemandZone *demands[]; - for (int i = 0; i < demandZonesCount; i++) - { - // - XCDemandZone *iZone = tmpState.demandZones[i]; - - // - bool isValid = - // - (bar.low < iZone.Upper() && - bar.high > iZone.Upper()) || - (bar.high > iZone.Lower() && - bar.low < iZone.Lower()) || - (bar.low > iZone.Lower() && - bar.high < iZone.Upper()) - // - ; - if (isValid) - { - Add( - iZone, - demands // - ); - } - } - - // - Clean(tmpState.demandZones); - Copy( - demands, - tmpState.demandZones // - ); - } - - // - // Bullish Order Blocks ... - int bullishOrderBlocksCount = ArraySize(tmpState.bullishOrderBlocks); - if (IsValidSize(bullishOrderBlocksCount)) - { - // - XCOrderBlock *obs[]; - for (int i = 0; i < bullishOrderBlocksCount; i++) - { - // - XCOrderBlock *iZone = tmpState.bullishOrderBlocks[i]; - - // - bool isValid = - // - (bar.low < iZone.Upper() && - bar.high > iZone.Upper()) || - (bar.high > iZone.Lower() && - bar.low < iZone.Lower()) || - (bar.low > iZone.Lower() && - bar.high < iZone.Upper()) - // - ; - if (isValid) - { - Add( - iZone, - obs // - ); - } - } - - // - Clean(tmpState.bullishOrderBlocks); - Copy( - obs, - tmpState.bullishOrderBlocks // - ); - } - - // - // Bearish Order Blocks ... - int bearishOrderBlocksCount = ArraySize(tmpState.bearishOrderBlocks); - if (IsValidSize(bearishOrderBlocksCount)) - { - // - XCOrderBlock *obs[]; - for (int i = 0; i < bearishOrderBlocksCount; i++) - { - // - XCOrderBlock *iZone = tmpState.bearishOrderBlocks[i]; - - // - bool isValid = - // - (bar.low < iZone.Upper() && - bar.high > iZone.Upper()) || - (bar.high > iZone.Lower() && - bar.low < iZone.Lower()) || - (bar.low > iZone.Lower() && - bar.high < iZone.Upper()) - // - ; - if (isValid) - { - Add( - iZone, - obs // - ); - } - } - - // - Clean(tmpState.bearishOrderBlocks); - Copy( - obs, - tmpState.bearishOrderBlocks // - ); - } - - // - // Bullish Fair Value Gaps ... - int bullishFairValueGapsCount = ArraySize(tmpState.bullishFairValueGaps); - if (IsValidSize(bullishFairValueGapsCount)) - { - // - XCFVG *obs[]; - for (int i = 0; i < bullishFairValueGapsCount; i++) - { - // - XCFVG *iZone = tmpState.bullishFairValueGaps[i]; - - // - bool isValid = - // - (bar.low < iZone.Upper() && - bar.high > iZone.Upper()) || - (bar.high > iZone.Lower() && - bar.low < iZone.Lower()) || - (bar.low > iZone.Lower() && - bar.high < iZone.Upper()) - // - ; - if (isValid) - { - Add( - iZone, - obs // - ); - } - } - - // - Clean(tmpState.bullishFairValueGaps); - Copy( - obs, - tmpState.bullishFairValueGaps // - ); - } - - // - // Bearish Fair Value Gaps ... - int bearishFairValueGapsCount = ArraySize(tmpState.bearishFairValueGaps); - if (IsValidSize(bearishFairValueGapsCount)) - { - // - XCFVG *obs[]; - for (int i = 0; i < bearishFairValueGapsCount; i++) - { - // - XCFVG *iZone = tmpState.bearishFairValueGaps[i]; - - // - bool isValid = - // - (bar.low < iZone.Upper() && - bar.high > iZone.Upper()) || - (bar.high > iZone.Lower() && - bar.low < iZone.Lower()) || - (bar.low > iZone.Lower() && - bar.high < iZone.Upper()) - // - ; - if (isValid) - { - Add( - iZone, - obs // - ); - } - } - - // - Clean(tmpState.bearishFairValueGaps); - Copy( - obs, - tmpState.bearishFairValueGaps // - ); - } - } - } - - // - bool drawSwingHighs = true; - bool drawSwingLows = true; - bool drawSupportZones = true; - bool drawResistanceZones = true; - bool drawSupplyZones = true; - bool drawDemandZones = true; - bool drawBullishOrderBlocks = true; - bool drawBearishOrderBlocks = true; - bool drawBullishFairValueGaps = true; - bool drawBearishFairValueGaps = true; - bool drawBullishRejectionBars = true; - bool drawBearishRejectionBars = true; - bool drawBullishMomentumBars = true; - bool drawBearishMomentumBars = true; - - // - // Change Drawing Specs Conditions based on - // Provided Direction ... - if (forDir == X_DIRECTION_BULLISH) - { - // - drawSwingLows = true; - drawDemandZones = true; - drawSupportZones = true; - drawBullishOrderBlocks = true; - drawBullishFairValueGaps = true; - drawBullishRejectionBars = true; - drawBullishMomentumBars = true; - - // - drawSwingHighs = false; - drawSupplyZones = false; - drawResistanceZones = false; - drawBearishOrderBlocks = false; - drawBearishFairValueGaps = false; - drawBearishRejectionBars = false; - drawBearishMomentumBars = false; - } - else if (forDir == X_DIRECTION_BEARISH) - { - // - drawSwingLows = false; - drawDemandZones = false; - drawSupportZones = false; - drawBullishOrderBlocks = false; - drawBullishFairValueGaps = false; - drawBullishRejectionBars = false; - drawBullishMomentumBars = false; - - // - drawSwingHighs = true; - drawSupplyZones = true; - drawResistanceZones = true; - drawBearishOrderBlocks = true; - drawBearishFairValueGaps = true; - drawBearishRejectionBars = true; - drawBearishMomentumBars = true; - } - - // - // Apply Ignore List ... - - // - if (ignoreSwingHighs) - { - drawSwingHighs = false; - } - - // - if (ignoreSwingLows) - { - drawSwingLows = false; - } - - // - if (ignoreSupportZones) - { - drawSupportZones = false; - } - - // - if (ignoreResistanceZones) - { - drawResistanceZones = false; - } - - // - if (ignoreSupplyZones) - { - drawSupplyZones = false; - } - - // - if (ignoreDemandZones) - { - drawDemandZones = false; - } - - // - if (ignoreBullishOrderBlocks) - { - drawBullishOrderBlocks = false; - } - - // - if (ignoreBearishOrderBlocks) - { - drawBearishOrderBlocks = false; - } - - // - if (ignoreBullishFairValueGaps) - { - drawBullishFairValueGaps = false; - } - - // - if (ignoreBearishFairValueGaps) - { - drawBearishFairValueGaps = false; - } - - // - if (ignoreBullishRejectionBars) - { - drawBullishRejectionBars = false; - } - - // - if (ignoreBearishRejectionBars) - { - drawBearishRejectionBars = false; - } - - // - if (ignoreBullishMomentumBars) - { - drawBullishMomentumBars = false; - } - - // - if (ignoreBearishMomentumBars) - { - drawBearishMomentumBars = false; - } - - // - DrawState( - tmpState, // State ... - true, // Update To of all Drawings Till now ... - drawSwingHighs, // Draw SwingHighs .. - drawSwingLows, // Draw SwingLows .. - drawSupportZones, // Draw SupportZones .. - drawResistanceZones, // Draw ResistanceZones .. - drawSupplyZones, // Draw SupplyZones .. - drawDemandZones, // Draw DemandZones .. - drawBullishOrderBlocks, // Draw BullishOrderBlocks .. - drawBearishOrderBlocks, // Draw BearishOrderBlocks .. - drawBullishFairValueGaps, // Draw BullishFairValueGaps .. - drawBearishFairValueGaps, // Draw BearishFairValueGaps .. - drawBullishRejectionBars, // Draw BullishRejectionBars .. - drawBearishRejectionBars, // Draw BearishRejectionBars .. - drawBullishMomentumBars, // Draw BullishMomentumBars .. - drawBearishMomentumBars, // Draw BearishMomentumBars .. - true // Draw Ticks Zone ... - ); - } - - /** - * Draw Specific Pivot ... - * - * @param pivot: XPVPivot instance Reference ... - * @param drawState: Boolean ... - * @param filterByPrice: Boolean ... - * @param ignoreSwingHighs: Boolean ... - * @param ignoreSwingLows: Boolean ... - * @param ignoreSupportZones: Boolean ... - * @param ignoreResistanceZones: Boolean ... - * @param ignoreSupplyZones: Boolean ... - * @param ignoreDemandZones: Boolean ... - * @param ignoreBullishOrderBlocks: Boolean ... - * @param ignoreBearishOrderBlocks: Boolean ... - * @param ignoreBullishFairValueGaps: Boolean ... - * @param ignoreBearishFairValueGaps: Boolean ... - * @param ignoreBullishRejectionBars: Boolean ... - * @param ignoreBearishRejectionBars: Boolean ... - * @param ignoreBullishMomentumBars: Boolean ... - * @param ignoreBearishMomentumBars: Boolean ... - */ - void DrawPivot( - XPVPivot &pivot, - bool drawState = true, - bool filterByPrice = false, - bool ignoreSwingHighs = false, - bool ignoreSwingLows = false, - bool ignoreSupportZones = false, - bool ignoreResistanceZones = false, - bool ignoreSupplyZones = false, - bool ignoreDemandZones = false, - bool ignoreBullishOrderBlocks = false, - bool ignoreBearishOrderBlocks = false, - bool ignoreBullishFairValueGaps = false, - bool ignoreBearishFairValueGaps = false, - bool ignoreBullishRejectionBars = false, - bool ignoreBearishRejectionBars = false, - bool ignoreBullishMomentumBars = false, - bool ignoreBearishMomentumBars = false // - ) - { - // - if (!pivot.IsValid()) - { - return; - } - - // - // Draw Pivot it self ... - XCXPVPivotObject *iPivotObj; - iPivotObj = new XCXPVPivotObject(); - bool isCreated = iPivotObj.Create( - mPOIDrawer.ChartIdentification(), - mPOIDrawer.SubWindowIdentification(), - pivot // - ); - if (!isCreated) - { - return; - } - - // - color clrPivotColor = pivot.IsPeak() - ? clrAqua - : clrMagenta; - iPivotObj.PivotColor(clrPivotColor); - iPivotObj.PivotWidth(2); - - // - AddObjectIfNotExists(iPivotObj); - - // - if (!drawState) - { - return; - } - - // - if (!pivot.state.IsValid()) - { - return; - } - - // - CustomStateDrawing( - pivot.state, - filterByPrice, - false, // forceDrawSamePeriod - X_DIRECTION_NONE, // forDir - ignoreSwingHighs, - ignoreSwingLows, - ignoreSupportZones, - ignoreResistanceZones, - ignoreSupplyZones, - ignoreDemandZones, - ignoreBullishOrderBlocks, - ignoreBearishOrderBlocks, - ignoreBullishFairValueGaps, - ignoreBearishFairValueGaps, - ignoreBullishRejectionBars, - ignoreBearishRejectionBars, - ignoreBullishMomentumBars, - ignoreBearishMomentumBars // - ); - } - // };