diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index aef40602..e8290c68 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -5295,6 +5295,52 @@ int FilterUSDSymbols( // // Time / Date ... +// +// 0 => Sunday +// 1 => Monday +// 2 => Tuesday +// 3 => Wednesday +// 4 => Thursday +// 5 => Friday +// 6 => Saturday +enum ENUM_X_WEEK_DAYS +{ + X_WEEK_DAY_NONE = -1, + X_WEEK_DAY_SUNDAY = 0, + X_WEEK_DAY_MONDAY = 1, + X_WEEK_DAY_TUESDAY = 2, + X_WEEK_DAY_WEDNESDAY = 3, + X_WEEK_DAY_THURSDAY = 4, + X_WEEK_DAY_FRIDAY = 5, + X_WEEK_DAY_SATURDAY = 6, +}; + +// +// Retrieve Day of Week ... +ENUM_X_WEEK_DAYS GetDayOfWeek( + datetime time = NULL // +) { + // + ENUM_X_WEEK_DAYS result = X_WEEK_DAY_NONE; + + // + time = NormalizeTime(time); + MqlDateTime timeStruct; + bool hasDate = TimeToStruct( + time, + timeStruct // + ); + if (!hasDate) { + return result; + } + + // + result = (ENUM_X_WEEK_DAYS) timeStruct.day_of_week; + + // + return result; +} + // // Representation of Time Struct ... // struct MqlDateTime diff --git a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 index abda98e3..6652c94c 100644 --- a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 +++ b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 @@ -2104,7 +2104,63 @@ class XC121SMCExpert : public XCBaseExpert if (canPartialClose) { // - // TODO: Implement this .. + XPosition iPosition; + bool hasPosition = mTrader.GetPosition( + iGuard.ticket, + iPosition // + ); + + // + bool isLong = IsLong(iPosition.type); + + // + if (hasPosition) + { + // + // Normalize Volume Multiplier ... + double vMult = iGuard.volumeMultiplier; + if (vMult > 0.5) + { + vMult = 0.5; + } + if (vMult < 0) + { + vMult = 0.5; + } + + // + // Calculate and Normalize Volume ... + double volume = iPosition.volume * iGuard.volumeMultiplier; + volume = NormalizeVolume( + volume, + iPosition.symbol // + ); + + // + string comment = "Guard Partially Closed: " + ToString(volume) + " ..."; + string message = "Guard Partially Closed " + (isLong ? "Long" : "Short") + ": " + ToString(volume) + " Successfully ..."; + bool isModified = mTrader.ClosePartial( + iPosition.ticket, + volume, + comment // + ); + if (isModified) + { + // + mTradeHandler.Alert(message); + + // + if (volume == iPosition.volume) + { + // + mTradeHandler.Finish( + iPosition.ticket, + iPosition, + comment // + ); + } + } + } } // diff --git a/X121SMCEA/Libraries/x-121.smc.guard.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.guard.lib.mq5 index 2b55cede..10afd58e 100644 --- a/X121SMCEA/Libraries/x-121.smc.guard.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.guard.lib.mq5 @@ -25,9 +25,12 @@ #include "../Libraries/x-121.smc.lib.mq5" // -// +XPriceZones x121SMCDecisionPriceZone; +XPriceZones x121SMCAnalysePriceZone; +XPriceZones x121SMCVerificationPriceZone; XConsolidationZone x121SMCConsolidationZone; bool DetectX121SMCGuards( + string provider, // Provider ... X121SMCGuard &guards[], const XPosition &positions[], XC121SMCCycleHelper *triggerCycleHelper, @@ -51,7 +54,6 @@ bool DetectX121SMCGuards( // string symbol = triggerCycleHelper.GetSymbol(); - string provider = ToString(X_121_SMC_PROVIDER_XSTRPV); ENUM_TIMEFRAMES period = triggerCycleHelper.GetPeriod(); // @@ -405,15 +407,322 @@ bool DetectX121SMCGuards( } } + // + // Detect Price Zones ... + + // + // Decision ... + double decisionPriceZoneUpper = 0; + double decisionPriceZoneLower = 0; + bool isValidDecisionPriceZoneForPeak = false; + bool isValidDecisionPriceZoneForVale = false; + bool isDecisionPriceZoneLowerRejected = false; + bool isDecisionPriceZoneUpperRejected = false; + bool isDecisionPriceZoneUpperBreakedUp = false; + bool isDecisionPriceZoneLowerBreakedDown = false; + bool hasDecisionPriceZone = x121SMCDecisionPriceZone.IsValid(); + + // + if (!hasDecisionPriceZone) + { + // + hasDecisionPriceZone = CalculatePriceInsideZones( + x121SMCDecisionPriceZone, + decisionState, + cBar // + ); + } + + // + if (hasDecisionPriceZone) + { + // + bool hasBoundary = x121SMCDecisionPriceZone.GetBoundary( + X_DIRECTION_ALL, + decisionPriceZoneUpper, + decisionPriceZoneLower // + ); + + // + if (hasBoundary) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + decisionXConditions.period, + cIndex // + ); + + // + isValidDecisionPriceZoneForPeak = + decisionXConditions.peaksBuffer[1] <= decisionPriceZoneUpper && + decisionXConditions.peaksBuffer[1] >= decisionPriceZoneLower; + + // + isValidDecisionPriceZoneForVale = + decisionXConditions.valesBuffer[1] <= decisionPriceZoneUpper && + decisionXConditions.valesBuffer[1] >= decisionPriceZoneLower; + + // + isDecisionPriceZoneLowerRejected = + isInited && + IsBarReject( + decisionPriceZoneLower, + X_DIRECTION_BULLISH, + iBar // + ); + + // + isDecisionPriceZoneUpperRejected = + isInited && + IsBarReject( + decisionPriceZoneUpper, + X_DIRECTION_BEARISH, + iBar // + ); + + // + isDecisionPriceZoneUpperBreakedUp = + isInited && + IsBarBreak( + decisionPriceZoneUpper, + X_DIRECTION_BULLISH, + iBar // + ); + + // + isDecisionPriceZoneLowerBreakedDown = + isInited && + IsBarBreak( + decisionPriceZoneUpper, + X_DIRECTION_BEARISH, + iBar // + ); + } + } + + // + // Analyse ... + double analysePriceZoneUpper = 0; + double analysePriceZoneLower = 0; + bool isValidAnalysePriceZoneForPeak = false; + bool isValidAnalysePriceZoneForVale = false; + bool isAnalysePriceZoneLowerRejected = false; + bool isAnalysePriceZoneUpperRejected = false; + bool isAnalysePriceZoneUpperBreakedUp = false; + bool isAnalysePriceZoneLowerBreakedDown = false; + bool hasAnalysePriceZone = x121SMCAnalysePriceZone.IsValid(); + + // + if (!hasAnalysePriceZone) + { + // + hasAnalysePriceZone = CalculatePriceInsideZones( + x121SMCAnalysePriceZone, + analyseState, + cBar // + ); + } + + // + if (hasAnalysePriceZone) + { + // + bool hasBoundary = x121SMCAnalysePriceZone.GetBoundary( + X_DIRECTION_ALL, + analysePriceZoneUpper, + analysePriceZoneLower // + ); + + // + if (hasBoundary) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + analyseXConditions.period, + cIndex // + ); + + // + isValidAnalysePriceZoneForPeak = + analyseXConditions.peaksBuffer[1] <= analysePriceZoneUpper && + analyseXConditions.peaksBuffer[1] >= analysePriceZoneLower; + + // + isValidAnalysePriceZoneForVale = + analyseXConditions.valesBuffer[1] <= analysePriceZoneUpper && + analyseXConditions.valesBuffer[1] >= analysePriceZoneLower; + + // + isAnalysePriceZoneLowerRejected = + isInited && + IsBarReject( + analysePriceZoneLower, + X_DIRECTION_BULLISH, + iBar // + ); + + // + isAnalysePriceZoneUpperRejected = + isInited && + IsBarReject( + analysePriceZoneUpper, + X_DIRECTION_BEARISH, + iBar // + ); + + // + isAnalysePriceZoneUpperBreakedUp = + isInited && + IsBarBreak( + analysePriceZoneUpper, + X_DIRECTION_BULLISH, + iBar // + ); + + // + isAnalysePriceZoneLowerBreakedDown = + isInited && + IsBarBreak( + analysePriceZoneUpper, + X_DIRECTION_BEARISH, + iBar // + ); + } + } + + // + // Verification ... + double verificationPriceZoneUpper = 0; + double verificationPriceZoneLower = 0; + bool isValidVerificationPriceZoneForPeak = false; + bool isValidVerificationPriceZoneForVale = false; + bool isVerificationPriceZoneLowerRejected = false; + bool isVerificationPriceZoneUpperRejected = false; + bool isVerificationPriceZoneUpperBreakedUp = false; + bool isVerificationPriceZoneLowerBreakedDown = false; + bool hasVerificationPriceZone = x121SMCVerificationPriceZone.IsValid(); + + // + if (!hasVerificationPriceZone) + { + // + hasVerificationPriceZone = CalculatePriceInsideZones( + x121SMCVerificationPriceZone, + verificationState, + cBar // + ); + } + + // + if (hasVerificationPriceZone) + { + // + bool hasBoundary = x121SMCVerificationPriceZone.GetBoundary( + X_DIRECTION_ALL, + verificationPriceZoneUpper, + verificationPriceZoneLower // + ); + + // + if (hasBoundary) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + verificationXConditions.period, + cIndex // + ); + + // + isValidVerificationPriceZoneForPeak = + verificationXConditions.peaksBuffer[1] <= verificationPriceZoneUpper && + verificationXConditions.peaksBuffer[1] >= verificationPriceZoneLower; + + // + isValidVerificationPriceZoneForVale = + verificationXConditions.valesBuffer[1] <= verificationPriceZoneUpper && + verificationXConditions.valesBuffer[1] >= verificationPriceZoneLower; + + // + isVerificationPriceZoneLowerRejected = + isInited && + IsBarReject( + verificationPriceZoneLower, + X_DIRECTION_BULLISH, + iBar // + ); + + // + isVerificationPriceZoneUpperRejected = + isInited && + IsBarReject( + verificationPriceZoneUpper, + X_DIRECTION_BEARISH, + iBar // + ); + + // + isVerificationPriceZoneUpperBreakedUp = + isInited && + IsBarBreak( + verificationPriceZoneUpper, + X_DIRECTION_BULLISH, + iBar // + ); + + // + isVerificationPriceZoneLowerBreakedDown = + isInited && + IsBarBreak( + verificationPriceZoneUpper, + X_DIRECTION_BEARISH, + iBar // + ); + } + } + // // Here We Have all Requirements for Guarding Positions ... // // Close ... + // TODO: Implement Force Close Position ... // // Close All ... + // + MqlDateTime mDate; + bool hasDate = TimeCurrent(mDate); + if (hasDate) { + // + ENUM_X_WEEK_DAYS dayOfWeek = GetDayOfWeek(); + + // + bool isWeekend = dayOfWeek == X_WEEK_DAY_FRIDAY; + if (isWeekend && mDate.hour == 23 && mDate.min == 30) { + // + X121SMCGuard guard; + + // + guard.time = cTime; + guard.symbol = symbol; + guard.provider = provider; + guard.action = X_121_SMC_GUARD_ACTION_CLOSE_ALL; + + // + AddGuard( + guard, + guards // + ); + } + } + // // Close Longs ... if (hasLongs) @@ -485,7 +794,8 @@ bool DetectX121SMCGuards( // bool hasGuard = // - hasTriggerBearishTrend + hasTriggerBearishTrend || + !hasDecisionBullishTrend // ; @@ -526,7 +836,8 @@ bool DetectX121SMCGuards( // bool hasGuard = // - hasTriggerBullishTrend + hasTriggerBullishTrend || + !hasDecisionBearishTrend // ; @@ -586,17 +897,34 @@ bool DetectX121SMCGuards( XPosition iPosition = ownLongPositions[i]; // + // Position Must Be In Profit ... if (iPosition.profit <= 0) { continue; } // + // Price Must Greater than Zone Lower ... if (iPosition.price < consolidationZoneLower) { continue; } + // + // Position Entry Must Lesser than Zone Lower ... + if (iPosition.entry > consolidationZoneLower) + { + continue; + } + + // + // Position SL must be Zero or Lesser than Zone Lower ... + if (iPosition.sl != 0 && + iPosition.sl > consolidationZoneLower) + { + continue; + } + // X121SMCGuard iGuard; @@ -643,17 +971,34 @@ bool DetectX121SMCGuards( XPosition iPosition = ownShortPositions[i]; // + // Position Must Be In Profit ... if (iPosition.profit <= 0) { continue; } // + // Price Must Lesser than Zone Upper ... if (iPosition.price > consolidationZoneUpper) { continue; } + // + // Position Entry Must Greater than Zone Upper ... + if (iPosition.entry < consolidationZoneUpper) + { + continue; + } + + // + // Position SL must be Zero or Greater than Zone Upper ... + if (iPosition.sl != 0 && + iPosition.sl < consolidationZoneUpper) + { + continue; + } + // X121SMCGuard iGuard; @@ -680,6 +1025,7 @@ bool DetectX121SMCGuards( // // Trail Target ... + // TODO: Implement Target Trail ... // if (hasLongs) @@ -693,6 +1039,7 @@ bool DetectX121SMCGuards( // // Hedge ... + // TODO: Implement Hedge ... // count = ArraySize(guards); diff --git a/X121SMCEA/Signals/x-121.smc.xpz.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xpz.signal.lib.mq5 index 881957ea..1277f73c 100644 --- a/X121SMCEA/Signals/x-121.smc.xpz.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xpz.signal.lib.mq5 @@ -1507,8 +1507,12 @@ bool DetectX121SMCXPZGuards( // bool result = false; + // + string provider = ToString(X_121_SMC_PROVIDER_XPZ); + // result = DetectX121SMCGuards( + provider, guards, positions, triggerCycleHelper, diff --git a/X121SMCEA/Signals/x-121.smc.xstrpv.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xstrpv.signal.lib.mq5 index be569f93..fbf6b715 100644 --- a/X121SMCEA/Signals/x-121.smc.xstrpv.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xstrpv.signal.lib.mq5 @@ -1567,8 +1567,12 @@ bool DetectX121SMCXSTRPVGuards( // bool result = false; + // + string provider = ToString(X_121_SMC_PROVIDER_XSTRPV); + // result = DetectX121SMCGuards( + provider, guards, positions, triggerCycleHelper,