diff --git a/Classes/x-saherelm.x-expert.class.mq5 b/Classes/x-saherelm.x-expert.class.mq5 index ecf1273c..5e90b3fb 100644 --- a/Classes/x-saherelm.x-expert.class.mq5 +++ b/Classes/x-saherelm.x-expert.class.mq5 @@ -459,6 +459,7 @@ class XCBaseExpert : public XCBaseAlert UpdateGUI(); HandleReportTime(); HandleStrategiesOnTick(); + HandleStrategiesGuard(); } /** @@ -786,6 +787,13 @@ class XCBaseExpert : public XCBaseAlert { } + /** + * Check Strategies for Guards and then Apply Them ... + */ + virtual void HandleStrategiesGuard() + { + } + // // Time Handlers ... diff --git a/X121SMCEA/Signals/x-121.smc.xobgpv.signal.lib.mq5 b/Documents/BKP/1/x-121.smc.xobgpv.signal.lib.mq5 similarity index 100% rename from X121SMCEA/Signals/x-121.smc.xobgpv.signal.lib.mq5 rename to Documents/BKP/1/x-121.smc.xobgpv.signal.lib.mq5 diff --git a/X121SMCEA/Signals/x-121.smc.xobspv.signal.lib.mq5 b/Documents/BKP/1/x-121.smc.xobspv.signal.lib.mq5 similarity index 100% rename from X121SMCEA/Signals/x-121.smc.xobspv.signal.lib.mq5 rename to Documents/BKP/1/x-121.smc.xobspv.signal.lib.mq5 diff --git a/Experts/x-saherelm.x-121.smc.ea.mq5 b/Experts/x-saherelm.x-121.smc.ea.mq5 index 3ddd36f9..212750d7 100644 --- a/Experts/x-saherelm.x-121.smc.ea.mq5 +++ b/Experts/x-saherelm.x-121.smc.ea.mq5 @@ -57,17 +57,17 @@ input int eaMinRequiredVerificationForSpreadPass = 20; // Minimum Spread Ver // // Trade ... input group "Trade"; -input bool eaAllowTrade = true; // Allow Open Trade On Signals -input string eaStartTradeAt = "2:00"; // Enable Trade on Signals on Time -input string eaStopTradeAt = "21:00"; // Enable Trade on Signals on Time -input string eaCloseAllTradesAt = "23:55"; // Enable Close All Trades on Signals on Time +input bool eaAllowTrade = true; // Allow Open Trade On Signals +input string eaStartTradeAt = "2:00"; // Enable Trade on Signals on Time +input string eaStopTradeAt = "21:00"; // Enable Trade on Signals on Time +input string eaCloseAllTradesAt = ""; // Enable Close All Trades on Signals on Time // // Risk Management ... input group "Risk Management"; input double eaR2R = 3; // Signallers Risk to Reward Ratio input double eaVolume = 0.05; // Static Volume -input double eaRiskPercentPerBalance = 1.0; // Risk Percent Per Balance in Each Trade +input double eaRiskPercentPerBalance = 0; // Risk Percent Per Balance in Each Trade input bool eaDynamicRiskManagement = false; // Dynamic Risk Management input bool eaUseDynamicVolume = false; // Use Dynamic Volume input double eaDynamicVolumeStep = 0.01; // Increase Volume Step @@ -80,9 +80,9 @@ input int eaPauseSignallingAfterReachesMaxAllowedSLInSecconds = 7200; // Pause S // Protection ... input group "Protection"; input bool eaAllowHedging = true; // Allow Hedge Positions -input int eaMinOpenTradesFroHedging = 3; // Minimum Open Positions for Hedging +input int eaMinOpenTradesFroHedging = 4; // Minimum Open Positions for Hedging input double eaHedgingMinVolumeStep = 0.01; // Minimum Volume Step for Hedging -input double eaHedgeingMinRequiredProfitPerVolumeStep = 0.3; // Minimum Required Profit Per Volume Step for Hedging +input double eaHedgeingMinRequiredProfitPerVolumeStep = 1.5; // Minimum Required Profit Per Volume Step for Hedging // // Alert ... diff --git a/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 b/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 index 60718f97..180f15fe 100644 --- a/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 @@ -382,6 +382,8 @@ class XCX121SMCBaseStrategy : public XCBaseAlert /** * Handle Tick Processing ... + * + * @param positions: XPosition instance Collection ... */ virtual void HandleTick() { @@ -450,6 +452,58 @@ class XCX121SMCBaseStrategy : public XCBaseAlert ); } + /** + * Check for any Guards ... + * + * @param guards: X121SMCGuard instance Collection ... + * @param positions: XPosition instance Collection ... + * + * @return ( virtual bool ) + */ + virtual bool HandleGuard( + X121SMCGuard &guards[], + XPosition &positions[] // + ) + { + // + bool result = false; + + // + // Check State ... + if (IsDisabled()) + { + return result; + } + + // + // Check Signalling State ... + if (!AllowLong() && !AllowShort()) + { + return result; + } + + // + // Check Bar Tracker State ... + if (!mGuardBarTracker.CanProcessBar()) + { + return result; + } + + // + // Check For Guards ... + result = CheckGuard( + guards, + positions // + ); + + // + // Waits Until Next Candle if Current Tick has Guard ... + mGuardBarTracker.Waits(); + + // + return result; + } + /** * Check For Signal ... * @@ -474,6 +528,25 @@ class XCX121SMCBaseStrategy : public XCBaseAlert return result; } + /** + * Check for any Guard Actions ... + * + * @param guards: X121SMCGuard instance Collection ... + * + * @return ( virtual bool ) + */ + virtual bool CheckGuard( + X121SMCGuard &guards[], + const XPosition &positions[] // Positions ... + ) + { + // + bool result = false; + + // + return result; + } + /** * Detect SL Candidates based on Strategy and Conditions ... * @@ -518,8 +591,9 @@ class XCX121SMCBaseStrategy : public XCBaseAlert MqlTick mLastTick; // Last Issued Tick ... // - XBarTracker mBarTracker; // Strategy Time Tracker ... - XCBarAnalyser mBarAnalyser; // Bar Analyser Instance + XBarTracker mBarTracker; // Strategy Bar Tracker ... + XBarTracker mGuardBarTracker; // Strategy Guard Bar Tracker ... + XCBarAnalyser mBarAnalyser; // Bar Analyser Instance // // Actions ... @@ -867,6 +941,13 @@ class XCX121SMCBaseStrategy : public XCBaseAlert period // ); + // + // Initialize Guard Bar Tracker ... + mGuardBarTracker.Init( + symbol, + period // + ); + // } diff --git a/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 b/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 index 6c3592ad..1c778b3e 100644 --- a/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 @@ -3276,7 +3276,7 @@ class XC121SMCTradeHandler : public XCBaseAlert // // Handle Last Executed Signal ... - HandleSignalExecuted(signal); + HandleSignalExecuted(signal); // // Alert Executed Signal ... @@ -3376,6 +3376,66 @@ class XC121SMCTradeHandler : public XCBaseAlert return result; } + /** + * Force Close Positions ... + * + * @return ( bool ) + */ + bool ForceClose( + XPosition &positions[], + string comment, + string notificationMessage // + ) + { + // + bool result = false; + + // + int count = ArraySize(positions); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + int closedPositionsCount = mTrader.Close( + positions, + comment // + ); + result = IsValidSize(closedPositionsCount); + if (result) + { + // + // Finish Positions and Clear Data ... + for (int i = 0; i < ArraySize(positions); i++) + { + // + XPosition iPosition = positions[i]; + Finish( + iPosition.ticket, + iPosition, + comment // + ); + } + + // + ResetProtections(); + + // + if (IsValid(notificationMessage)) + { + Alert(notificationMessage); + } + } + + // + return result; + + // + return result; + } + // // Timing Actions ... diff --git a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 index 21f919b5..abda98e3 100644 --- a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 +++ b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 @@ -1365,6 +1365,52 @@ class XC121SMCExpert : public XCBaseExpert } } + /** + * Handle Strategies Guards ... + */ + void HandleStrategiesGuard() override + { + // + int count = ArraySize(mStrategies); + if (!IsValidSize(count)) + { + return; + } + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions( + positions, // Result ... + NULL, // Symbol ... + NULL, // Provider ... + NULL, // Period ... + X_POSITION_TYPE_ALL // All Types ... + ); + if (!IsValidSize(positionsCount)) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + // Call Tick Handler Function ... + X121SMCGuard iGuards[]; + bool hasGuards = mStrategies[i].HandleGuard( + iGuards, + positions // + ); + if (hasGuards) + { + HandleGuards(iGuards); + } + } + + // + Clean(positions); + } + // // Event Handlers ... @@ -1819,6 +1865,393 @@ class XC121SMCExpert : public XCBaseExpert return result; } + /** + * Handle Guard Actions ... + * + * @param guards: X121SMCGuard instance Collection ... + */ + void HandleGuards(X121SMCGuard &guards[]) + { + // + int count = ArraySize(guards); + if (!IsValidSize(guards)) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + X121SMCGuard iGuard = guards[i]; + + // + if (!iGuard.IsValid()) + { + continue; + } + + // + // Here we Have to Handle Guard Actions ... + + // + // Close ... + bool canClose = + NotEmpty(iGuard.ticket) && + iGuard.action == X_121_SMC_GUARD_ACTION_CLOSE; + + // + // Close All ... + bool canCloseAll = iGuard.action == X_121_SMC_GUARD_ACTION_CLOSE_ALL; + + // + // Close Longs ... + bool canCloseLongs = iGuard.action == X_121_SMC_GUARD_ACTION_CLOSE_LONGS; + + // + // Close Shorts ... + bool canCloseShorts = iGuard.action == X_121_SMC_GUARD_ACTION_CLOSE_SHORTS; + + // + // Partial Close ... + bool canPartialClose = + NotEmpty(iGuard.ticket) && + iGuard.volumeMultiplier > 0 && + iGuard.action == X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE; + + // + // Trail Stop ... + bool canTrailStop = + iGuard.sl > 0 && + NotEmpty(iGuard.ticket) && + iGuard.action == X_121_SMC_GUARD_ACTION_TRAIL_STOP; + + // + // Trail Target ... + bool canTrailTarget = + iGuard.tp > 0 && + NotEmpty(iGuard.ticket) && + iGuard.action == X_121_SMC_GUARD_ACTION_TRAIL_TARGET; + + // + // Hedge ... + bool canHedge = iGuard.action == X_121_SMC_GUARD_ACTION_HEDGE; + + // + // Check is Guard Valid ... + bool isValidGuardAction = + canHedge || + canClose || + canCloseAll || + canTrailStop || + canCloseLongs || + canTrailTarget || + canCloseShorts || + canPartialClose; + if (!isValidGuardAction) + { + continue; + } + + // + // Now we Sure to Have a Valid Guard ... + // Start to o Guard Actions ... + + // + // Close All ... + if (canCloseAll) + { + // + XPosition positions[]; + int positionsCount = + mTrader + .GetPositions( + positions, // Result ... + iGuard.symbol, + iGuard.provider, + NULL, // Period ... + X_POSITION_TYPE_ALL, // All Types ... + true // Filter by Magic ... + ); + if (IsValidSize(positionsCount)) + { + // + string comment = "Guard Close All ..."; + string message = "Guard Close All (" + ToString(positionsCount) + ") Positions Successfully ..."; + mTradeHandler.ForceClose( + positions, + comment, + message // + ); + } + } + + // + // Close Longs ... + if (canCloseLongs) + { + // + XPosition longPositions[]; + XPosition shortPositions[]; + mTrader + .GetPositions( + longPositions, // Result ... + shortPositions, // Result ... + iGuard.symbol, + iGuard.provider, + NULL, // Period ... + true // Filter by Magic ... + ); + + // + int longPositionsCount = ArraySize(longPositions); + bool hasLongPositions = IsValidSize(longPositionsCount); + + // + int shortPositionsCount = ArraySize(shortPositions); + bool hasShortPositions = IsValidSize(shortPositionsCount); + + // + if (hasLongPositions) + { + // + string comment = "Guard Close Longs ..."; + string message = "Guard Close (" + ToString(longPositionsCount) + ") Long Positions Successfully ..."; + mTradeHandler.ForceClose( + longPositions, + comment, + message // + ); + } + } + + // + // Close Shorts ... + if (canCloseShorts) + { + // + XPosition longPositions[]; + XPosition shortPositions[]; + mTrader + .GetPositions( + longPositions, // Result ... + shortPositions, // Result ... + iGuard.symbol, + iGuard.provider, + NULL, // Period ... + true // Filter by Magic ... + ); + + // + int longPositionsCount = ArraySize(longPositions); + bool hasLongPositions = IsValidSize(longPositionsCount); + + // + int shortPositionsCount = ArraySize(shortPositions); + bool hasShortPositions = IsValidSize(shortPositionsCount); + + // + if (hasShortPositions) + { + // + string comment = "Guard Close Shorts ..."; + string message = "Guard Close (" + ToString(shortPositionsCount) + ") Short Positions Successfully ..."; + mTradeHandler.ForceClose( + shortPositions, + comment, + message // + ); + } + } + + // + // Close ... + if (canClose) + { + // + XPosition iPosition; + bool hasPosition = mTrader.GetPosition( + iGuard.ticket, + iPosition // + ); + + // + bool isLong = IsLong(iPosition.type); + + // + if (hasPosition) + { + // + XPosition positions[]; + AddRef( + iPosition, + positions // + ); + + // + string comment = "Guard Close ..."; + string message = "Guard Close " + (isLong ? "Long" : "Short") + " Position: (" + ToString(iGuard.ticket) + ") Successfully ..."; + mTradeHandler.ForceClose( + positions, + comment, + message // + ); + } + } + + // + // Partial Close ... + if (canPartialClose) + { + // + // TODO: Implement this .. + } + + // + // Hedge ... + if (canHedge) + { + // + XPosition positions[]; + int positionsCount = + mTrader + .GetPositions( + positions, // Result ... + iGuard.symbol, + iGuard.provider, + NULL, // Period ... + X_POSITION_TYPE_ALL, // All Types ... + true // Filter by Magic ... + ); + if (IsValidSize(positionsCount)) + { + // + int longs = 0; + double longProfits = 0; + double longVolumes = 0; + + // + int shorts = 0; + double shortProfits = 0; + double shortVolumes = 0; + CountPositions( + positions, + longs, + longProfits, + longVolumes, + shorts, + shortProfits, + shortVolumes // + ); + + // + int count = longs + shorts; + double profits = longProfits + shortProfits; + double volumes = longVolumes + shortVolumes; + + // + bool canDoHedge = + count > 0 && + profits > 0 && + volumes > 0; + if (canDoHedge) + { + // + string comment = "Guard Hedge ..."; + string message = "Guard Hedge (" + ToString(count) + ") Positions by: (" + ToString(profits) + ") Successfully ..."; + mTradeHandler.ForceClose( + positions, + comment, + message // + ); + } + } + } + + // + // Trail Stop ... + if (canTrailStop) + { + // + XPosition iPosition; + bool hasPosition = mTrader.GetPosition( + iGuard.ticket, + iPosition // + ); + + // + bool isLong = IsLong(iPosition.type); + + // + bool canDoTrail = + hasPosition && + iPosition.profit > 0 && + isLong + ? iPosition.price > iGuard.sl && + (iPosition.sl == 0 || + iPosition.sl < iGuard.sl) + : iPosition.price < iGuard.sl && + (iPosition.sl == 0 || + iPosition.sl > iGuard.sl); + if (canDoTrail) + { + // + string comment = "Guard Trail Stop ..."; + string message = "Guard Trail " + (isLong ? "Long" : "Short") + " Position: (" + ToString(iGuard.ticket) + ") Stop Successfully ..."; + bool isModified = mTrader.Modify( + iPosition.ticket, + iGuard.sl, + iPosition.tp, + comment // + ); + if (isModified) + { + mTradeHandler.Alert(message); + } + } + } + + // + // Trail Target ... + if (canTrailTarget) + { + // + XPosition iPosition; + bool hasPosition = mTrader.GetPosition( + iGuard.ticket, + iPosition // + ); + + // + bool isLong = IsLong(iPosition.type); + + // + bool canDoTrail = + hasPosition && + iGuard.tp != iPosition.tp && + isLong + ? iGuard.tp > iPosition.price + : iGuard.tp < iPosition.price; + if (canDoTrail) + { + // + string comment = "Guard Trail Target ..."; + string message = "Guard Trail " + (isLong ? "Long" : "Short") + " Position: (" + ToString(iGuard.ticket) + ") Target Successfully ..."; + bool isModified = mTrader.Modify( + iPosition.ticket, + iPosition.sl, + iGuard.tp, + comment // + ); + if (isModified) + { + mTradeHandler.Alert(message); + } + } + } + } + } + // }; diff --git a/X121SMCEA/Libraries/x-121.smc.guard.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.guard.lib.mq5 new file mode 100644 index 00000000..2b55cede --- /dev/null +++ b/X121SMCEA/Libraries/x-121.smc.guard.lib.mq5 @@ -0,0 +1,703 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: +// Description: provide all Global Guarding 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" + +// +// +XConsolidationZone x121SMCConsolidationZone; +bool DetectX121SMCGuards( + X121SMCGuard &guards[], + const XPosition &positions[], + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper // +) +{ + // + bool result = false; + + // + int count = ArraySize(positions); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + string symbol = triggerCycleHelper.GetSymbol(); + string provider = ToString(X_121_SMC_PROVIDER_XSTRPV); + ENUM_TIMEFRAMES period = triggerCycleHelper.GetPeriod(); + + // + XPosition ownPositions[]; + XPosition ownLongPositions[]; + XPosition ownShortPositions[]; + for (int i = 0; i < count; i++) + { + // + XPosition iPosition = positions[i]; + bool isOwn = iPosition + .IsFiltersPassed( + symbol, + provider, + NULL, + X_POSITION_TYPE_ALL, + iPosition.magic // + ); + if (isOwn) + { + // + AddRef( + iPosition, + ownPositions // + ); + + // + bool isLong = IsLong(positions[i].type); + if (isLong) + { + // + AddRef( + iPosition, + ownLongPositions // + ); + } + else + { + // + AddRef( + iPosition, + ownShortPositions // + ); + } + } + } + + // + count = ArraySize(ownPositions); + + // + int longsCount = ArraySize(ownLongPositions); + bool hasLongs = IsValidSize(longsCount); + + // + int shortsCount = ArraySize(ownShortPositions); + bool hasShorts = IsValidSize(shortsCount); + + // + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + // Here we Are Sure there is Positions to Guard ... + // based on Current Provider ... + + // + // Detect Required Data for Analyse Market to Guard Positions ... + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + 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 points = GetPoints(symbol); + + // + int swingLoopback = 3; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // 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; + + // + // Cycle X121Conditions ... + X121Conditions triggerXConditions = triggerConditions.x121Conditions; + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.x121Conditions; + X121Conditions verificationXConditions = verificationConditions.x121Conditions; + X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; + X121Conditions visionXConditions = visionConditions.x121Conditions; + + // + // Trigger ... + ENUM_X_DIRECTION triggerMarketDir; + bool hasTriggerMarketDir = triggerCycleHelper + .DetectMarketStructure(triggerMarketDir); + + // + bool hasTriggerBullishTrend = + hasTriggerMarketDir && + IsBullish(triggerMarketDir); + + // + bool hasTriggerBearishTrend = + hasTriggerMarketDir && + IsBearish(triggerMarketDir); + + // + // Decision ... + ENUM_X_DIRECTION decisionMarketDir; + bool hasDecisionMarketDir = decisionCycleHelper + .DetectMarketStructure(decisionMarketDir); + + // + bool hasDecisionBullishTrend = + hasDecisionMarketDir && + IsBullish(decisionMarketDir); + + // + bool hasDecisionBearishTrend = + hasDecisionMarketDir && + IsBearish(decisionMarketDir); + + // + // Consolidation Zone ... + int consolidationLoopback = 7; + double consolidationZoneLower = 0; + double consolidationZoneUpper = 0; + bool isConsolidationZoneBreaked = false; + bool isConsolidationZoneBreakedUp = false; + bool isConsolidationZoneBreakedDown = false; + bool hasConsolidationZone = x121SMCConsolidationZone.IsValid(); + if (!hasConsolidationZone) + { + // + double upper = 0; + double lower = 0; + hasConsolidationZone = + triggerCycleHelper + .mBarAnalyser + .IsConsolidate( + cBar, + upper, + lower, + consolidationLoopback // + ); + + // + if (hasConsolidationZone) + { + // + hasConsolidationZone = x121SMCConsolidationZone.Init( + cBar.symbol, + cBar.period, + upper, + lower, + consolidationLoopback // + ); + } + } + + // + if (hasConsolidationZone) + { + // + x121SMCConsolidationZone.Update(); + + // + consolidationZoneUpper = x121SMCConsolidationZone.upper; + consolidationZoneLower = x121SMCConsolidationZone.lower; + + // + isConsolidationZoneBreaked = x121SMCConsolidationZone.IsBreaked(); + isConsolidationZoneBreakedUp = + isConsolidationZoneBreaked && + IsBullish(x121SMCConsolidationZone.breakDirection); + isConsolidationZoneBreakedDown = + isConsolidationZoneBreaked && + IsBearish(x121SMCConsolidationZone.breakDirection); + + // + consolidationZoneUpper = triggerXConditions.peaksBuffer[1]; + consolidationZoneLower = triggerXConditions.valesBuffer[1]; + + // + if (isConsolidationZoneBreaked) + { + x121SMCConsolidationZone.Clean(); + } + } + + // + // Here We Have all Requirements for Guarding Positions ... + + // + // Close ... + + // + // Close All ... + + // + // Close Longs ... + if (hasLongs) + { + // + bool hasGuard = + // + hasDecisionBearishTrend + // + ; + + // + if (hasGuard) + { + // + X121SMCGuard guard; + + // + guard.time = cTime; + guard.symbol = symbol; + guard.provider = provider; + guard.action = X_121_SMC_GUARD_ACTION_CLOSE_LONGS; + + // + AddGuard( + guard, + guards // + ); + } + } + + // + // Close Shorts ... + if (hasShorts) + { + // + bool hasGuard = + // + hasDecisionBullishTrend + // + ; + + // + if (hasGuard) + { + // + X121SMCGuard guard; + + // + guard.time = cTime; + guard.symbol = symbol; + guard.provider = provider; + guard.action = X_121_SMC_GUARD_ACTION_CLOSE_SHORTS; + + // + AddGuard( + guard, + guards // + ); + } + } + + // + // Partial Close ... + + // + if (hasLongs) + { + // + bool hasGuard = + // + hasTriggerBearishTrend + // + ; + + // + if (hasGuard) + { + // + for (int i = 0; i < longsCount; i++) + { + // + XPosition iPosition = ownLongPositions[i]; + + // + X121SMCGuard iGuard; + + // + iGuard.time = cTime; + iGuard.symbol = symbol; + iGuard.provider = provider; + iGuard.action = X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE; + + // + iGuard.ticket = iPosition.ticket; + iGuard.volumeMultiplier = 0.5; + + // + AddGuard( + iGuard, + guards // + ); + } + } + } + + // + if (hasShorts) + { + // + bool hasGuard = + // + hasTriggerBullishTrend + // + ; + + // + if (hasGuard) + { + // + for (int i = 0; i < shortsCount; i++) + { + // + XPosition iPosition = ownShortPositions[i]; + + // + X121SMCGuard iGuard; + + // + iGuard.time = cTime; + iGuard.symbol = symbol; + iGuard.provider = provider; + iGuard.action = X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE; + + // + iGuard.ticket = iPosition.ticket; + iGuard.volumeMultiplier = 0.5; + + // + AddGuard( + iGuard, + guards // + ); + } + } + } + + // + // Trail Stop ... + + // + if (hasLongs) + { + // + bool hasGuard = + // + (hasConsolidationZone && + isConsolidationZoneBreaked && + isConsolidationZoneBreakedUp) + // + ; + + // + if (hasGuard) + { + // + for (int i = 0; i < longsCount; i++) + { + // + XPosition iPosition = ownLongPositions[i]; + + // + if (iPosition.profit <= 0) + { + continue; + } + + // + if (iPosition.price < consolidationZoneLower) + { + continue; + } + + // + X121SMCGuard iGuard; + + // + iGuard.time = cTime; + iGuard.symbol = symbol; + iGuard.provider = provider; + iGuard.action = X_121_SMC_GUARD_ACTION_TRAIL_STOP; + + // + iGuard.ticket = iPosition.ticket; + + // + iGuard.sl = consolidationZoneLower; + + // + AddGuard( + iGuard, + guards // + ); + } + } + } + + // + if (hasShorts) + { + // + bool hasGuard = + // + (hasConsolidationZone && + isConsolidationZoneBreaked && + isConsolidationZoneBreakedDown) + // + ; + + // + if (hasGuard) + { + // + for (int i = 0; i < shortsCount; i++) + { + // + XPosition iPosition = ownShortPositions[i]; + + // + if (iPosition.profit <= 0) + { + continue; + } + + // + if (iPosition.price > consolidationZoneUpper) + { + continue; + } + + // + X121SMCGuard iGuard; + + // + iGuard.time = cTime; + iGuard.symbol = symbol; + iGuard.provider = provider; + iGuard.action = X_121_SMC_GUARD_ACTION_TRAIL_STOP; + + // + iGuard.ticket = iPosition.ticket; + + // + iGuard.sl = consolidationZoneUpper; + + // + AddGuard( + iGuard, + guards // + ); + } + } + } + + // + // Trail Target ... + + // + if (hasLongs) + { + } + + // + if (hasShorts) + { + } + + // + // Hedge ... + + // + count = ArraySize(guards); + result = IsValidSize(count); + + // + return result; +} diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index 15e9b306..3075997d 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -36,8 +36,7 @@ const string X121SMCStrategyToken = "X121SMC"; // const string X121SMCXTestToken = "X121XTest"; -const string X121SMCXOBGPVToken = "X121XOBGPV"; -const string X121SMCXOBSPVToken = "X121XOBSPV"; +const string X121SMCXPZToken = "X121XPZ"; const string X121SMCXSTRPVToken = "X121XSTRPV"; // @@ -47,11 +46,25 @@ enum ENUM_X_121_SMC_PROVIDERS // X_121_SMC_PROVIDER_NONE, X_121_SMC_PROVIDER_XTEST, - X_121_SMC_PROVIDER_XOBGPV, - X_121_SMC_PROVIDER_XOBSPV, + X_121_SMC_PROVIDER_XPZ, X_121_SMC_PROVIDER_XSTRPV, }; +// +// Guard Actions ... +enum ENUM_X_121_SMC_GUARD_ACTIONS +{ + X_121_SMC_GUARD_ACTION_NONE, // Nothing to Do + X_121_SMC_GUARD_ACTION_CLOSE, // Close Specified Position + X_121_SMC_GUARD_ACTION_CLOSE_ALL, // Close All Positions + X_121_SMC_GUARD_ACTION_CLOSE_LONGS, // Close All Long Positions + X_121_SMC_GUARD_ACTION_CLOSE_SHORTS, // Close All Short Position + X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE, // Partial Close Specified Position + X_121_SMC_GUARD_ACTION_TRAIL_STOP, // Trail Stop of Specified Position + X_121_SMC_GUARD_ACTION_TRAIL_TARGET, // Trail Target of Specified Position + X_121_SMC_GUARD_ACTION_HEDGE, // Hedge Specified Positions +}; + // // Each Market Cycle (Time Frame) Conditions // Model as this Structure ... @@ -506,6 +519,136 @@ struct X121SMCStrategyConditions // }; +// +// Model a Guard Action ... +struct X121SMCGuard +{ + // + // Props ... + ENUM_X_121_SMC_GUARD_ACTIONS action; + datetime time; + + // + string symbol; + string provider; + + // + // Specified Position ... + ulong ticket; + + // + // Partial Close ... + double volumeMultiplier; + + // + // SL Trial ... + double sl; + + // + // TP Trial ... + double tp; + + // + // Constructor ... + X121SMCGuard() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + time = NULL; + action = X_121_SMC_GUARD_ACTION_NONE; + + // + symbol = NULL; + provider = NULL; + + // + ticket = 0; + + // + volumeMultiplier = 0; + + // + sl = 0; + tp = 0; + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(time) && + IsValid(symbol) && + IsValid(provider) && + action != X_121_SMC_GUARD_ACTION_NONE + // + ; + if (!result) + { + return result; + } + + // + // Validate Model Based On Specified Guard Actions ... + + // + return result; + } +}; + +/** + * Add Guard to Collection ... + * + * @param guard: X121SMCGuard instance ... + * @param guards: X121SMCGuard instance Collection ... + * + * @return ( int ) + */ +int AddGuard( + X121SMCGuard &guard, + X121SMCGuard &guards[] // +) +{ + // + int result = 0; + + // + if (!guard.IsValid()) + { + return result; + } + + // + AddRef( + guard, + guards // + ); + + // + result = ArraySize(guards); + + // + return result; +} + /** * Draw X121 SMC Conditions ... * @@ -678,13 +821,8 @@ string ToString(ENUM_X_121_SMC_PROVIDERS value) break; // - case X_121_SMC_PROVIDER_XOBGPV: - result = X121SMCXOBGPVToken; - break; - - // - case X_121_SMC_PROVIDER_XOBSPV: - result = X121SMCXOBSPVToken; + case X_121_SMC_PROVIDER_XPZ: + result = X121SMCXPZToken; break; // @@ -720,13 +858,9 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value) { result = X_121_SMC_PROVIDER_XTEST; } - else if (Contains(X121SMCXOBGPVToken, value)) + else if (Contains(X121SMCXPZToken, value)) { - result = X_121_SMC_PROVIDER_XOBGPV; - } - else if (Contains(X121SMCXOBSPVToken, value)) - { - result = X_121_SMC_PROVIDER_XOBSPV; + result = X_121_SMC_PROVIDER_XPZ; } else if (Contains(X121SMCXSTRPVToken, value)) { diff --git a/X121SMCEA/Signals/x-121.smc.xpz.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xpz.signal.lib.mq5 new file mode 100644 index 00000000..881957ea --- /dev/null +++ b/X121SMCEA/Signals/x-121.smc.xpz.signal.lib.mq5 @@ -0,0 +1,1649 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: XPZ +// 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 "../../Libraries/x-trade.lib" +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +// Definitions ... +struct X121SMCStrategyXPZSignalConditions +{ + // + // 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 pivot; + double point; + + // + XPriceZones priceZone; + bool isPriceZoneValidForPeak; + bool isPriceZoneValidForVale; + + // + // Constructor ... + X121SMCStrategyXPZSignalConditions() + { + 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() + { + // + pivot = 0; + point = 0; + + // + priceZone.Clean(); + isPriceZoneValidForPeak = false; + isPriceZoneValidForVale = false; + } + + // +}; + +// +// Signaller Data Sources ... +X121SMCStrategyXPZSignalConditions mXPZConditions; +X121SMCStrategyXPZSignalConditions mXPZConditionsCollection[]; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXPZSiganlSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXPZSignalConditions &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 points = GetPoints(symbol); + + // + int swingLoopback = 3; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // 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; + + // + // Cycle X121Conditions ... + X121Conditions triggerXConditions = triggerConditions.x121Conditions; + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.x121Conditions; + X121Conditions verificationXConditions = verificationConditions.x121Conditions; + X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; + X121Conditions visionXConditions = visionConditions.x121Conditions; + + // + // Setup Conditions ... + + // + // Detect Trend ... + + // + // Consolidation ... + ENUM_X_DIRECTION consolidationMarketDir; + bool hasConsolidationMarketDir = consolidationCycleHelper + .DetectMarketStructure(consolidationMarketDir); + + // + bool hasConsolidationBullishTrend = + hasConsolidationMarketDir && + IsBullish(consolidationMarketDir); + + // + bool hasConsolidationBearishTrend = + hasConsolidationMarketDir && + IsBearish(consolidationMarketDir); + + // + // Verification ... + ENUM_X_DIRECTION verificationMarketDir; + bool hasVerificationMarketDir = verificationCycleHelper + .DetectMarketStructure(verificationMarketDir); + + // + bool hasVerificationBullishTrend = + hasVerificationMarketDir && + IsBullish(verificationMarketDir); + + // + bool hasVerificationBearishTrend = + hasVerificationMarketDir && + IsBearish(verificationMarketDir); + + // + // Analyse ... + ENUM_X_DIRECTION analyseMarketDir; + bool hasAnalyseMarketDir = analyseCycleHelper + .DetectMarketStructure(analyseMarketDir); + + // + bool hasAnalyseBullishTrend = + hasAnalyseMarketDir && + IsBullish(analyseMarketDir); + + // + bool hasAnalyseBearishTrend = + hasAnalyseMarketDir && + IsBearish(analyseMarketDir); + + // + // Decision ... + ENUM_X_DIRECTION decisionMarketDir; + bool hasDecisionMarketDir = decisionCycleHelper + .DetectMarketStructure(decisionMarketDir); + + // + bool hasDecisionBullishTrend = + hasDecisionMarketDir && + IsBullish(decisionMarketDir); + + // + bool hasDecisionBearishTrend = + hasDecisionMarketDir && + IsBearish(decisionMarketDir); + + // + // Detect Bar State ... + + // + // Engulf ... + ENUM_X_DIRECTION cBarEngulfDir; + bool isCBarEngulfed = decisionCycleHelper + .mBarAnalyser + .IsEngulfBar( + cBar, + cBarEngulfDir, + 0 // Extended ... + ); + bool isCBarBullishEngulfed = + isCBarEngulfed && + IsBullish(cBarEngulfDir); + bool isCBarBearishEngulfed = + isCBarEngulfed && + IsBearish(cBarEngulfDir); + + // + // Momentum ... + ENUM_X_DIRECTION cBarMomentumDir; + bool isCBarMomentum = decisionCycleHelper + .mBarAnalyser + .IsMomentumBar( + cBar, + cBarMomentumDir, + 0 // Extended ... + ); + bool isCBarBullishMomentum = + isCBarMomentum && + IsBullish(cBarMomentumDir); + bool isCBarBearishMomentum = + isCBarMomentum && + IsBearish(cBarMomentumDir); + + // + // Reject ... + ENUM_X_DIRECTION cBarRejectDir; + bool isCBarRejected = decisionCycleHelper + .mBarAnalyser + .IsRejectionBar( + cBar, + cBarRejectDir, + 0 // Extended ... + ); + bool isCBarBullishRejected = + isCBarRejected && + IsBullish(cBarRejectDir); + bool isCBarBearishRejected = + isCBarRejected && + IsBearish(cBarRejectDir); + + // + // HH/LL Break ... + + // + bool isCBarBreaksUpHH = IsBarBreak( + hh, + X_DIRECTION_BULLISH, + cBar // + ); + + // + bool isCBarBreaksDownLL = IsBarBreak( + hh, + X_DIRECTION_BEARISH, + cBar // + ); + + // + // Bar Checking Summary ... + + // + // Bullish ... + bool isCBarBullishFormed = + // + isCBarBreaksUpHH || + isCBarBullishEngulfed || + isCBarBullishMomentum || + isCBarBullishRejected + // + ; + + // + // Bearish ... + bool isCBarBearishFormed = + // + isCBarBreaksDownLL || + isCBarBearishEngulfed || + isCBarBearishMomentum || + isCBarBearishRejected + // + ; + + // + // Detect Price Zone ... + + // + double pzPeak = decisionXConditions.peaksBuffer[1]; + double pzVale = decisionXConditions.valesBuffer[1]; + + // + // Detecting Decision Price ones ... + XPriceZones decisionPriceZone; + bool hasDecisionPriceZone = CalculatePriceInsideZones( + decisionPriceZone, + decisionState, + cBar // + ); + double decisionPriceZoneUpper = 0; + double decisionPriceZoneLower = 0; + bool isDecisionPriceZoneValidForPeak = false; + bool isDecisionPriceZoneValidForVale = false; + if (hasDecisionPriceZone) + { + // + bool hasBoundary = decisionPriceZone.GetBoundary( + X_DIRECTION_ALL, + decisionPriceZoneUpper, + decisionPriceZoneLower // + ); + + // + isDecisionPriceZoneValidForPeak = + hasBoundary && + pzPeak <= decisionPriceZoneUpper && + pzPeak >= decisionPriceZoneLower; + + // + isDecisionPriceZoneValidForVale = + hasBoundary && + pzVale <= decisionPriceZoneUpper && + pzVale >= decisionPriceZoneLower; + } + + // + // Detecting Analyse Price ones ... + XPriceZones analysePriceZone; + bool hasAnalysePriceZone = CalculatePriceInsideZones( + analysePriceZone, + analyseState, + cBar // + ); + double analysePriceZoneUpper = 0; + double analysePriceZoneLower = 0; + bool isAnalysePriceZoneValidForPeak = false; + bool isAnalysePriceZoneValidForVale = false; + if (hasAnalysePriceZone) + { + // + bool hasBoundary = analysePriceZone.GetBoundary( + X_DIRECTION_ALL, + analysePriceZoneUpper, + analysePriceZoneLower // + ); + + // + isAnalysePriceZoneValidForPeak = + hasBoundary && + pzPeak <= analysePriceZoneUpper && + pzPeak >= analysePriceZoneLower; + + // + isAnalysePriceZoneValidForVale = + hasBoundary && + pzVale <= analysePriceZoneUpper && + pzVale >= analysePriceZoneLower; + } + + // + // Detecting Verification Price ones ... + XPriceZones verificationPriceZone; + bool hasVerificationPriceZone = CalculatePriceInsideZones( + verificationPriceZone, + verificationState, + cBar // + ); + double verificationPriceZoneUpper = 0; + double verificationPriceZoneLower = 0; + bool isVerificationPriceZoneValidForPeak = false; + bool isVerificationPriceZoneValidForVale = false; + if (hasVerificationPriceZone) + { + // + bool hasBoundary = verificationPriceZone.GetBoundary( + X_DIRECTION_ALL, + verificationPriceZoneUpper, + verificationPriceZoneLower // + ); + + // + isVerificationPriceZoneValidForPeak = + hasBoundary && + pzPeak <= verificationPriceZoneUpper && + pzPeak >= verificationPriceZoneLower; + + // + isVerificationPriceZoneValidForVale = + hasBoundary && + pzVale <= verificationPriceZoneUpper && + pzVale >= verificationPriceZoneLower; + } + + // + // + // + + // + // Summarize Conditions ... + + // + double decisionPVMiddle = decisionXConditions.valesBuffer[1] + + (decisionXConditions.peaksBuffer[1] - decisionXConditions.valesBuffer[1]) / 2; + bool isInDecisionPremium = + // + ask > decisionPVMiddle && + bid > decisionPVMiddle && + // + ask < decisionXConditions.peaksBuffer[1] && + bid < decisionXConditions.peaksBuffer[1] + // + ; + bool isInDecisionDiscount = + // + ask < decisionPVMiddle && + bid < decisionPVMiddle && + // + ask < decisionXConditions.valesBuffer[1] && + bid < decisionXConditions.valesBuffer[1] + // + ; + + // + bool isPriceZoneBullish = + // + hasVerificationBullishTrend && + hasAnalyseBullishTrend && + hasDecisionBullishTrend && + // + hasAnalysePriceZone && + analysePriceZone.IsBullish() && + isAnalysePriceZoneValidForVale && + // + isCBarBullishFormed && + isInDecisionDiscount && + decisionXConditions.isAtrLowerUnderVale && + decisionXConditions.isAtrLowerSlopeBullish && + // + true + // + ; + + // + bool isPriceZoneBearish = + // + hasVerificationBearishTrend && + hasAnalyseBearishTrend && + hasDecisionBearishTrend && + // + hasAnalysePriceZone && + analysePriceZone.IsBearish() && + isAnalysePriceZoneValidForPeak && + // + isInDecisionPremium && + isCBarBearishFormed && + decisionXConditions.isAtrUpperOverPeak && + decisionXConditions.isAtrUpperSlopeBearish && + // + true + // + ; + + // + bool hasPriceZoneCondition = isPriceZoneBullish || + isPriceZoneBearish; + if (hasPriceZoneCondition) + { + // + ENUM_X_DIRECTION pzDir = + isPriceZoneBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + XCBaseObject *drawnObjects[]; + int drawnObjectsCount = triggerCycleHelper + .mPOIDetector + .mDrawer + .DrawPriceZone( + analysePriceZone, + drawnObjects, + pzDir // + ); + + // + conditions.priceZone = analysePriceZone; + conditions.isPriceZoneValidForPeak = isAnalysePriceZoneValidForPeak; + conditions.isPriceZoneValidForVale = isAnalysePriceZoneValidForVale; + + // + pzPeak = analysePriceZoneUpper; + pzVale = analysePriceZoneLower; + + // + double point = GetEntry( + conditions.symbol, + pzDir // + ); + + // + // Manipulate Conditions Point ... + + // + // point = + // isPriceZoneBullish ? pzPeak + // : pzVale; + conditions.point = point; + + // + // Manipulate Conditions Pivot ... + + // + conditions.pivot = + isPriceZoneBullish + ? pzVale + : pzPeak; + } + + // + // + // + + // + isBullish = + isPriceZoneBullish; + + // + isBearish = + isPriceZoneBearish; + + // + 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 DetectX121SMCXPZSiganlTrigger( + // + X121SMCStrategyXPZSignalConditions &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; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 9; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // 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; + + // + // Cycle X121Conditions ... + X121Conditions triggerXConditions = triggerConditions.x121Conditions; + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.x121Conditions; + X121Conditions verificationXConditions = verificationConditions.x121Conditions; + X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; + X121Conditions visionXConditions = visionConditions.x121Conditions; + + // + // Trigger Conditions ... + + // + // SAR ... + double sar = decisionXConditions.sarBuffer[1]; + + // + // STR ... + double str = decisionXConditions.strBuffer[1]; + + // + // CHE ... + double le1 = decisionXConditions.le1Buffer[1]; + double le2 = decisionXConditions.le2Buffer[1]; + double se1 = decisionXConditions.se1Buffer[1]; + double se2 = decisionXConditions.se2Buffer[1]; + + // + // ATR ... + double atrUpper = decisionXConditions.atrUpperBuffer[1]; + double atrLower = decisionXConditions.atrLowerBuffer[1]; + + // + // PV ... + double peak = decisionXConditions.peaksBuffer[1]; + double vale = decisionXConditions.valesBuffer[1]; + + // + int higherPeakIDX = -1; + double higherPeak = decisionCycleHelper + .mX121Helper + .xpvHelper.GetHigherPeak( + higherPeakIDX, + peak // + ); + + // + int lowerValeIDX = -1; + double lowerVale = decisionCycleHelper + .mX121Helper + .xpvHelper.GetLowerVale( + lowerValeIDX, + vale // + ); + + // + // Slopes ... + + // + bool isRsiSlopeBullish = decisionXConditions.isRsiSlopeBullish; + bool isStrSlopeBullish = decisionXConditions.isStrSlopeBullish; + bool isAtrUpperSlopeBullish = decisionXConditions.isAtrUpperSlopeBullish; + bool isAtrLowerSlopeBullish = decisionXConditions.isAtrLowerSlopeBullish; + bool isVwapFastSlopeBullish = decisionXConditions.isVwapFastSlopeBullish; + bool isVwapMidSlopeBullish = decisionXConditions.isVwapMidSlopeBullish; + bool isVwapSlowSlopeBullish = decisionXConditions.isVwapSlowSlopeBullish; + + // + bool isRsiSlopeBearish = decisionXConditions.isRsiSlopeBearish; + bool isStrSlopeBearish = decisionXConditions.isStrSlopeBearish; + bool isAtrUpperSlopeBearish = decisionXConditions.isAtrUpperSlopeBearish; + bool isAtrLowerSlopeBearish = decisionXConditions.isAtrLowerSlopeBearish; + bool isVwapFastSlopeBearish = decisionXConditions.isVwapFastSlopeBearish; + bool isVwapMidSlopeBearish = decisionXConditions.isVwapMidSlopeBearish; + bool isVwapSlowSlopeBearish = decisionXConditions.isVwapSlowSlopeBearish; + + // + bool isSlopesBullish = + isRsiSlopeBullish && + isStrSlopeBullish && + isAtrUpperSlopeBullish && + isAtrLowerSlopeBullish && + isVwapFastSlopeBullish && + isVwapMidSlopeBullish && + isVwapSlowSlopeBullish; + + // + bool isSlopesBearish = + isRsiSlopeBearish && + isStrSlopeBearish && + isAtrUpperSlopeBearish && + isAtrLowerSlopeBearish && + isVwapFastSlopeBearish && + isVwapMidSlopeBearish && + isVwapSlowSlopeBearish; + + // + double point = conditions.point; + bool isPointBreaked = IsBarBreak( + point, + setupDir, + cBar // + ); + + // + // Summary ... + + // + isBullish = + // + isBullish && + isPointBreaked && + // isSlopesBullish && + cBar.IsBullish() + // + ; + + // + isBearish = + // + isBearish && + isPointBreaked && + // isSlopesBearish && + cBar.IsBearish() + // + ; + + // + 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 Pivot Point ... + + // + // Detect Target ... + double target = CalculateTarget( + cBar, + decisionState, + setupDir // + ); + if (target == 0) + { + // + target = CalculateTarget( + cBar, + analyseState, + setupDir // + ); + + // + if (target == 0) + { + // + target = CalculateTarget( + cBar, + verificationState, + setupDir // + ); + } + } + target = 0; + + // + double entry = GetEntry( + conditions.symbol, + setupDir // + ); + + // + // Filling SL Candidates ... + double momentumBarPointsDif = 30 * points; + + // + // Bullish Momentum Bar Selection ... + XOHCL bullishMomentumBar; + int bullishMomentumBarsCount = decisionState.CountBullishMomentumBars(); + if (IsValidSize(bullishMomentumBarsCount)) + { + // + for (int i = 0; i < bullishMomentumBarsCount; i++) + { + // + XCMomentumBar *iMomentum = decisionState.bullishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isValidDistane = (MathAbs(iBar.low) - entry) >= momentumBarPointsDif; + if (!isValidDistane) + { + continue; + } + + // + bool isIndexPassed = iBar.Index() <= 5; + if (!isIndexPassed) + { + continue; + } + + // + bool canSet = + !bullishMomentumBar.IsValid() || + (bullishMomentumBar.IsValid() && + bullishMomentumBar.low < entry && + bullishMomentumBar.Index() > iBar.Index()); + if (canSet) + { + bullishMomentumBar = iBar; + } + } + } + + // + // Bearish Momentum Bar Selection ... + XOHCL bearishMomentumBar; + int bearishMomentumBarsCount = decisionState.CountBearishMomentumBars(); + if (IsValidSize(bearishMomentumBarsCount)) + { + // + for (int i = 0; i < bearishMomentumBarsCount; i++) + { + // + XCMomentumBar *iMomentum = decisionState.bearishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isValidDistane = (MathAbs(iBar.high) - entry) >= momentumBarPointsDif; + if (!isValidDistane) + { + continue; + } + + // + bool isIndexPassed = iBar.Index() <= 5; + if (!isIndexPassed) + { + continue; + } + + // + bool canSet = + !bearishMomentumBar.IsValid() || + (bearishMomentumBar.IsValid() && + bearishMomentumBar.high > entry && + bearishMomentumBar.Index() > iBar.Index()); + if (canSet) + { + bearishMomentumBar = iBar; + } + } + } + + // + double sls[]; + Add( + sar, + sls // + ); + Add( + str, + sls // + ); + + // + if (isBullish) + { + // + Add( + atrLower, + sls // + ); + + // // + // Add( + // vale, + // sls // + // ); + + // + if (bullishMomentumBar.IsValid()) + { + // + Add( + bullishMomentumBar.low, + sls // + ); + } + + // // + // if (IsValidIndex(lowerValeIDX)) + // { + // // + // Add( + // lowerVale, + // sls // + // ); + // } + + // + if (le1 != EMPTY_VALUE) + { + // + Add( + le1, + sls // + ); + } + + // + if (le2 != EMPTY_VALUE) + { + // + Add( + le2, + sls // + ); + } + } + else + { + // + Add( + atrUpper, + sls // + ); + + // // + // Add( + // peak, + // sls // + // ); + + // + if (bearishMomentumBar.IsValid()) + { + // + Add( + bearishMomentumBar.high, + sls // + ); + } + + // + // if (IsValidIndex(higherPeakIDX)) + // { + // // + // Add( + // higherPeak, + // sls // + // ); + // } + + // + if (se1 != EMPTY_VALUE) + { + // + Add( + se1, + sls // + ); + } + + // + if (se2 != EMPTY_VALUE) + { + // + Add( + se2, + sls // + ); + } + } + + // + double iAtr = decisionConditions.x121Conditions.atrBuffer[1]; + + // + double slsMin = GetMin(sls); + double slsMax = GetMax(sls); + + // + double sl = isBullish + ? slsMin - iAtr + : slsMax + iAtr; + double risk = MathAbs(entry - sl); + double riskInPoints = risk / points; + if (riskInPoints >= 150) + { + // + target = + isBullish + ? entry + (points * 200) + : entry - (points * 200); + + // + target = 0; + } + + // + // Filling Conditions Props ... + conditions.sl = sl; + conditions.target = target; + conditions.triggerTime = cTime; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + return result; +} + +// +bool DetectX121SMCXPZGuards( + X121SMCGuard &guards[], + const XPosition &positions[], + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper // +) +{ + // + bool result = false; + + // + result = DetectX121SMCGuards( + guards, + positions, + triggerCycleHelper, + decisionCycleHelper, + analyseCycleHelper, + verificationCycleHelper, + consolidationCycleHelper, + visionCycleHelper // + ); + + // + return result; +} + +// +int AddX121SMCXPZConditionsIfNotExists( + X121SMCStrategyXPZSignalConditions &item, + X121SMCStrategyXPZSignalConditions &items[], + int maxAllowed = 10 // +) +{ + // + int result = 0; + + // + bool isSetuped = IsValid(item.setupTime) && + HasDirection(item.dir); + if (!isSetuped) + { + return result; + } + + // + int count = ArraySize(items); + if (IsValidSize(count)) + { + // + // Copy Original Items ... + X121SMCStrategyXPZSignalConditions tmpItems[]; + Copy( + items, + tmpItems // + ); + + // + // Prese Item Data ... + bool isBullish = IsBullish(item.dir); + + // + for (int i = 0; i < count; i++) + { + // + X121SMCStrategyXPZSignalConditions iItem = tmpItems[i]; + + // + bool canRemove = item.dir == iItem.dir && + item.pivot == iItem.pivot; + if (canRemove) + { + // + ArrayRemove( + items, + i, + 1 // + ); + } + } + + // + Clean(tmpItems); + } + + // + AddRef( + item, + items // + ); + + // + // Remove Olds ... + CleanupArray( + items, + maxAllowed // + ); + + // + result = ArraySize(items); + + // + return result; +} + +// +int DrawX121SMCXPZConditions( + X121SMCStrategyXPZSignalConditions &conditions, + XCBaseObject *&drawnObjects[], + XCPOIDrawer *drawer // +) +{ + // + int result = 0; + + // + Clean(drawnObjects); + + // + if (drawer == NULL) + { + return result; + } + + // + bool isSetuped = conditions.IsSetuped(); + if (!isSetuped) + { + return result; + } + + // + bool hasPriceZone = conditions.priceZone.IsValid(); + if (!hasPriceZone) + { + return result; + } + + // + int zonesObjCount = drawer.DrawPriceZone( + conditions.priceZone, + drawnObjects, + conditions.dir // + ); + result = zonesObjCount; + + // + return result; +} + +// diff --git a/X121SMCEA/Signals/x-121.smc.xstrpv.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xstrpv.signal.lib.mq5 index a5dc0daf..be569f93 100644 --- a/X121SMCEA/Signals/x-121.smc.xstrpv.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xstrpv.signal.lib.mq5 @@ -21,8 +21,7 @@ // // Imports ... -#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" -#include "../Libraries/x-121.smc.lib.mq5" +#include "../Libraries/x-121.smc.guard.lib.mq5" // // Definitions ... @@ -869,147 +868,15 @@ bool DetectX121SMCXSTRPVSiganlSetup( // // - // - double decisionPVMiddle = decisionXConditions.valesBuffer[1] + - (decisionXConditions.peaksBuffer[1] - decisionXConditions.valesBuffer[1]) / 2; - bool isInDecisionPremium = - // - ask > decisionPVMiddle && - bid > decisionPVMiddle && - // - ask < decisionXConditions.peaksBuffer[1] && - bid < decisionXConditions.peaksBuffer[1] - // - ; - bool isInDecisionDiscount = - // - ask < decisionPVMiddle && - bid < decisionPVMiddle && - // - ask < decisionXConditions.valesBuffer[1] && - bid < decisionXConditions.valesBuffer[1] - // - ; - - // - bool isPriceZoneBullish = - // - !hasDecisionCondition && - !hasAnalyseCondition && - // - hasVerificationBullishTrend && - hasAnalyseBullishTrend && - hasDecisionBullishTrend && - // - hasAnalysePriceZone && - analysePriceZone.IsBullish() && - isAnalysePriceZoneValidForVale && - // - isCBarBullishFormed && - isInDecisionDiscount && - decisionXConditions.isAtrLowerUnderVale && - decisionXConditions.isAtrLowerSlopeBullish && - true - // - ; - - // - bool isPriceZoneBearish = - // - !hasDecisionCondition && - !hasAnalyseCondition && - // - hasVerificationBearishTrend && - hasAnalyseBearishTrend && - hasDecisionBearishTrend && - // - hasAnalysePriceZone && - analysePriceZone.IsBearish() && - isAnalysePriceZoneValidForPeak && - // - isInDecisionPremium && - isCBarBearishFormed && - decisionXConditions.isAtrUpperOverPeak && - decisionXConditions.isAtrUpperSlopeBearish && - true - // - ; - - // - bool hasPriceZoneCondition = isPriceZoneBullish || - isPriceZoneBearish; - if (hasPriceZoneCondition) - { - // - ENUM_X_DIRECTION pzDir = - isPriceZoneBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - - // - // XCBaseObject *drawnObjects[]; - // int drawnObjectsCount = triggerCycleHelper - // .mPOIDetector - // .mDrawer - // .DrawPriceZone( - // analysePriceZone, - // drawnObjects, - // pzDir // - // ); - // if (IsValidSize(drawnObjectsCount)) - // { - // Print("DIR: " + EnumToString(pzDir)); - // } - - // - conditions.priceZone = analysePriceZone; - conditions.isPriceZoneValidForPeak = isAnalysePriceZoneValidForPeak; - conditions.isPriceZoneValidForVale = isAnalysePriceZoneValidForVale; - - // - pzPeak = analysePriceZoneUpper; - pzVale = analysePriceZoneLower; - - // - double point = GetEntry( - conditions.symbol, - conditions.dir // - ); - - // - // Manipulate Conditions Point ... - - // - // point = - // isPriceZoneBullish ? pzPeak - // : pzVale; - conditions.point = point; - - // - // Manipulate Conditions Pivot ... - - // - conditions.pivot = - isPriceZoneBullish - ? pzVale - : pzPeak; - } - - // - // - // - // isBullish = isAnalyseBullish || - isDecisionBullish || - isPriceZoneBullish; + isDecisionBullish; // isBearish = isAnalyseBearish || - isDecisionBearish || - isPriceZoneBearish; + isDecisionBearish; // result = isBullish || @@ -1685,6 +1552,37 @@ bool DetectX121SMCXSTRPVSiganlTrigger( return result; } +// +bool DetectX121SMCXSTRPVGuards( + X121SMCGuard &guards[], + const XPosition &positions[], + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper // +) +{ + // + bool result = false; + + // + result = DetectX121SMCGuards( + guards, + positions, + triggerCycleHelper, + decisionCycleHelper, + analyseCycleHelper, + verificationCycleHelper, + consolidationCycleHelper, + visionCycleHelper // + ); + + // + return result; +} + // int AddX121SMCXSTRPVConditionsIfNotExists( X121SMCStrategyXSTRPVSignalConditions &item, diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index 193e5b77..b9f19669 100644 --- a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 @@ -28,8 +28,7 @@ // #include "../Signals/x-121.smc.test.signal.lib.mq5" -#include "../Signals/x-121.smc.xobgpv.signal.lib.mq5" -#include "../Signals/x-121.smc.xobspv.signal.lib.mq5" +#include "../Signals/x-121.smc.xpz.signal.lib.mq5" #include "../Signals/x-121.smc.xstrpv.signal.lib.mq5" // @@ -43,6 +42,10 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // Public ... public: // + // Props ... + bool useTestSignal; + bool useXPZSignal; + bool useXSTRPVSignal; // // Constructor(s) ... @@ -184,16 +187,9 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // Detect Signal Conditions ... bool hasSignal = false; - // - bool useTestSignal = false; - bool useXOBGPVSignal = false; - bool useXOBSPVSignal = false; - bool useXSTRPVSignal = true; - // bool hasTestSignal = false; - bool hasXOBGPVSignal = false; - bool hasXOBSPVSignal = false; + bool hasXPZSignal = false; bool hasXSTRPVSignal = false; // @@ -207,20 +203,11 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // // XOBGPV Signal ... - if (useXOBGPVSignal && !hasSignal) + if (useXPZSignal && !hasSignal) { // - hasXOBGPVSignal = DetectXOBGPVSignal(conditions); - hasSignal = hasXOBGPVSignal; - } - - // - // XOBSPV Signal ... - if (useXOBSPVSignal && !hasSignal) - { - // - hasXOBSPVSignal = DetectXOBSPVSignal(conditions); - hasSignal = hasXOBSPVSignal; + hasXPZSignal = DetectXPZSignal(conditions); + hasSignal = hasXPZSignal; } // @@ -339,15 +326,15 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy { // // Configure Signal Protector ... - if (useXSTRPVSignal) - { - // - signal.trailSL = false; - signal.fullTPLevel = r2r; - signal.partialCloseOnTPLevel = 2; - signal.partialCloseMultiplier = 0.5; - signal.trailSLStartOnReachTPLevel = 2; - } + // if (useXSTRPVSignal) + // { + // // + // signal.trailSL = false; + // signal.fullTPLevel = r2r; + // signal.partialCloseOnTPLevel = 2; + // signal.partialCloseMultiplier = 0.5; + // signal.trailSLStartOnReachTPLevel = 2; + // } // // TODO: Remove this ... @@ -365,6 +352,76 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy return result; } + /** + * Check for any Guard Actions ... + */ + bool CheckGuard( + X121SMCGuard &guards[], + const XPosition &positions[] // + ) override + { + // + bool result = false; + + // + Clean(guards); + + // + int count = ArraySize(positions); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + // XTEST Guard Detection ... + if (useTestSignal) + { + } + + // + // XSTRPV Guard Detection ... + if (useXSTRPVSignal) + { + // + bool hasGuard = DetectX121SMCXSTRPVGuards( + guards, + positions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + } + + // + // XPZ Guard Detection ... + if (useXPZSignal) + { + // + bool hasGuard = DetectX121SMCXPZGuards( + guards, + positions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + } + + // + count = ArraySize(guards); + result = IsValidSize(count); + + // + return result; + } + /** * Customize Strategy Identifier ... */ @@ -511,483 +568,6 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy return result; } - // - // XOBGPV Signal ... - bool DetectXOBGPVSignal( - X121SMCStrategyConditions &conditions // - ) - { - // - bool result = false; - - // - bool isBullish = false; - bool isBearish = false; - - // - int zIndex = 0; - int cIndex = zIndex + 1; - int pIndex = cIndex + 1; - int ppIndex = pIndex + 1; - - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - 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 cLL = cBar.FindLowest(7, MODE_LOW); - double cHH = cBar.FindHighest(7, MODE_HIGH); - - // - datetime cTime = TimeCurrent(); - - // - ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XOBGPV; - string providerStr = ToString(provider); - - // - // Detect Setup Conditions ... - datetime setupTime = mXOBGPVConditions.setupTime; - bool isSetuped = mXOBGPVConditions.IsSetuped(); - ENUM_X_DIRECTION setupDir = mXOBGPVConditions.dir; - if (!isSetuped) - { - // - // Detect Signal Setup ... - isSetuped = DetectX121SMCXOBGPVSiganlSetup( - symbol, - period, - mXOBGPVConditions, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - - // - setupDir = mXOBGPVConditions.dir; - setupTime = mXOBGPVConditions.setupTime; - - // - if (isSetuped) - { - // - int items = AddX121SMCXOBGPVConditionsIfNotExists( - mXOBGPVConditions, - mXOBGPVConditionsCollection // - ); - - // - mXOBGPVConditions.Clean(); - } - } - - // - int conditionsCount = ArraySize(mXOBGPVConditionsCollection); - result = IsValidSize(conditionsCount); - if (!result) - { - return result; - } - - // - // Looking For Conditions ... - int selectedIndex = 0; - X121SMCStrategyXOBGPVSignalConditions mTmpConditions[]; - Copy( - mXOBGPVConditionsCollection, - mTmpConditions // - ); - X121SMCStrategyXOBGPVSignalConditions mConditions; - for (int i = 0; i < conditionsCount; i++) - { - // - // Update Conditions ... - mTmpConditions[i].UpdateOrderBlocks(); - - // - // Retrieve Required Data ... - ENUM_X_DIRECTION iDir = mTmpConditions[i].dir; - bool isIBullish = IsBullish(iDir); - double iUpper = 0; - double iLower = 0; - bool iHasBoundary = mTmpConditions[i].fvgOB.GetBoundary( - iUpper, - iLower // - ); - if (!iHasBoundary) - { - continue; - } - - // - // Draw Conditions ... - - // - XFVGOrderBlock iFVGOB = mTmpConditions[i].fvgOB; - XCBaseObject *drawnObjects[]; - mPOIDrawer.DrawFVGOrderBlock( - iFVGOB, - drawnObjects // - ); - AddObjectsIfNotExists(drawnObjects); - - // - // Check Broken Order Blocks and Remove them ... - bool isBreaked = - isBullish - ? (cBar.high < iLower || - pBar.high < iLower) - : (cBar.low > iUpper || - cBar.low > iUpper); - if (isBreaked) - { - // - ArrayRemove( - mXOBGPVConditionsCollection, - i, - 1 // - ); - - // - continue; - } - - // - // Check Triggers ... - bool canTrigger = mTmpConditions[i].CanTrigger(); - datetime triggerTime = mTmpConditions[i].triggerTime; - if (!canTrigger) - { - // - // Detect Signal Trigger ... - canTrigger = DetectX121SMCXOBGPVSiganlTrigger( - mTmpConditions[i], - symbol, - period, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - - // - result = canTrigger; - if (!result) - { - continue; - } - - // - triggerTime = mTmpConditions[i].triggerTime; - } - - // - if (canTrigger) - { - // - selectedIndex = i; - mConditions = mTmpConditions[i]; - break; - } - } - - // - result = IsValid(mConditions.setupTime) && - HasDirection(mConditions.dir); - if (!result) - { - return result; - } - - // - // Remove Selected Index from Main Collection ... - ArrayRemove( - mXOBGPVConditionsCollection, - selectedIndex, - 1 // - ); - - // - // Check Signal Direction ... - isBullish = IsBullish(mConditions.dir); - isBearish = IsBearish(mConditions.dir); - result = isBullish || - isBearish; - if (!result) - { - return result; - } - - // - // Issues Signal on Conditions ... - conditions.sl = mConditions.sl; - conditions.provider = providerStr; - conditions.signalDir = mConditions.dir; - conditions.target = mConditions.target; - - // - return result; - } - - // - // XOBSPV Signal ... - bool DetectXOBSPVSignal( - X121SMCStrategyConditions &conditions // - ) - { - // - bool result = false; - - // - bool isBullish = false; - bool isBearish = false; - - // - int zIndex = 0; - int cIndex = zIndex + 1; - int pIndex = cIndex + 1; - int ppIndex = pIndex + 1; - - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - 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 cLL = cBar.FindLowest(7, MODE_LOW); - double cHH = cBar.FindHighest(7, MODE_HIGH); - - // - datetime cTime = TimeCurrent(); - - // - ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XOBSPV; - string providerStr = ToString(provider); - - // - // Detect Setup Conditions ... - datetime setupTime = mXOBSPVConditions.setupTime; - bool isSetuped = mXOBSPVConditions.IsSetuped(); - ENUM_X_DIRECTION setupDir = mXOBSPVConditions.dir; - if (!isSetuped) - { - // - // Detect Signal Setup ... - isSetuped = DetectX121SMCXOBSPVSiganlSetup( - symbol, - period, - mXOBSPVConditions, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - - // - setupDir = mXOBSPVConditions.dir; - setupTime = mXOBSPVConditions.setupTime; - - // - if (isSetuped) - { - // - int items = AddX121SMCXOBSPVConditionsIfNotExists( - mXOBSPVConditions, - mXOBSPVConditionsCollection // - ); - - // - mXOBSPVConditions.Clean(); - } - } - - // - int conditionsCount = ArraySize(mXOBSPVConditionsCollection); - result = IsValidSize(conditionsCount); - if (!result) - { - return result; - } - - // - // Looking For Conditions ... - int selectedIndex = 0; - X121SMCStrategyXOBSPVSignalConditions mTmpConditions[]; - Copy( - mXOBSPVConditionsCollection, - mTmpConditions // - ); - X121SMCStrategyXOBSPVSignalConditions mConditions; - for (int i = 0; i < conditionsCount; i++) - { - // - // Check Triggers ... - bool canTrigger = mTmpConditions[i].CanTrigger(); - datetime triggerTime = mTmpConditions[i].triggerTime; - if (!canTrigger) - { - // - // Detect Signal Trigger ... - canTrigger = DetectX121SMCXOBSPVSiganlTrigger( - mTmpConditions[i], - symbol, - period, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - - // - result = canTrigger; - if (!result) - { - // - bool isISetuped = mTmpConditions[i].IsSetuped(); - if (!isISetuped) - { - // - ArrayRemove( - mXOBSPVConditionsCollection, - i, - 1 // - ); - } - continue; - } - - // - triggerTime = mTmpConditions[i].triggerTime; - } - - // - if (canTrigger) - { - // - selectedIndex = i; - mConditions = mTmpConditions[i]; - break; - } - } - - // - result = IsValid(mConditions.setupTime) && - HasDirection(mConditions.dir); - if (!result) - { - return result; - } - - // - // Remove Selected Index from Main Collection ... - ArrayRemove( - mXOBSPVConditionsCollection, - selectedIndex, - 1 // - ); - - // - // Check Signal Direction ... - isBullish = IsBullish(mConditions.dir); - isBearish = IsBearish(mConditions.dir); - result = isBullish || - isBearish; - if (!result) - { - return result; - } - - // - // Issues Signal on Conditions ... - conditions.sl = mConditions.sl; - conditions.provider = providerStr; - conditions.signalDir = mConditions.dir; - conditions.target = mConditions.target; - - // - return result; - } - // // XSTRPV Signal ... bool DetectXSTRPVSignal( @@ -1214,6 +794,232 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy return result; } + // + // XPZ Signal ... + bool DetectXPZSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + 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 cLL = cBar.FindLowest(7, MODE_LOW); + double cHH = cBar.FindHighest(7, MODE_HIGH); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XPZ; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mXPZConditions.setupTime; + bool isSetuped = mXPZConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mXPZConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCXPZSiganlSetup( + symbol, + period, + mXPZConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + setupDir = mXPZConditions.dir; + setupTime = mXPZConditions.setupTime; + + // + if (isSetuped) + { + // + int items = AddX121SMCXPZConditionsIfNotExists( + mXPZConditions, + mXPZConditionsCollection // + ); + + // + mXPZConditions.Clean(); + } + } + + // + int conditionsCount = ArraySize(mXPZConditionsCollection); + result = IsValidSize(conditionsCount); + if (!result) + { + return result; + } + + // + // Looking For Conditions ... + int selectedIndex = 0; + X121SMCStrategyXPZSignalConditions mTmpConditions[]; + Copy( + mXPZConditionsCollection, + mTmpConditions // + ); + X121SMCStrategyXPZSignalConditions mConditions; + for (int i = 0; i < conditionsCount; i++) + { + // + // Check Triggers ... + bool canTrigger = mTmpConditions[i].CanTrigger(); + datetime triggerTime = mTmpConditions[i].triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCXPZSiganlTrigger( + mTmpConditions[i], + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + // + bool isISetuped = mTmpConditions[i].IsSetuped(); + if (!isISetuped) + { + // + ArrayRemove( + mXPZConditionsCollection, + i, + 1 // + ); + } + continue; + } + + // + triggerTime = mTmpConditions[i].triggerTime; + } + + // + if (canTrigger) + { + // + selectedIndex = i; + mConditions = mTmpConditions[i]; + break; + } + } + + // + result = IsValid(mConditions.setupTime) && + HasDirection(mConditions.dir); + if (!result) + { + return result; + } + + // + // Remove Selected Index from Main Collection ... + ArrayRemove( + mXPZConditionsCollection, + selectedIndex, + 1 // + ); + + // + XCBaseObject *objects[]; + DrawX121SMCXPZConditions( + mConditions, + objects, + mPOIDrawer // + ); + + // + // Check Signal Direction ... + isBullish = IsBullish(mConditions.dir); + isBearish = IsBearish(mConditions.dir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.sl = mConditions.sl; + conditions.provider = providerStr; + conditions.signalDir = mConditions.dir; + conditions.target = mConditions.target; + + // + return result; + } + // // Private ... private: @@ -1228,6 +1034,11 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy */ void InitialHelpers() { + // + useTestSignal = false; + useXPZSignal = true; + useXSTRPVSignal = true; + // string symbol = GetSymbol(); ENUM_TIMEFRAMES period = GetPeriod();