From 6e8768e6ebbd19d03965a656d0bb57feb3d2c9e7 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Tue, 5 Nov 2024 04:34:58 +0330 Subject: [PATCH] Last Works ... --- Classes/x-saherelm.x-chart-objects.class.mq5 | 212 ++++++ Classes/x-saherelm.xexpert.class.mq5 | 75 +- Documents/BKP/121.smc.strategy.tmp.mq5 | 116 ++++ .../x-121.smc.test.strategy.class copy 2.mq5 | Bin 0 -> 172776 bytes .../x-121.smc.test.strategy.class copy.mq5 | Bin 0 -> 156806 bytes Libraries/x-saherelm.common.lib.mq5 | 277 ++++++++ .../Classes/x-121.smc.base.strategy.class.mq5 | 89 ++- .../Classes/x-121.smc.xtradehandler.class.mq5 | 646 ++++++++++++++++-- X121SMCEA/Experts/x-121.smc.expert.class.mq5 | 32 +- .../x-saherelm.x121.smc.trade.handler.mq5 | 1 - X121SMCEA/Libraries/x-121.smc.lib.mq5 | 343 ++++++++-- .../x-121.smc.test.strategy.class.mq5 | Bin 139992 -> 44544 bytes 12 files changed, 1589 insertions(+), 202 deletions(-) create mode 100644 Documents/BKP/x-121.smc.test.strategy.class copy 2.mq5 create mode 100644 Documents/BKP/x-121.smc.test.strategy.class copy.mq5 delete mode 100644 X121SMCEA/Handler/x-saherelm.x121.smc.trade.handler.mq5 diff --git a/Classes/x-saherelm.x-chart-objects.class.mq5 b/Classes/x-saherelm.x-chart-objects.class.mq5 index 398dd25e..dfc64384 100644 --- a/Classes/x-saherelm.x-chart-objects.class.mq5 +++ b/Classes/x-saherelm.x-chart-objects.class.mq5 @@ -41,6 +41,7 @@ enum ENUM_XCHARTOBJECTS X_BAR_ARROW_OBJ = 7862, // X_SIGNAL_OBJ = 8860, + X_TREND_OBJ = 8861, // // Structured ... X_TRADE_DAY_OBJ = 9860, @@ -1941,3 +1942,214 @@ class XCBearishFVGObject : public XCZoneObject }; // + +// +// XTrend ... +class XCTrendObject : public XCBaseObject +{ + // + public: + // + + // + // Constructor ... + void XCTrendObject() + { + } + + // + // Deconstructor ... + void ~XCTrendObject() + { + // + Clean(mSwingLows); + Clean(mSwingHighs); + + // + mTrend.Delete(); + } + + bool CreateByTrend( + long chart_id, + const int window, + XTrend &trend // + ) + { + // + bool result = false; + + // + result = trend.IsValid(); + if (!result) + { + return result; + } + + // + string name = trend.GetTag(); + string nameHash = ToMD5(name); + + // + int swingLowsCount = ArraySize(trend.swingLows); + int swingHighsCount = ArraySize(trend.swingHighs); + + // + double price1 = 0; + double price2 = 0; + datetime from = NULL; + if (trend.isBullish) + { + // + from = trend.swingLows[0].time; + price1 = trend.swingLows[0].GetDown(); + price2 = trend.swingLows[swingLowsCount - 1].GetDown(); + } + else + { + // + from = trend.swingHighs[0].time; + price1 = trend.swingHighs[0].GetUp(); + price2 = trend.swingHighs[swingHighsCount - 1].GetUp(); + } + + // + string trendName = name; + result = mTrend.Create( + chart_id, + trendName, + window, + from, + price1, + trend.at, + price2 // + ); + if (!result) + { + return result; + } + + // + mTrend.Width(1); + color clrTrend = trend.isBullish + ? clrAqua + : trend.isBearish + ? clrMagenta + : clrGray; + mTrend.Color(clrTrend); + mTrend.Style(STYLE_SOLID); + + // + int arrowCode = 108; + if (trend.isBullish) + { + // + for (int i = 0; i < swingLowsCount; i++) + { + // + XOHCL iBar = trend.swingLows[i]; + + // + string iName = "XSPL_" + nameHash; + + // + XCSwingLowObject iObj; + result = iObj.CreateBySwing( + chart_id, + iName, + window, + iBar, + arrowCode // + ); + if (!result) + { + break; + } + + // + iObj.ArrowWidth(5); + iObj.ArrowColor(clrAqua); + iObj.ArrowAnchor(ANCHOR_TOP); + + // + AddRef( + iObj, + mSwingLows // + ); + } + } + else if (trend.isBearish) + { + // + for (int i = 0; i < swingHighsCount; i++) + { + // + XOHCL iBar = trend.swingHighs[i]; + + // + string iName = "XSPH_" + nameHash; + + // + XCSwingHighObject iObj; + result = iObj.CreateBySwing( + chart_id, + iName, + window, + iBar, + arrowCode // + ); + if (!result) + { + break; + } + + // + iObj.ArrowWidth(5); + iObj.ArrowColor(clrMagenta); + iObj.ArrowAnchor(ANCHOR_BOTTOM); + + // + AddRef( + iObj, + mSwingHighs // + ); + } + } + + // + if (result) + { + ObjName(name); + } + else + { + // + mTrend.Delete(); + Clean(mSwingLows); + Clean(mSwingHighs); + } + + // + return result; + } + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + virtual ENUM_XCHARTOBJECTS Type() + { + return X_TREND_OBJ; + } + + // + private: + // + CChartObjectTrend mTrend; + XCSwingLowObject mSwingLows[]; + XCSwingHighObject mSwingHighs[]; + + // +}; + +// diff --git a/Classes/x-saherelm.xexpert.class.mq5 b/Classes/x-saherelm.xexpert.class.mq5 index 3a7bef9e..652e9e62 100644 --- a/Classes/x-saherelm.xexpert.class.mq5 +++ b/Classes/x-saherelm.xexpert.class.mq5 @@ -731,6 +731,25 @@ class XCBaseExpert : public XSCBaseAlert { } + // + // Time Handlers ... + + virtual void HandleOnNewMonth() + { + } + + virtual void HandleOnNewWeek() + { + } + + virtual void HandleOnNewDay() + { + } + + virtual void HandleOnNewHour() + { + } + /** * Generate Identifier Tag ... * @@ -798,50 +817,74 @@ class XCBaseExpert : public XSCBaseAlert { // // Monthly Report .... - if (mReportNewMonths && - mTimeTracker.IsNewMonth()) + if (mTimeTracker.IsNewMonth()) { // - string msg = "New Month ..."; + HandleOnNewMonth(); // - Alert(msg); + if (mReportNewMonths) + { + // + string msg = "New Month ..."; + + // + Alert(msg); + } } // // Weekly Report .... - if (mReportNewWeeks && - mTimeTracker.IsNewWeek()) + if (mTimeTracker.IsNewWeek()) { // - string msg = "New Week ..."; + HandleOnNewWeek(); // - Alert(msg); + if (mReportNewWeeks) + { + // + string msg = "New Week ..."; + + // + Alert(msg); + } } // // Daily Report .... - if (mReportNewDays && - mTimeTracker.IsNewDay()) + if (mTimeTracker.IsNewDay()) { // - string msg = "New Day ..."; + HandleOnNewDay(); // - Alert(msg); + if (mReportNewDays) + { + // + string msg = "New Day ..."; + + // + Alert(msg); + } } // // Hourly Report .... - if (mReportNewHours && - mTimeTracker.IsNewHour()) + if (mTimeTracker.IsNewHour()) { // - string msg = "New Hour ..."; + HandleOnNewHour(); // - Alert(msg); + if (mReportNewHours) + { + // + string msg = "New Hour ..."; + + // + Alert(msg); + } } } diff --git a/Documents/BKP/121.smc.strategy.tmp.mq5 b/Documents/BKP/121.smc.strategy.tmp.mq5 index 26e37223..29b6f68f 100644 --- a/Documents/BKP/121.smc.strategy.tmp.mq5 +++ b/Documents/BKP/121.smc.strategy.tmp.mq5 @@ -1129,3 +1129,119 @@ // result = isConditionReadyForDemand || isConditionReadyForSupply; + +////////////////////////////////////////////////////////////////// + + + // + // Detect Trend ... + // // + // bool d1HasBullishTrend = HasBullishTrend(_1DState); + // bool d1HasBearishTrend = HasBearishTrend(_1DState); + + // // + // bool h4HasBullishTrend = HasBullishTrend(_4HState); + // bool h4HasBearishTrend = HasBearishTrend(_4HState); + + // // + // bool m15HasBullishTrend = HasBullishTrend(_15MState); + // bool m15HasBearishTrend = HasBearishTrend(_15MState); + + // // + // bool m5HasBullishTrend = HasBullishTrend(_5MState); + // bool m5HasBearishTrend = HasBearishTrend(_5MState); + + // // + // bool m1HasBullishTrend = HasBullishTrend(_1MState); + // bool m1HasBearishTrend = HasBearishTrend(_1MState); + + // // + // bool isBullishTrendValid = m15HasBullishTrend && + // m5HasBullishTrend; + // // + // bool isBearishTrendValid = m15HasBearishTrend && + // m5HasBearishTrend; + + // // + // if (isBullishTrendValid) + // { + // Print("isBullishTrendValid"); + // } + + // // + // if (isBearishTrendValid) + // { + // Print("isBearishTrendValid"); + // } + + // // + // XOHCL tmpSWH[]; + // XOHCL tmpSWL[]; + + // // + // XOHCL m15Bar; + // result = m15Bar.Init( + // _symbol, + // PERIOD_M15, + // cIndex // + // ); + // if (!result) + // { + // return result; + // } + // bool m15HasBullishTrend = + // m15Bar.HasBullishTrend( + // tmpSWH, + // tmpSWL, + // true // + // ); + // bool m15HasBearishTrend = + // m15Bar.HasBearishTrend( + // tmpSWH, + // tmpSWL, + // true // + // ); + + // // + // XOHCL m5Bar; + // result = m5Bar.Init( + // _symbol, + // PERIOD_M5, + // cIndex // + // ); + // if (!result) + // { + // return result; + // } + // bool m5HasBullishTrend = + // m5Bar.HasBullishTrend( + // tmpSWH, + // tmpSWL // + // ); + // bool m5HasBearishTrend = + // m5Bar.HasBearishTrend( + // tmpSWH, + // tmpSWL // + // ); + + // // + // bool hasBullishTrend = + // m15HasBullishTrend && + // m5HasBullishTrend; + + // // + // bool hasBearishTrend = + // m15HasBearishTrend && + // m5HasBearishTrend; + + // // + // if (hasBullishTrend) + // { + // Print("hasBullishTrend"); + // } + + // // + // if (hasBearishTrend) + // { + // Print("hasBearishTrend"); + // } diff --git a/Documents/BKP/x-121.smc.test.strategy.class copy 2.mq5 b/Documents/BKP/x-121.smc.test.strategy.class copy 2.mq5 new file mode 100644 index 0000000000000000000000000000000000000000..f5d5afd29d938661b7324e21a3026116adfac2ca GIT binary patch literal 172776 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 literal 0 HcmV?d00001 diff --git a/Documents/BKP/x-121.smc.test.strategy.class copy.mq5 b/Documents/BKP/x-121.smc.test.strategy.class copy.mq5 new file mode 100644 index 0000000000000000000000000000000000000000..8d97ebf9ba61b6d06a65aa46b67e298932c392b6 GIT binary patch literal 156806 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 literal 0 HcmV?d00001 diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index a1673603..e4305224 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -36,6 +36,15 @@ enum ENUM_X_PRICE X_PRICE_LOW }; +// +enum ENUM_X_DIRECTION +{ + X_DIRECTION_ALL, + X_DIRECTION_NONE, + X_DIRECTION_BULLISH, + X_DIRECTION_BEARISH, +}; + // // Swing Types Enum ... enum ENUM_X_SWING_TYPE @@ -5038,6 +5047,219 @@ struct XOHCL } }; +struct XTrend +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + datetime at; + + // + XOHCL swingHighs[]; + XOHCL swingLows[]; + + // + bool isBullish; + bool isBearish; + + // + void XTrend() + { + Clean(); + } + + // + // Tools ... + + /** + * Initialize ... + * + * @param _symbol: String ... + * @param _period: ENUM_TIMEFRAMES member ... + * + * @return ( bool ) + */ + bool Init( + string _symbol, + ENUM_TIMEFRAMES _period = NULL // + ) + { + // + bool result = false; + + // + NormalizePeriod(_period); + + // + result = IsValid(_symbol) && + IsValid(_period); + if (!result) + { + return result; + } + + // + symbol = _symbol; + period = _period; + + // + XOHCL bar; + result = bar.Init( + symbol, + period, + 0 // + ); + if (!result) + { + return result; + } + + // + XOHCL tmpBULLSWH[]; + XOHCL tmpBULLSWL[]; + bool hasBullishTrend = bar.HasBullishTrend( + tmpBULLSWH, + tmpBULLSWL, + true // + ); + + // + XOHCL tmpBEARSWH[]; + XOHCL tmpBEARSWL[]; + bool hasBearishTrend = bar.HasBearishTrend( + tmpBEARSWH, + tmpBEARSWL, + true // + ); + + // + if (hasBullishTrend) + { + // + Copy( + tmpBULLSWH, + swingHighs // + ); + + // + Copy( + tmpBULLSWL, + swingLows // + ); + } + // + else if (hasBearishTrend) + { + // + Copy( + tmpBEARSWH, + swingHighs // + ); + + // + Copy( + tmpBEARSWL, + swingLows // + ); + } + + // + if (hasBullishTrend || + hasBullishTrend) + { + at = TimeCurrent(); + } + + // + result = IsValid(); + + // + return result; + } + + /** + * Clean ... + */ + void Clean() + { + // + symbol = NULL; + period = NULL; + at = NULL; + + // + isBullish = false; + isBearish = false; + + // + Clean(swingLows); + Clean(swingHighs); + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + IsValid(symbol) && + IsValid(period) && + IsValid(at) && + (isBullish || + isBearish) && + (ArraySize(swingHighs) > 0 || + ArraySize(swingLows) > 0); + + // + return result; + } + + /** + * Generate Unique Identifier ... + * + * @return ( string ) + */ + string GetTag() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + string hash = symbol + "," + ToString(period) + "," + ToFormatString(at); + hash = ToMD5(hash); + + // + result = + // + "XTrend_" + + (isBullish ? "Bullish_" : "Bearish_") + + symbol + "_" + + ToString(period) + "_" + + hash + // + ; + + // + return result; + } + + // +}; + // // Tracking Times ... struct XTimeTracker @@ -8660,6 +8882,32 @@ MqlDateTime MilliSecondsToStruct( return result; } +// +// Converts Hours to Seconds ... +int HoursToSeconds(int value) +{ + // + int result = 0; + + // + if (value < 0) + { + value = 0; + } + + // + if (value == 0) + { + return result; + } + + // + result = value * 60 * 60; + + // + return result; +} + // // Retrieve DateTime Structure ... MqlDateTime GetCurrentTime() @@ -12971,4 +13219,33 @@ int GetCycleLengthOn( return result; } +// +// Direction ... + +// +bool IsBullish(ENUM_X_DIRECTION value) +{ + // + bool result = false; + + // + result = value == X_DIRECTION_BULLISH; + + // + return result; +} + +// +bool IsBearish(ENUM_X_DIRECTION value) +{ + // + bool result = false; + + // + result = value == X_DIRECTION_BEARISH; + + // + return result; +} + // \ No newline at end of file diff --git a/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 b/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 index ff9ae218..ae8c2818 100644 --- a/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 @@ -535,6 +535,11 @@ class XCX121SMCBaseStrategy : public XSCBaseAlert return result; } + // + bool useSwings = true; + bool useMomentumBars = true; + bool useRejectionBars = true; + // Clean(candidates); @@ -547,27 +552,39 @@ class XCX121SMCBaseStrategy : public XSCBaseAlert // // Swing Lows ... - Copy( - conditions.swingLows, - candidateBars, - false // - ); + if (useSwings) + { + // + Copy( + conditions.swingLows, + candidateBars, + false // + ); + } // // Bullish Momentum Bars ... - Copy( - conditions.bullishMomentumBars, - candidateBars, - false // - ); + if (useMomentumBars) + { + // + Copy( + conditions.bullishMomentumBars, + candidateBars, + false // + ); + } // // Bullish Rejection Bars ... - Copy( - conditions.bullishRejectionBars, - candidateBars, - false // - ); + if (useRejectionBars) + { + // + Copy( + conditions.bullishRejectionBars, + candidateBars, + false // + ); + } // int count = ArraySize(candidateBars); @@ -598,27 +615,39 @@ class XCX121SMCBaseStrategy : public XSCBaseAlert // // Swing Highs ... - Copy( - conditions.swingHighs, - candidateBars, - false // - ); + if (useSwings) + { + // + Copy( + conditions.swingHighs, + candidateBars, + false // + ); + } // // Bearish Momentum Bars ... - Copy( - conditions.bearishMomentumBars, - candidateBars, - false // - ); + if (useMomentumBars) + { + // + Copy( + conditions.bearishMomentumBars, + candidateBars, + false // + ); + } // // Bearish Rejection Bars ... - Copy( - conditions.bearishRejectionBars, - candidateBars, - false // - ); + if (useRejectionBars) + { + // + Copy( + conditions.bearishRejectionBars, + candidateBars, + false // + ); + } // int count = ArraySize(candidateBars); diff --git a/X121SMCEA/Classes/x-121.smc.xtradehandler.class.mq5 b/X121SMCEA/Classes/x-121.smc.xtradehandler.class.mq5 index c4d2e1c4..0907a488 100644 --- a/X121SMCEA/Classes/x-121.smc.xtradehandler.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.xtradehandler.class.mq5 @@ -437,7 +437,7 @@ struct X121SMCTradeData struct X121SMCProtectedPosition { // - XPosition main; // Main Position ... + XPosition main; // Main Position ... X121SMCTradeData data; // Trade Handler Data ... // @@ -495,6 +495,191 @@ struct X121SMCProtectedPosition } }; +// +struct X121SMCSymbolPositionInfo +{ + // + string symbol; + + // + datetime enableAt; + + // + int longSLs; + int longTPs; + + // + int shortSLs; + int shortTPs; + + // + int countedSLs; + + // + void X121SMCSymbolPositionInfo() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + longSLs = 0; + longTPs = 0; + + // + shortSLs = 0; + shortTPs = 0; + + // + countedSLs = 0; + + // + enableAt = NULL; + } + + /** + * Check is own Symbol Info ... + * + * @param _symbol: String ... + * + * @return ( bool ) + */ + bool IsOwn(string _symbol) + { + // + bool result = false; + + // + result = + // + IsValid(symbol) && + _symbol == symbol + // + ; + + // + return result; + } + + /** + * Check Symbol Trading is Enable or not ... + * + * @param time: DateTime ... + * + * @return ( bool ) + */ + bool IsEnable(datetime time = NULL) + { + // + bool result = false; + + // + time = NormalizeTime(time); + + // + bool isEnableAtValid = IsValid(enableAt); + + // + result = + !isEnableAtValid + ? true + : time > enableAt; + if (result && + isEnableAtValid) + { + Reset(); + } + + // + return result; + } + + /** + * Pause Symbol Trading ... + * + * @param seconds: Integer ... + */ + void Pause(int seconds) + { + // + if (seconds <= 0) + { + return; + } + + // + datetime _enableAt = ((datetime)((int)TimeCurrent() + seconds)); + enableAt = _enableAt; + } + + /** + * Handle Stop Loss ... + * + * @param _type: ENUM_POSITION_TYPE member ... + */ + void HandleSL(ENUM_POSITION_TYPE _type) + { + // + bool isLong = IsLong(_type); + if (isLong) + { + longSLs++; + } + else + { + shortSLs++; + } + + // + countedSLs++; + } + + /** + * Handle Take Profit ... + * + * @param _type: ENUM_POSITION_TYPE member ... + */ + void HandleTP(ENUM_POSITION_TYPE _type) + { + // + bool isLong = IsLong(_type); + if (isLong) + { + longTPs++; + } + else + { + shortTPs++; + } + + // + countedSLs--; + if (countedSLs < 0) + { + countedSLs = 0; + } + } + + /** + * Reset Counter ... + */ + void Reset() + { + // + countedSLs = 0; + enableAt = NULL; + } + + // +}; + // // Implementations ... @@ -1092,6 +1277,44 @@ class XC121SMCTradeHandler : public XSCBaseAlert mDelayBarBetweenTwoSignal = value; } + // + int MaxAllowedSLToPause() + { + return mMaxAllowedSLToPause; + } + + // + void MaxAllowedSLToPause(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxAllowedSLToPause = value; + } + + // + int MaxAllowedSLReachedPauseDelay() + { + return mMaxAllowedSLReachedPauseDelay; + } + +// + void MaxAllowedSLReachedPauseDelay(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxAllowedSLReachedPauseDelay = value; + } + // double AcceptNextSameTypeSignalWhenLastInProfit() { @@ -1779,9 +2002,73 @@ class XC121SMCTradeHandler : public XSCBaseAlert mData[idx].endTime = deal.time; mData[idx].profit = deal.profit; + // + bool isTP = deal.reason == DEAL_REASON_TP; + bool isSL = deal.reason == DEAL_REASON_SL; + // mData[idx].message = - deal.reason == DEAL_REASON_TP ? "TP" : "SL"; + isTP + ? "TP" + : isSL + ? "SL" + : ""; + + // + if (isTP || isSL) + { + // + int symbolIDX = -1; + bool hasInfo = HasSymbol( + mData[idx].symbol, + symbolIDX // + ); + + // + X121SMCSymbolPositionInfo info; + if (!hasInfo) + { + // + // Add New One ... + info.symbol = mData[idx].symbol; + } + else + { + // + // Update Exists ... + info = mSymbolInfos[symbolIDX]; + + // + // Remove Exists ... + ArrayRemove( + mSymbolInfos, + symbolIDX, + 1 // + ); + } + + // + ENUM_POSITION_TYPE xType = IsLong(mData[idx].type) + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + if (isTP) + { + info.HandleTP(xType); + } + else if (isSL) + { + info.HandleSL(xType); + } + + // + AddRef( + info, + mSymbolInfos // + ); + + // + HandlePauseSymbol(mData[idx].symbol); + } // Save(idx); @@ -1815,7 +2102,72 @@ class XC121SMCTradeHandler : public XSCBaseAlert mData[idx].message = comment; // - Save(idx); + bool handleForceClose = true; + if (handleForceClose) + { + // + bool isTP = position.profit > 0; + bool isSL = position.profit < 0; + + // + if (isTP || isSL) + { + // + int symbolIDX = -1; + bool hasInfo = HasSymbol( + mData[idx].symbol, + symbolIDX // + ); + + // + X121SMCSymbolPositionInfo info; + if (!hasInfo) + { + // + // Add New One ... + info.symbol = mData[idx].symbol; + } + else + { + // + // Update Exists ... + info = mSymbolInfos[symbolIDX]; + + // + // Remove Exists ... + ArrayRemove( + mSymbolInfos, + symbolIDX, + 1 // + ); + } + + // + ENUM_POSITION_TYPE xType = IsLong(mData[idx].type) + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + if (isTP) + { + info.HandleTP(xType); + } + else if (isSL) + { + info.HandleSL(xType); + } + + // + AddRef( + info, + mSymbolInfos // + ); + + // + HandlePauseSymbol(mData[idx].symbol); + } + + // + Save(idx); + } } // @@ -1992,7 +2344,24 @@ class XC121SMCTradeHandler : public XSCBaseAlert { return result; } - + + // + int symbolIDX = -1; + bool hasSymbolInfo = HasSymbol( + signal.symbol, + symbolIDX // + ); + + // + // Check rading Not Paused ... + result = + !hasSymbolInfo || + mSymbolInfos[symbolIDX].IsEnable(); + if (!result) + { + return result; + } + // bool isLong = IsLong(signal.type); @@ -2105,39 +2474,39 @@ class XC121SMCTradeHandler : public XSCBaseAlert return result; } + // + XPosition longs[]; + XPosition shorts[]; + + // + // Counting Positions ... + if (mUseMaxAllowedTradesPerSymbol) + { + // + mTrader.GetPositions( + longs, + shorts, + signal.symbol // + ); + } + else + { + // + mTrader.GetPositions( + longs, + shorts, + NULL // All Symbols ... + ); + } + + // + int longsCount = ArraySize(longs); + int shortsCount = ArraySize(shorts); + // // Check Trades Count ... if (mMaxAllowedLongs > 0 || mMaxAllowedShorts > 0) { - // - XPosition longs[]; - XPosition shorts[]; - - // - // Counting Positions ... - if (mUseMaxAllowedTradesPerSymbol) - { - // - mTrader.GetPositions( - longs, - shorts, - signal.symbol // - ); - } - else - { - // - mTrader.GetPositions( - longs, - shorts, - NULL // All Symbols ... - ); - } - - // - int longsCount = ArraySize(longs); - int shortsCount = ArraySize(shorts); - // result = // @@ -2159,48 +2528,48 @@ class XC121SMCTradeHandler : public XSCBaseAlert state = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED; return result; } + } + + // + // Check Position Delays ... + if (result && mDelayBarBetweenTwoSignal > 0) + { + // + int youngestAge = 0; + XPosition youngestPosition; // - // Check Position Delays ... - if (result && mDelayBarBetweenTwoSignal > 0) + // Long Positions when there are Longs ... + if (isLong && longsCount > 0) { // - int youngestAge = 0; - XPosition youngestPosition; + youngestAge = GetYoungest( + youngestPosition, + longs // + ); + } + // + // Short Positions when there are Shorts ... + else if (!isLong && shortsCount > 0) + { + // + youngestAge = GetYoungest( + youngestPosition, + shorts // + ); + } + // + // Only Check when there is must to check and conditions happens ... + if (youngestAge > 0 && youngestPosition.IsValid()) + { // - // Long Positions when there are Longs ... - if (isLong && longsCount > 0) + result = youngestAge >= mDelayBarBetweenTwoSignal; + if (!result) { // - youngestAge = GetYoungest( - youngestPosition, - longs // - ); - } - // - // Short Positions when there are Shorts ... - else if (!isLong && shortsCount > 0) - { - // - youngestAge = GetYoungest( - youngestPosition, - shorts // - ); - } - - // - // Only Check when there is must to check and conditions happens ... - if (youngestAge > 0 && youngestPosition.IsValid()) - { - // - result = youngestAge >= mDelayBarBetweenTwoSignal; - if (!result) - { - // - state = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED; - return result; - } + state = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED; + return result; } } } @@ -2346,11 +2715,35 @@ class XC121SMCTradeHandler : public XSCBaseAlert } } + /** + * Reset All Paused Symbols ... + */ + void ResumePausedSymbols() + { + // + int count = ArraySize(mSymbolInfos); + if (!IsValidSize(count)) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + mSymbolInfos[i].Reset(); + } + + // + string message = "Force Resume Paused Symbols ..."; + Alert(message); + } + // // Protected ... protected: // - XSCTrade *mTrader; // Instance of Trader Class + XSCTrade *mTrader; // Instance of Trader Class X121SMCTradeCollector *mCollector; // Instance of Trade Collector Class // @@ -2583,8 +2976,8 @@ class XC121SMCTradeHandler : public XSCBaseAlert * Handle Protecting Position ... */ bool HandlePositionProtecting( - XPosition &position, // Main Position - XPosition &supports[], // Supports + XPosition &position, // Main Position + XPosition &supports[], // Supports X121SMCProtectedPosition &positions[] // All Positions ) { @@ -3286,6 +3679,57 @@ class XC121SMCTradeHandler : public XSCBaseAlert // Trailling ... } + /** + * Pause Specified Symbol Trading ... + * + * @param symbol: String ... + */ + void HandlePauseSymbol(string symbol) + { + // + if (!IsValid(symbol)) + { + return; + } + + // + int idx = -1; + bool hasItem = HasSymbol( + symbol, + idx // + ); + if (!hasItem) + { + return; + } + + // + int maxAllowedSLToPause = MaxAllowedSLToPause(); + int pauseDelay = MaxAllowedSLReachedPauseDelay(); + if (maxAllowedSLToPause <= 0 || pauseDelay <= 0) + { + return; + } + + // + bool canPauseSymbol = + mSymbolInfos[idx].IsEnable() && + mSymbolInfos[idx].countedSLs >= maxAllowedSLToPause; + if (!canPauseSymbol) + { + return; + } + + // + mSymbolInfos[idx].Pause(pauseDelay); + + // + string message = "Pause (" + symbol + ") until: (" + ToString(mSymbolInfos[idx].enableAt) + ") ..."; + Alert(message); + + // + } + // // Private ... private: @@ -3317,8 +3761,10 @@ class XC121SMCTradeHandler : public XSCBaseAlert // Protector ... // - bool mUseForceMomentumsInProtection; // Use Force Momentums In Protection; int mDelayBarBetweenTwoSignal; // Delay Bars Between Two Signal + int mMaxAllowedSLToPause; // Max Allowed SL Per Symbol + int mMaxAllowedSLReachedPauseDelay; // Pause Symbol Trading After Mx Allowed SL Reached + bool mUseForceMomentumsInProtection; // Use Force Momentums In Protection double mAcceptNextSameTypeSignalWhenLastInProfit; // Accept Next Same Type Signal When Last in Profit in Point // @@ -3364,6 +3810,64 @@ class XC121SMCTradeHandler : public XSCBaseAlert double mHedgeHEMinProfitPerVolumeStep; // Minimum Required Profit For HE Hedge Per Volume Step double mHedgeBEMinProfitPerVolumeStep; // Minimum Required Profit For BE Hedge Per Volume Step + // + X121SMCSymbolPositionInfo mSymbolInfos[]; + + /** + * Find Specific Symbo Indo Item index ... + * + * @param symbol: String ... + * @param index: Integer ... + * + * @return ( bool ) + */ + bool HasSymbol( + string symbol, + int &index // + ) + { + // + bool result = false; + + // + index = -1; + + // + result = IsValid(symbol); + if (!result) + { + return result; + } + + // + int count = ArraySize(mSymbolInfos); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + bool isOwn = mSymbolInfos[i] + .IsOwn(symbol); + if (isOwn) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + // // Common Functions ... diff --git a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 index f60004a2..af6e9d61 100644 --- a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 +++ b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 @@ -237,18 +237,8 @@ class XC121SMCExpert : public XCBaseExpert signal.conditions = conditionsSummary; // - // TODO: Check Signal Delay ... - // datetime currentTime = TimeCurrent(); - // int delay = mDelayBarBetweenTwoSignal; - // bool isDelayPassed = delay <= 0 - // ? true - // : !IsValid(lastSignalOn) - // ? true - // : MathAbs(TimeToSeconds(currentTime)) - MathAbs(TimeToSeconds(lastSignalOn)) >= ulong(delay * PeriodSeconds(_Period)); - // if (!isDelayPassed) - // { - // return; - // } + datetime currentTime = TimeCurrent(); + // // Execute Signal Using Trade Handler ... ENUM_X_SIGNAL_EXECUTION_RESULT state; @@ -260,7 +250,7 @@ class XC121SMCExpert : public XCBaseExpert // if (isExecuted) { - // lastSignalOn = currentTime; + mLastSignalOn = currentTime; } } @@ -469,6 +459,11 @@ class XC121SMCExpert : public XCBaseExpert // // TODO: Make This Configurable Later ... + // + mTradeHandler.DelayBarBetweenTwoSignal(3); + mTradeHandler.MaxAllowedSLToPause(0); + mTradeHandler.MaxAllowedSLReachedPauseDelay(HoursToSeconds(24)); + // // Configure Trade Management ... mTradeHandler.AllowLong(AllowLong()); @@ -720,7 +715,13 @@ class XC121SMCExpert : public XCBaseExpert HandleReportBalance(); } - // + /** + * Reset All Paused Symbols on Each New Days ... + */ + void HandleOnNewDay() override + { + mTradeHandler.ResumePausedSymbols(); + } /** * Generate Identifier Tag ... @@ -758,6 +759,9 @@ class XC121SMCExpert : public XCBaseExpert // // Props ... + // + datetime mLastSignalOn; + // XC121SMCTradeHandler *mTradeHandler; // Trade Handler ... XCX121SMCBaseStrategy *mStrategies[]; // Registere Strategies in EA ... diff --git a/X121SMCEA/Handler/x-saherelm.x121.smc.trade.handler.mq5 b/X121SMCEA/Handler/x-saherelm.x121.smc.trade.handler.mq5 deleted file mode 100644 index 8d763b8d..00000000 --- a/X121SMCEA/Handler/x-saherelm.x121.smc.trade.handler.mq5 +++ /dev/null @@ -1 +0,0 @@ -// Complete this ... \ No newline at end of file diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index edfe1351..4c49b373 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -54,30 +54,36 @@ struct X121SMCStrategyConditions // Conditions ... // + XOHCL swingHigh; XZone supplyZone; - XZone bearishOrderBlock; XZone bearishFVG; + XOHCL resistance; + XZone bearishOrderBlock; + XOHCL bullishMomentumBar; + XOHCL bullishRejectionBar; // - XZone bearishOrderBlocks[]; + XZone demandZones[]; XZone bearishFVGs[]; - - // + XZone bearishOrderBlocks[]; XOHCL swingHighs[]; XOHCL resistances[]; XOHCL bearishMomentumBars[]; XOHCL bearishRejectionBars[]; // + XOHCL support; + XOHCL swingLow; XZone demandZone; - XZone bullishOrderBlock; XZone bullishFVG; + XZone bullishOrderBlock; + XOHCL bearishMomentumBar; + XOHCL bearishRejectionBar; // - XZone bullishOrderBlocks[]; + XZone supplyZones[]; XZone bullishFVGs[]; - - // + XZone bullishOrderBlocks[]; XOHCL supports[]; XOHCL swingLows[]; XOHCL bullishMomentumBars[]; @@ -93,8 +99,9 @@ struct X121SMCStrategyConditions // // Tools ... - // - // Cleanup ... + /** + * Cleanup ... + */ void Clean() { // @@ -103,99 +110,63 @@ struct X121SMCStrategyConditions time = NULL; // - supplyZone.Clean(); - bearishFVG.Clean(); - bearishOrderBlock.Clean(); - - // - Clean(bearishFVGs); - Clean(bearishOrderBlocks); - - // - demandZone.Clean(); - bullishFVG.Clean(); - bullishOrderBlock.Clean(); - - // - Clean(bullishFVGs); - Clean(bullishOrderBlocks); - - // - Clean(swingHighs); - Clean(resistances); - Clean(bearishMomentumBars); - Clean(bearishRejectionBars); - - // - Clean(swingLows); - Clean(supports); - Clean(bullishMomentumBars); - Clean(bullishRejectionBars); + CleanDemand(); + CleanSupply(); } + /** + * Cleanup Demand Related ... + */ void CleanDemand() { // + support.Clean(); + swingLow.Clean(); demandZone.Clean(); bullishFVG.Clean(); bullishOrderBlock.Clean(); + bullishMomentumBar.Clean(); + bullishRejectionBar.Clean(); // Clean(supports); Clean(swingLows); + Clean(supplyZones); Clean(bullishFVGs); Clean(bullishOrderBlocks); Clean(bullishMomentumBars); Clean(bullishRejectionBars); } + /** + * Cleanup Supply Related ... + */ void CleanSupply() { // + swingHigh.Clean(); supplyZone.Clean(); bearishFVG.Clean(); + resistance.Clean(); bearishOrderBlock.Clean(); + bearishMomentumBar.Clean(); + bearishRejectionBar.Clean(); // Clean(swingHighs); - Clean(resistances); + Clean(demandZones); Clean(bearishFVGs); + Clean(resistances); Clean(bearishOrderBlocks); Clean(bearishMomentumBars); Clean(bearishRejectionBars); } - bool ValidateSupply() - { - // - bool result = false; - - // - result = IsValid(); - if (!result) - { - return result; - } - - // - result = - // - supplyZone.IsValid() && - bearishFVG.IsValid() && - bearishOrderBlock.IsValid() && - (ArraySize(swingHighs) > 0 || - ArraySize(bearishFVGs) > 0 || - ArraySize(resistances) > 0 || - ArraySize(bearishOrderBlocks) > 0 || - ArraySize(bearishMomentumBars) > 0 || - ArraySize(bearishRejectionBars) > 0) - // - ; - - // - return result; - } - + /** + * Validate Demand ... + * + * @return ( bool ) + */ bool ValidateDemand() { // @@ -211,11 +182,17 @@ struct X121SMCStrategyConditions // result = // + support.IsValid() && + swingLow.IsValid() && demandZone.IsValid() && bullishFVG.IsValid() && bullishOrderBlock.IsValid() && + bullishMomentumBar.IsValid() && + bullishRejectionBar.IsValid() && + // (ArraySize(supports) > 0 || ArraySize(swingLows) > 0 || + ArraySize(supplyZones) > 0 || ArraySize(bullishFVGs) > 0 || ArraySize(bullishOrderBlocks) > 0 || ArraySize(bullishMomentumBars) > 0 || @@ -227,6 +204,48 @@ struct X121SMCStrategyConditions return result; } + /** + * Validate Supply ... + * + * @return ( bool ) + */ + bool ValidateSupply() + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + result = + // + swingHigh.IsValid() && + supplyZone.IsValid() && + bearishFVG.IsValid() && + resistance.IsValid() && + bearishOrderBlock.IsValid() && + bearishMomentumBar.IsValid() && + bearishRejectionBar.IsValid() && + // + (ArraySize(swingHighs) > 0 || + ArraySize(demandZones) > 0 || + ArraySize(bearishFVGs) > 0 || + ArraySize(resistances) > 0 || + ArraySize(bearishOrderBlocks) > 0 || + ArraySize(bearishMomentumBars) > 0 || + ArraySize(bearishRejectionBars) > 0) + // + ; + + // + return result; + } + // // Validate ... bool IsValid() @@ -650,4 +669,188 @@ struct XRange // }; +// +struct XRangeStructure +{ + // + XRange range; + + // + XZone demandZones[]; + XZone supplyZones[]; + + // + XZone bearishOrderBlocks[]; + XZone bearishFVGs[]; + + // + XOHCL swingHighs[]; + XOHCL resistances[]; + XOHCL bearishMomentumBars[]; + XOHCL bearishRejectionBars[]; + + // + XZone bullishOrderBlocks[]; + XZone bullishFVGs[]; + + // + XOHCL supports[]; + XOHCL swingLows[]; + XOHCL bullishMomentumBars[]; + XOHCL bullishRejectionBars[]; + + // + // Constructor ... + void XRangeStructure() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + range.Clean(); + + // + Clean(supports); + Clean(swingLows); + Clean(swingHighs); + Clean(demandZones); + Clean(supplyZones); + Clean(bearishFVGs); + Clean(resistances); + Clean(bullishFVGs); + Clean(bearishOrderBlocks); + Clean(bullishOrderBlocks); + Clean(bearishMomentumBars); + Clean(bearishRejectionBars); + Clean(bullishMomentumBars); + Clean(bullishRejectionBars); + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = range.IsValid(); + if (!result) + { + return result; + } + + // + result = + // + ArraySize(supports) > 0 || + ArraySize(swingLows) > 0 || + ArraySize(swingHighs) > 0 || + ArraySize(demandZones) > 0 || + ArraySize(supplyZones) > 0 || + ArraySize(bearishFVGs) > 0 || + ArraySize(resistances) > 0 || + ArraySize(bullishFVGs) > 0 || + ArraySize(bearishOrderBlocks) > 0 || + ArraySize(bullishOrderBlocks) > 0 || + ArraySize(bearishMomentumBars) > 0 || + ArraySize(bearishRejectionBars) > 0 || + ArraySize(bullishMomentumBars) > 0 || + ArraySize(bullishRejectionBars) > 0 + // + ; + + // + return result; + } + + /** + * Generate Tag ... + * + * @return ( string ) + */ + string GetTag() + { + // + string result = NULL; + + // + string hash = range.GetTag(); + hash = ToMD5(hash); + + // + result = X121SMCMarketStructureToken + "_" + hash; + + // + return result; + } +}; + +/** + * Check a Zone is Between to other Zones ... + * + * @param source: XZone instance ... + * @param upper: XZone instance ... + * @param lower: XZone instance ... + * + * @return ( bool ) + */ +bool IsBetween( + XZone &source, + XRange &range // +) +{ + // + bool result = false; + + // + result = source.IsValid() && + range.IsValid(); + if (!result) + { + return result; + } + + // + result = source.upper <= range.upper && + source.lower >= range.lower; + + // + return result; +} +bool IsBetween( + XOHCL &source, + XRange &range // +) +{ + // + bool result = false; + + // + result = source.IsValid() && + range.IsValid(); + if (!result) + { + return result; + } + + // + result = source.high <= range.upper && + source.low >= range.lower; + + // + return result; +} + // \ No newline at end of file diff --git a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 index f40dae9420aacb27cec5a94a054b5deeb68b1be6..bf1b34057468ea7b3a7bc72d3d04bd89d289f4d1 100644 GIT binary patch literal 44544 zcmeHQ`)?e#5#FB*^nW;~fTO&W*l7?TZQ97P90{>wS0|@Rf1WCI5Qc z@8jHvk0qDn>U1YN!ognM9yuJ&dxqTQ|Ni@NGtbYTn?ITH^g3vU&4cDiv)3FqYt2D3 zY6i_lvxWaxaqqA>F~1C&JI%kE+s$X@{sDSS@EPFFe)AALAK>51#=`ulncc@i{TAbl zfX^2gc^mj`H`ki$_%{T0tH5~=IGy0ziNT1NKlZS?X!*ZpRUR{PBnW=Lpb+&gN1 z#hpi{%>W}E;4{GNIM+SgA2hqTBQxhngXU-SImY#wX)$P)%}4PKucYAvj6j;ol{EjN zfNBb9(5$29BfuCm-+*TinpgO@htHr{0S?4>$=qj~o#v_6W(RHA<}1*I96!Qm8FM-U zP2W4kLdTkyOzL=g9W-A9$0I{`&gY)t%ouY#HXIYmTT1_B$~$fG5`7LZdtWMJtvK^B zXhCUs40@cP=R1(2_TB5vCy=vGn-9^VL|fi5)QpWu%nrd9j>Hj9fWZVZKx#iXpJjYk zecZ!LM&Qvta7@Ge)zD^wR+MH!zJ@-Z;FIn{J>k4}aV6!I`g)}e7y&oR_X#j^Wn0_u z`WG`F>cumoIUJq5`FQ&OI&eDx9CB}hyDwlD+Vgt>Jf1-No@3@?^rSV?UdzDa7uX%0 z3+WddZxubPZpuhv9Z1m;`YfO7GVk~{f_k9+{Sn>Sl1tPu;%jf@P?j~~vAcir#Q zRTsY1QMMX8zlqIr`w~_NFZ@obQNo3H&oGA*BcE*=Ddb=AJ1u%_t|@P^!?SJk*f*qQ-s^8}V>1a2IGAG9msM`ULUdLtHJ`VF04E`7B3TJvplAAV*B z-f#ogwdPi{3E#lKhGtyRMcN9|B|gd)s76`5Wk%;;v9ZKw=*W7F`(~xkFwncD2qku= z_Cj#;v*XXm#M}=LG)nz2o1Z_FRhwRXt#_!)5p*w9h%w1WQtNlxsiBa;_oJfN^iei(3>(Xl3*zP?*JB-MdLW)r#-m?Y|i5K3*>am z9eASq&G&)5Ymc=J=yx%@n}EKFzwh81|E7l+0dHD687tM2eOA!-8}!=hA$e9)nZ-uI*(2Qg7ci=&bkF5RTzqWn1 zwoln^-ls=p&dpqgQ6!^;UE>`d;7-n)=SJv?>_i^FHZ*W!w=`d^MJS8ls4oKl9!8;! zrT$v@HL~y9G-iL|an#4?IQD)RzlE`u(k_I|`io1Odl+eKa((6|d%)k1kZa&xpF-yK zef%36*l~G^;q~dXKd)i`8fvPyeg%uph-eSlugp2+U$w_>tA`Kc1HieKu<{CH+=Agl zErZd9;@@$h^q~!HE9)(+vPoo2dHy^xH(%4-3`*$g%S@c(N*{^nH9Bn5Cd4cb?Gf;1 zosm{VeE%-|q5jRe=(km418EJJ;amMw4bf{(|NZ=pBl!7};90{9v5=c)7PKFGCLWip zR^m&W$=AdE0q|H`Rd}&{M(4hbIAk66`8Ha=GFkO;LK0lBB)r%5%SP^*SH&|S9m|)M zcm`zKx>WCO>uYMtE2Zq&;{0x3&w3jgK)tNx?`|c3wf&;`>syMqpTDfX(;_gg;5tVw zpU0Ja*7l3$v+w8LWp3!Yx{i3hgfCR)^r2SdjQZo~Y!QdKO+{?as zR&jGmK}H+QYBx*-$k>+g0&~@OjV{HjXx87V2huBR_Up}e&A*YE-oxLqTARC;5^E8s zvD?dC;aHw#7cofP9@d2z>)q`~T|3*|GK|#Ps}o8+^}01t%y#pGp)xBXtSFB0IY2!| z@5ZUAQD&^i#PIEzi325eS%EyT&i@j6v5&|{@}JL8W0Aa-5hmBH+M{#zDUN~FYN@ac zBfYi4y*jngf(>>2J7B|gqDKx!@$t!7nM(>2)!uSE`qUXx7Fu~H3`0rrVwL}7c z#EgHMN?}a1bS%A=;-+$Q1=T&qm}L@twYgeEA;reddU;yuW4kw{KF z4Wk3=X=Jr2E}NkR>Xy~8bxwA}_SXI{o1EorekR7#S@@Y!Ze4mB?t-%Q)d|)#B|BZ8 z#x`*;uTgEgeP1sVgH-BchApgXbC__}?krMRXe6qUO$Z~zA+EjM+M3hO(y`CStHgL_ zz4D@bik0SlFN2L`E+Nk*&Aj|ciOkmf67HxwHhX0yGr7naOIv!>^2;pZmM8Q_`n^sQ zF0%`(C6*7jkvBe1WI=6mk$d za$YL6R+EP4dcgDWU8U`i%RyS}*y6 z=1tmGYXM>FvIsrI&DF#>ZmIF&*u`fexRtCM*|%ysm+81iCMwg z5iL)3)#~C#4Q2kymz^?MR9;H9*q{3C2ty&KuIUw^utz_6^tGy1I;=dpa8mNv_LH^a zS!vV=_TsLrmPI|Ykj8$r?<+FNmmG)WF!5u|c^DhQ1_zV;|&bJQ8 zvtja#6nE;&j>UT3+civPCBDZcC3a0VDS4a`X{un)dn3~ul;ctT>u;oE&vWsW`@J;v)+>n58!6aI<5T;WkSh&EaOpD#J}R_w3%euVkx)TJK(Oe>BGEqmerPS@EB* z{iz$Rc5Y?Rb5M0{C&raj->}l+){!nNEf=}cqAMK(?7@`xUCknsw6z?Cuh8e0Gg4ML zmsq9AKC$LjSro_FP{59%H5P@xNE*ze!s2TG#jLQn7?{2G6HR_*S@1JvbrKM_8+6RGJjpn zSs$zSWw^~!Lvy&!AT zW>Q-7d2GI=+qR5hRhPxN+|&9*_xp^LDtgsfr{8O&E%mC>uisNwl?qCdJL^a1@}85? zDV-0ee3T~>CZPEWc*3{V>Rd}_5Z}S3^Ud$X%t>gdi|&q|+32DRQRSn(^JCuH7{f|* zPk6Q%ZH!@6r;U%G{o(snF169+?3<*Gw))MJF!VX-{2n5;d+H7KDN}_JRtD#-eRf_J zqs4o|kVP5ytT6oPnW}s(b+OQ>ooac(G%2{`t5T6&C+joy?WOA?ZQs! z_o5?Szp9qTa?w$68J@M;UBaPD?S50VnB3WvrI6%4yG94Chk5Ua1+mp63?FQSL`%oaoRh_3` zy@gW+xoa5F{F$k}eS%v!mTG$1*Tif;A+%B%_ z=x3t?p8{-i;3LdL&N%$ET5IDFd8(g6l(~1!Ehk0%ojJ`0B<36QmwP&I-k-=@$eyC- zmqqhC8;xDtLduf6U9(rt>XmXO62aaUTDJ_*i$6DemUV5~&YEXX%E`ptF!Vg;5^QHj zBg%@4eaYx9tt^EG4JqcrI=k%oCwHr+3WvI>>GxFH^0bO^#`}jot#`L4IoFKspUAA= zY9P2Y=Dr8}y#`AAjBEE!4J6mcN_OI(##jSujLd`YI^^CBzTJfL^Y7I`;~Ow|+8tMl z`8E{76F;#9{d{cRomKGI% z38rsokr?kW;#{69M>%EO%Y2Y$w^C-?K9!K9D#6p}LU|q-nP*?NAw*YJUVGn^uKs+t zaUSt?{2SuLDDLIDkF19$%FFpt+{wm$SHyV>V?8xE`&v{=7s}m{fyTF*%3dyizC6Fs zZ}EjU1Ese+N4=-B6CTJ|V`EqB82NtwDSa`1_$@ZTLE0?Y&F7w*=l=+>y>K3+v;8$r<9d3&54>Fpa~^VjBG2^Q2QCNrz6s9% z0*dj?F(Lz`6ze$lghhG-ch({Pg4_FuPTle7)2IXCm@cG=@d9qIxQ>KW^{L_W&c)7! z?Dk3Br)AKJnF~kz>NTuOteL3%E;Mxqnz{zvWR89lbDw~YcR<+_16N~GsU7&eR!}Xt zkNtbBihPgANOmcb^73XeIiZYCp~*WL?g1+0hNslW=3{Z(f^{QSw}9n}`HS@uV&=k7 zZ{%Zj4QJO8m()k}TfH%BK0a14%(}TrYEk~4!CudX2crwi17hYc+^ykj5+?!X*>Hp-y(w~^+=znvr^6z?j zH)dFdHQz&I_yBf^>ofM8<{Ar^h9375;axv+QH|_|+NN)4`D>xZ?P++o57aiUp@po4 z8n->+-9Av;xQ5oG7HV8i!@GT;ws8$LPoU09mKj4m_hKpL?EVQtD!qE`l4619M+UQi zX#LzQpjoTkhSry|ZnP}X!6EDrpJvMCE!ILQh4t!E+J(Q2IPnmkht@5IulAR$cZeKx zgr|s(U=KM~_ZpA%apf@I$HmjN#p&mFv__(s#&Y3!UPSB8ESR}4pBa;U$e#DX%%0DS z>51|2$TXI5ePuE$ThUko6#GO~xYiP8QNEYI2@Y){l3zuJv0>I1iz+dQ$~ete0PxLa9wn5TKjcz%3;Bnh}?N)_WV;BKDVrBC~VyWL)nPa6)>TYR!Wu-5k$&LX*Ghva3xU~^{ zYj`7>6>B6s@q?UV)o;VZ=5B@LUGN~b?}T^L8I)hQXzyBKZ`TIKTEuza_VO*fP$mYc z+vd9vW4*hrzblvBEkk+D+xi-QTD#lc5q1|cL~YVK*q2d@lCx3zdyZbq&<%ZG@vPrG zlONl@VW4bmeZxSE);i;qebe9LlG??QA*{VtOlQXpUmrH0x&BV`rL4}8cNRC{BF_QJ zy%EUe%Pg=sxDZ%8iC{5bIcY~b^a5Qtw6)*zGtb9%Z{K#*`#+Sq(R07Qr2LadxQ|i}SHdwOB01F1c9t zwM#AxSJra+C3eZ}?c0ueyQF)g+ZHc2w;X;~5J87~=i6}nJXNEI*PZsfJo~(XH8!rW zaSz>kBDeZIIu>^f%IN`0mAr>>dC{I}-qR?>+;gDXaL$`zYgjduU5DKii_s%x0m(62 X6LI@Z&AsN=?eimPaVmc+d2-l1mzK}u-}g;` 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 SH;%@**?*sB`$QgbJo`UB%!ttd